false
true
0

Contract Address Details

0x5d844B752C0DeBA5460bba4792A02393ca8e70db

Token
TokenTrader.Win (TDR)
Creator
0x8c45ab–d802e5 at 0x067147–1dc351
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
700 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
26126841
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
TDR




Optimization enabled
true
Compiler version
v0.8.28+commit.7893614a




Optimization runs
200
EVM Version
shanghai




Verified at
2025-08-28T01:52:51.776253Z

Constructor Arguments

0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000010b07600000000000000000000000000000000000000000000000000000000000000000f546f6b656e5472616465722e57696e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035444520000000000000000000000000000000000000000000000000000000000

Arg [0] (string) : TokenTrader.Win
Arg [1] (string) : TDR
Arg [2] (uint8) : 18
Arg [3] (uint256) : 280000000

              

contracts/TKNTDR.sol

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

/*
 * ████████╗ ██████╗ ██╗  ██╗███████╗███╗   ██╗    ████████╗██████╗ ██████╗ 
 * ╚══██╔══╝██╔═══██╗██║ ██╔╝██╔════╝████╗  ██║    ╚══██╔══╝██╔══██╗██╔══██╗
 *    ██║   ██║   ██║█████╔╝ █████╗  ██╔██╗ ██║       ██║   ██║  ██║██████╔╝
 *    ██║   ██║   ██║██╔═██╗ ██╔══╝  ██║╚██╗██║       ██║   ██║  ██║██╔══██╗
 *    ██║   ╚██████╔╝██║  ██╗███████╗██║ ╚████║       ██║   ██████╔╝██║  ██║
 *    ╚═╝    ╚═════╝ ╚═╝  ╚═╝╚══════╝╚═╝  ╚═══╝       ╚═╝   ╚═════╝ ╚═╝  ╚═╝
 * 
 * ═══════════════════════════════════════════════════════════════════════════
 *                        TokenTrader.win Platform Token (TDR)
 * ═══════════════════════════════════════════════════════════════════════════
 * 
 * PLATFORM & MEME TOKEN FOR THE X AND PTGC ECOSYSTEM
 * 
 * REVENUE SOURCES:
 *    • SniperSwap + Automated Portal trading fees
 *    • TokenTrader.win platform utilities
 *    
 * TOKENOMICS & FEE STRUCTURE:
 *    ┌─────────────────────────────────────────────────────────────┐
 *    │                    DEFAULT FEE ALLOCATION                   │
 *    │                        Total: 4.0%                          │
 *    ├─────────────────────────────────────────────────────────────┤
 *    │  LIQUIDITY         │  2.0%  │ Auto-LP for TDR/USDC           │
 *    │  NOEXPECTATIONS    │  1.0%  │ Operations (WETH)              │
 *    │  TDR REWARDS       │  1.0%  │ TDR self-rewarding dividends   │
 *    │  BURN              │  0.0%  │ Token burning                  │
 *    └─────────────────────────────────────────────────────────────┘
 * 
 * LAUNCH PHASE FEE POLICY:
 *    • Taxes may be temporarily increased to 6% during the launch phase
 *    • Potential for an additional sell-side tax during early market stabilization
 * 
 * REWARD SYSTEM:
 *    • TDR self-rewards to holders (on-chain distributor)
 *    • NoExpectations fee paid in WETH via v1 router swap
 * 
 * TECHNICAL FEATURES:
 *    • PRC-20 standard (PulseChain ERC-20)
 *    • Multiple liquidity pool support (WPLS/TDR, USDC pair for auto-LP)
 *    • Automated reward distribution with gas optimization
 * 
 * PULSECHAIN INTEGRATION:
 *    • USDC liquidity pairing
 *    • PulseX router integration (0x165C3410fC91EF562C50559f7d2289fEbed552d9,0x98bf93ebf5c380c0e6ae8e192a7e2ae08edacc02)
 *    • Optimized for PulseChain's low-cost environment
 * 
 * 
 * SUPPLY:
 *    • Supply: 280,000,000 
 *    • Decimals: 18
 * 
 * Website: https://tokentrader.win
 * Platform: SniperSwap & TokenTrader.win utilities
 * 
 * DISCLAIMER: This is experimental DeFi software. Use at your own risk.
 *    Always verify contract addresses and audit before interacting
 * 
 * ═══════════════════════════════════════════════════════════════════════════
 */

library SafeMath {
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return sub(a, b, "SafeMath: subtraction overflow");
    }
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        uint256 c = a - b;
        return c;
    }
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return div(a, b, "SafeMath: division by zero");
    }
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        uint256 c = a / b;
        return c;
    }
}

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

abstract contract Auth {
    address internal owner;
    mapping (address => bool) internal authorizations;

    constructor(address _owner) {
        owner = _owner;
        authorizations[_owner] = true;
    }

    modifier onlyOwner() {
        require(isOwner(msg.sender), "!OWNER"); _;
    }

    modifier authorized() {
        require(isAuthorized(msg.sender), "!AUTHORIZED"); _;
    }

    function isOwner(address account) public view returns (bool) {
        return account == owner;
    }

    function isAuthorized(address adr) public view returns (bool) {
        return authorizations[adr];
    }

    function authorize(address adr) external onlyOwner {
        authorizations[adr] = true;
    }

    function unauthorize(address adr) external onlyOwner {
        require(adr != owner, "Cannot unauthorize owner");
        authorizations[adr] = false;
    }

    function transferOwnership(address payable adr) external onlyOwner {
        require(adr != address(0), "Invalid address");
        owner = adr;
        authorizations[adr] = true;
        emit OwnershipTransferred(adr);
    }

    event OwnershipTransferred(address owner);
}

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

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

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);

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

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
}

interface IDividendDistributor {
    function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external;
    function setShare(address shareholder, uint256 amount) external;
    function deposit() external payable;
    function process(uint256 gas) external;
}

// TDR Self-Rewarding Distributor
contract DividendDistributor is IDividendDistributor {
    using SafeMath for uint256;

    address _token;

    struct Share {
        uint256 amount;
        uint256 totalExcluded;
        uint256 totalRealised;
    }

    IPRC20 RWRD; // Will be TDR token itself
    address WPLS = 0xA1077a294dDE1B09bB078844df40758a5D0f9a27;
    IDEXRouter router;

    address[] shareholders;
    mapping (address => uint256) shareholderIndexes;
    mapping (address => uint256) shareholderClaims;
    mapping (address => Share) public shares;

    uint256 public totalShares;
    uint256 public totalDividends;
    uint256 public totalDistributed;
    uint256 public dividendsPerShare;
    uint256 public dividendsPerShareAccuracyFactor = 10 ** 36;

    uint256 public minPeriod = 0;
    uint256 public minDistribution = 0;
    uint256 currentIndex;

    modifier onlyToken() {
        require(msg.sender == _token); _;
    }

    constructor (address _router) {
        router = _router != address(0)
            ? IDEXRouter(_router)
            : IDEXRouter(0x165C3410fC91EF562C50559f7d2289fEbed552d9);
        _token = msg.sender;
        RWRD = IPRC20(_token); // Self-rewarding
    }

    function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external override onlyToken {
        minPeriod = _minPeriod;
        minDistribution = _minDistribution;
    }

    function setShare(address shareholder, uint256 amount) external override onlyToken {
        if(shares[shareholder].amount > 0){
            distributeDividend(shareholder);
        }

        if(amount > 0 && shares[shareholder].amount == 0){
            addShareholder(shareholder);
        }else if(amount == 0 && shares[shareholder].amount > 0){
            removeShareholder(shareholder);
        }

        totalShares = totalShares.sub(shares[shareholder].amount).add(amount);
        shares[shareholder].amount = amount;
        shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
    }

    function deposit() external payable override onlyToken {
        uint256 balanceBefore = RWRD.balanceOf(address(this));

        address[] memory path = new address[](2);
        path[0] = WPLS;
        path[1] = address(RWRD); // Buy TDR with WPLS

        router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: msg.value}(
            0,
            path,
            address(this),
            block.timestamp
        );

        uint256 amount = RWRD.balanceOf(address(this)).sub(balanceBefore);
        totalDividends = totalDividends.add(amount);
        if (totalShares > 0) {
        dividendsPerShare = dividendsPerShare.add(dividendsPerShareAccuracyFactor.mul(amount).div(totalShares));
        }
    }

    function process(uint256 gas) external override onlyToken {
        uint256 shareholderCount = shareholders.length;
        if(shareholderCount == 0) { return; }

        uint256 gasUsed = 0;
        uint256 gasLeft = gasleft();
        uint256 iterations = 0;

        while(gasUsed < gas && iterations < shareholderCount) {
            if(currentIndex >= shareholderCount){
                currentIndex = 0;
            }

            if(shouldDistribute(shareholders[currentIndex])){
                distributeDividend(shareholders[currentIndex]);
            }

            gasUsed = gasUsed.add(gasLeft.sub(gasleft()));
            gasLeft = gasleft();
            currentIndex++;
            iterations++;
        }
    }

    function shouldDistribute(address shareholder) internal view returns (bool) {
        return shareholderClaims[shareholder] + minPeriod < block.timestamp
                && getUnpaidEarnings(shareholder) > minDistribution;
    }

    function distributeDividend(address shareholder) internal {
        if(shares[shareholder].amount == 0){ return; }

        uint256 amount = getUnpaidEarnings(shareholder);
        if(amount > 0){
            totalDistributed = totalDistributed.add(amount);
            RWRD.transfer(shareholder, amount);
            shareholderClaims[shareholder] = block.timestamp;
            shares[shareholder].totalRealised = shares[shareholder].totalRealised.add(amount);
            shares[shareholder].totalExcluded = getCumulativeDividends(shares[shareholder].amount);
        }
    }
    
    function claimDividend() external {
        distributeDividend(msg.sender);
    }

    function getUnpaidEarnings(address shareholder) public view returns (uint256) {
        if(shares[shareholder].amount == 0){ return 0; }

        uint256 shareholderTotalDividends = getCumulativeDividends(shares[shareholder].amount);
        uint256 shareholderTotalExcluded = shares[shareholder].totalExcluded;

        if(shareholderTotalDividends <= shareholderTotalExcluded){ return 0; }

        return shareholderTotalDividends.sub(shareholderTotalExcluded);
    }

    function getCumulativeDividends(uint256 share) internal view returns (uint256) {
        return share.mul(dividendsPerShare).div(dividendsPerShareAccuracyFactor);
    }

    function addShareholder(address shareholder) internal {
        shareholderIndexes[shareholder] = shareholders.length;
        shareholders.push(shareholder);
    }

    function removeShareholder(address shareholder) internal {
        shareholders[shareholderIndexes[shareholder]] = shareholders[shareholders.length-1];
        shareholderIndexes[shareholders[shareholders.length-1]] = shareholderIndexes[shareholder];
        shareholders.pop();
    }
}


contract TDR is IPRC20, Auth {
    using SafeMath for uint256;

    address WPLS = 0xA1077a294dDE1B09bB078844df40758a5D0f9a27;
    address USDC = 0x15D38573d2feeb82e7ad5187aB8c1D52810B1f07;
    address WETH = 0x02DcdD04e3F455D838cd1249292C58f3B79e3C3C;
    address DEAD = 0x0000000000000000000000000000000000000369;

    string private _name;
    string private _symbol;
    uint8 private _decimals;
    uint256 private _totalSupply;

    mapping (address => uint256) _balances;
    mapping (address => mapping (address => uint256)) _allowances;

    mapping (address => bool) isFeeExempt;
    mapping (address => bool) isDividendExempt;
    mapping (address => bool) public isAutomatedMarketMakerPairs;

    bool public notliftoff = true;

    //  fees (in basis points, 1000 = 100%)
    uint256 public liquidityFee     = 0;  // 0.0% TDR/WPLS LP (disabled)
    uint256 public tdrRewardFee     = 10; // 1.0% TDR Reflections 
    uint256 public NoExpectationFee = 10; // 1.0% No Expectation Fee (WETH)
    uint256 public burnFee          = 0;  // 0.0% burn TDR
    uint256 public extraLiqFee      = 20; // 2.0% TDR/USDC LP
    uint256 public totalFee         = liquidityFee + tdrRewardFee + NoExpectationFee + extraLiqFee;
    uint256 public feeDenominator   = 1000;

    uint256 public sellMultiplier  = 100;

    address public autoLiquidityReceiver;
    address public NoExpectationFeeReceiver;

    IDEXRouter public router;
    IDEXRouter public v1Router;
    address public pair; // TDR/WPLS main pair

    bool public tradingOpen = false;

    DividendDistributor public tdrDistributor;   // Self-rewarding TDR
    uint256 distributorGas = 1000000;

    bool public swapEnabled = true;
    uint256 public swapThreshold;
    bool public noExpUseWETH = true; // true = WETH via v1, false = PLS
    bool inSwap;
    modifier swapping() { inSwap = true; _; inSwap = false; }

    constructor (
        string memory tokenName,
        string memory tokenSymbol,
        uint8 tokenDecimals,
        uint256 tokenTotalSupply
    ) Auth(msg.sender) {
        _name = tokenName;
        _symbol = tokenSymbol;
        _decimals = tokenDecimals;
        _totalSupply = tokenTotalSupply.mul(10**uint256(tokenDecimals));
        swapThreshold = _totalSupply.mul(5).div(10000); // 0.05%

        router = IDEXRouter(0x165C3410fC91EF562C50559f7d2289fEbed552d9);
        v1Router = IDEXRouter(0x98bf93ebf5c380C0e6Ae8e192A7e2AE08edAcc02);
        pair = IDEXFactory(router.factory()).createPair(address(this), WPLS);
        _allowances[address(this)][address(router)] = type(uint256).max;

        // Pre-create USDC pair for 2% auto-LP
        address usdcPair = IDEXFactory(router.factory()).createPair(address(this), USDC);
        
        // Mark both pairs as AMM pairs
        isAutomatedMarketMakerPairs[pair] = true;
        isAutomatedMarketMakerPairs[usdcPair] = true;

        // Create distributor
        tdrDistributor = new DividendDistributor(address(router));        // TDR rewards via v2 router

        // Fee exemptions
        isFeeExempt[msg.sender] = true;
        isFeeExempt[address(this)] = true;
        isFeeExempt[address(tdrDistributor)] = true;

        // Dividend exemptions
        isDividendExempt[address(tdrDistributor)] = true;
        isDividendExempt[pair] = true;
        isDividendExempt[usdcPair] = true;
        isDividendExempt[address(this)] = true;
        isDividendExempt[DEAD] = true;

        autoLiquidityReceiver = msg.sender;
        NoExpectationFeeReceiver = msg.sender;

        _balances[msg.sender] = _totalSupply;
        emit Transfer(address(0), msg.sender, _totalSupply);
    }

    receive() external payable { }

    function totalSupply() external view override returns (uint256) { return _totalSupply; }
    function decimals() external view override returns (uint8) { return _decimals; }
    function symbol() external view override returns (string memory) { return _symbol; }
    function name() external view override returns (string memory) { return _name; }
    function getOwner() external view override returns (address) { return owner; }
    function balanceOf(address account) public view override returns (uint256) { return _balances[account]; }
    function allowance(address holder, address spender) external view override returns (uint256) { return _allowances[holder][spender]; }

    function approve(address spender, uint256 amount) public override returns (bool) {
        _allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function approveMax(address spender) external returns (bool) {
        return approve(spender, type(uint256).max);
    }

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

    function transferFrom(address sender, address recipient, uint256 amount) external override returns (bool) {
        if(_allowances[sender][msg.sender] != type(uint256).max){
            _allowances[sender][msg.sender] = _allowances[sender][msg.sender].sub(amount, "Insufficient Allowance");
        }

        return _transferFrom(sender, recipient, amount);
    }

    function _transferFrom(address sender, address recipient, uint256 amount) internal returns (bool) {

        if(inSwap || sender == address(tdrDistributor)){ 
            return _basicTransfer(sender, recipient, amount); 
        }

        if(!authorizations[sender] && !authorizations[recipient]){
            require(tradingOpen,"Trading not open yet");
        }

        // Only trigger swapBack on sells (recipient is an AMM pair)
        if(isAutomatedMarketMakerPairs[recipient] && shouldSwapBack()){ swapBack(); }

        _balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");

        uint256 amountReceived = shouldTakeFee(sender, recipient) ? takeFee(sender, amount, isAutomatedMarketMakerPairs[recipient]) : amount;
        _balances[recipient] = _balances[recipient].add(amountReceived);

        // Dividend tracker
        if(!isDividendExempt[sender]) {
            try tdrDistributor.setShare(sender, _balances[sender]) {} catch {}
        }

        if(!isDividendExempt[recipient]) {
            try tdrDistributor.setShare(recipient, _balances[recipient]) {} catch {}
        }

        emit Transfer(sender, recipient, amountReceived);
        return true;
    }

    function _basicTransfer(address sender, address recipient, uint256 amount) internal returns (bool) {
        _balances[sender] = _balances[sender].sub(amount, "Insufficient Balance");
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
        return true;
    }

    function shouldTakeFee(address sender, address recipient) internal view returns (bool) {
        if (isFeeExempt[recipient]){
            return false;
        }
        return !isFeeExempt[sender];
    }

    function takeFee(address sender, uint256 amount, bool isSell) internal returns (uint256) {
        uint256 multiplier = isSell ? sellMultiplier : 100;
        uint256 feeAmount = amount.mul(totalFee).mul(multiplier).div(feeDenominator.mul(100));
        uint256 burnAmount = amount.mul(burnFee).mul(multiplier).div(feeDenominator.mul(100));

        if (burnAmount > 0){
            _balances[DEAD] = _balances[DEAD].add(burnAmount);
            emit Transfer(sender, DEAD, burnAmount);
        }

        _balances[address(this)] = _balances[address(this)].add(feeAmount);
        emit Transfer(sender, address(this), feeAmount);

        return amount.sub(feeAmount).sub(burnAmount);
    }

    function shouldSwapBack() internal view returns (bool) {
        return !inSwap
        && swapEnabled
        && _balances[address(this)] >= swapThreshold;
    }

    //  swapBack with dual LP
    function swapBack() internal swapping {
        uint256 amountToLiquifyExtra = swapThreshold.mul(extraLiqFee).div(totalFee).div(2); // TDR/USDC
        uint256 amountToLiquify = swapThreshold.mul(liquidityFee).div(totalFee).div(2);      // TDR/WPLS
        uint256 amountToSwap = swapThreshold.sub(amountToLiquify).sub(amountToLiquifyExtra);

        uint256 balanceBefore = address(this).balance;

        // Swap TDR -> WPLS
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = WPLS;

        router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            amountToSwap,
            0,
            path,
            address(this),
            block.timestamp
        );

        uint256 amountPLS = address(this).balance.sub(balanceBefore);

        // Calculate PLS distribution 
        uint256 totalPLSFee = totalFee.sub(liquidityFee.div(2).add(extraLiqFee.div(2))).mul(1000);
        
        uint256 amountPLSLiquidity = amountPLS.mul(liquidityFee).div(totalPLSFee.div(1000)).div(2);
        uint256 amountPLSLiquidityExtra = amountPLS.mul(extraLiqFee).div(totalPLSFee.div(1000)).div(2);
        uint256 amountPLSTDRRewards = amountPLS.mul(tdrRewardFee).div(totalPLSFee.div(1000));
        uint256 amountPLSNoExpectation = amountPLS.mul(NoExpectationFee).div(totalPLSFee.div(1000));
        
        // Distribute TDR rewards
        try tdrDistributor.deposit{value: amountPLSTDRRewards}() {} catch {}
        try tdrDistributor.process(distributorGas) {} catch {}

        // Convert NoExpectations portion - WETH or PLS
        if (amountPLSNoExpectation > 0) {
            if (noExpUseWETH) {
                address[] memory wethPath = new address[](2);
                wethPath[0] = WPLS;
                wethPath[1] = WETH;
                
                // Buy WETH using v1 router for better liquidity
                try v1Router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amountPLSNoExpectation}(
                    0,
                    wethPath,
                    NoExpectationFeeReceiver,  // Send WETH directly to receiver
                    block.timestamp
                ) {} catch {
                    // If WETH swap fails, send PLS instead
                    (bool tmpSuccess,) = payable(NoExpectationFeeReceiver).call{value: amountPLSNoExpectation, gas: 30000}("");
                    tmpSuccess = false; // Suppress warning
                }
            } else {
                // Send PLS directly
                (bool tmpSuccess,) = payable(NoExpectationFeeReceiver).call{value: amountPLSNoExpectation, gas: 30000}("");
                tmpSuccess = false; // Suppress warning
            }
        }

        // Add TDR/USDC liquidity 
        if (amountPLSLiquidityExtra > 0) {
            addTokenToTokenLP(amountPLSLiquidityExtra, amountToLiquifyExtra);
        }

        // Add TDR/WPLS liquidity
        if(amountToLiquify > 0){
            router.addLiquidityETH{value: amountPLSLiquidity}(
                address(this),
                amountToLiquify,
                0,
                0,
                autoLiquidityReceiver,
                block.timestamp
            );
            emit AutoLiquify(amountPLSLiquidity, amountToLiquify);
        }

        // Send any remaining PLS crumbs
        uint256 crumbs = address(this).balance;
        if (crumbs > 0) {
            (bool tmpSuccess,) = payable(NoExpectationFeeReceiver).call{value: crumbs, gas: 30000}("");
            tmpSuccess = false; // Suppress warning
        }
    }

    // Add TDR/USDC liquidity 
    function addTokenToTokenLP(uint256 amountPLSLiquidityExtra, uint256 amountToLiquifyExtra) internal {
        IPRC20 Token = IPRC20(USDC);

        uint256 balanceBeforeToken = Token.balanceOf(address(this));

        // Swap WPLS -> USDC
        address[] memory path2 = new address[](2);
        path2[0] = WPLS;
        path2[1] = USDC;

        // Buy USDC on PulseX v1 for better depth, then add LP on v2
        v1Router.swapExactETHForTokensSupportingFeeOnTransferTokens{value: amountPLSLiquidityExtra}(
            0,
            path2,
            address(this),
            block.timestamp
        );

        uint256 amount = Token.balanceOf(address(this)).sub(balanceBeforeToken);

        Token.approve(address(router), type(uint256).max);

        // Add TDR/USDC liquidity
        (uint256 amountUSDCUsed, uint256 amountTDRUsed, uint256 liquidity) = router.addLiquidity(
            address(Token),
            address(this),
            amount,
            amountToLiquifyExtra,
            0,
            0,
            autoLiquidityReceiver,
            block.timestamp
        );

        // Send any leftover USDC
        uint256 tokencrumbs = Token.balanceOf(address(this));
        if(tokencrumbs > 0){
            Token.transfer(NoExpectationFeeReceiver, tokencrumbs);
        }

        emit AutoLiquifyUSDC(amountUSDCUsed, amountTDRUsed, liquidity);
    } 

    // Configuration functions
    function setIsDividendExempt(address holder, bool exempt) external authorized {
        require(holder != address(this) && holder != pair);
        isDividendExempt[holder] = exempt;
        if(exempt){
            tdrDistributor.setShare(holder, 0);
        }else{
            tdrDistributor.setShare(holder, _balances[holder]);
        }
    }

    function setIsFeeExempt(address holder, bool exempt) external authorized {
        isFeeExempt[holder] = exempt;
    }

    function setFees(
        uint256 _liquidityFee, 
        uint256 _tdrRewardFee, 
        uint256 _NoExpectationFee, 
        uint256 _burnFee, 
        uint256 _extraLiqFee
    ) external authorized {
        liquidityFee = _liquidityFee;
        tdrRewardFee = _tdrRewardFee;
        NoExpectationFee = _NoExpectationFee;
        burnFee = _burnFee;
        extraLiqFee = _extraLiqFee;
        totalFee = _liquidityFee.add(_tdrRewardFee).add(_NoExpectationFee).add(_extraLiqFee);
        require(totalFee <= 100, "Fees cannot be more than 10%"); // 100/1000 = 10%
    }

    function setSellMultiplier(uint256 multiplier) external authorized {
        require(multiplier >= 100, "Multiplier too low");
        require(multiplier <= 1000, "Multiplier too high");
        sellMultiplier = multiplier;
    }

    function liftoff() external onlyOwner {
        require(notliftoff, "Moon mission already a go");
        tradingOpen = true;
        notliftoff = false;
    }

    function setFeeReceivers(address _autoLiquidityReceiver, address _NoExpectationFeeReceiver) external authorized {
        autoLiquidityReceiver = _autoLiquidityReceiver;
        NoExpectationFeeReceiver = _NoExpectationFeeReceiver;
    }

    function setSwapBackSettings(bool _enabled, uint256 _amount) external authorized {
        swapEnabled = _enabled;
        swapThreshold = _amount;
    }

    function setNoExpUseWETH(bool _useWETH) external authorized {
        noExpUseWETH = _useWETH;
    }
    
    function setAutomatedMarketMakerPair(address _pair, bool _value) external authorized {
        require(_pair != address(0), "Zero address");
        isAutomatedMarketMakerPairs[_pair] = _value;
        
        // Update dividend exemption status
        isDividendExempt[_pair] = _value;
        
        emit SetAutomatedMarketMakerPair(_pair, _value);
    }
    
    event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);

    function setDistributionCriteria(uint256 _minPeriod, uint256 _minDistribution) external authorized {
        tdrDistributor.setDistributionCriteria(_minPeriod, _minDistribution);
    }

    function setDistributorSettings(uint256 gas) external authorized {
        require(gas >= 500000 && gas <= 3000000, "Gas out of range");
        distributorGas = gas;
    }
    
    // Emergency functions
    function clearStuckBalance(uint256 amountPercentage, address receiver) external authorized {
        require(amountPercentage <= 100, "Invalid percentage");
        require(receiver != address(0), "Invalid receiver");
        uint256 amountPLS = address(this).balance;
        uint256 amountToSend = amountPLS.mul(amountPercentage).div(100);
        (bool success,) = payable(receiver).call{value: amountToSend, gas: 30000}("");
        require(success, "Failed to clear balance");
    }

    function clearStuckTokens(address _token, address receiver) external authorized {
        require (_token != address(this), "Cannot withdraw TDR itself");
        require(receiver != address(0), "Invalid receiver");

        IPRC20 tokeninst = IPRC20(_token);
        uint256 tokeninstbalance = tokeninst.balanceOf(address(this));
        tokeninst.transfer(receiver, tokeninstbalance);
    }

    function manualSwapBack(uint256 amount) external authorized {
        require(amount > 0 && amount <= _balances[address(this)], "Invalid amount");
        require(!inSwap, "Already in swap");
        
        uint256 originalThreshold = swapThreshold;
        swapThreshold = amount;
        
        if (shouldSwapBack()) {
            swapBack();
        }
        
        swapThreshold = originalThreshold;
    }

    // Claim functions
    function claimTDRDividend() external {
        tdrDistributor.claimDividend();
    }
    
    // View functions
    function getCirculatingSupply() public view returns (uint256) {
        return _totalSupply.sub(balanceOf(DEAD));
    }

    function getLiquidityBacking(uint256 accuracy) public view returns (uint256) {
        return accuracy.mul(balanceOf(pair).mul(2)).div(getCirculatingSupply());
    }

    function getUnpaidTDREarnings(address shareholder) external view returns (uint256) {
        return tdrDistributor.getUnpaidEarnings(shareholder);
    }

    event AutoLiquify(uint256 amountPLS, uint256 amountTDR);
    event AutoLiquifyUSDC(uint256 amountUSDC, uint256 amountTDR, uint256 liquidity);
}
        

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","metadata","evm.methodIdentifiers"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{},"evmVersion":"shanghai"}
              

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"string","name":"tokenName","internalType":"string"},{"type":"string","name":"tokenSymbol","internalType":"string"},{"type":"uint8","name":"tokenDecimals","internalType":"uint8"},{"type":"uint256","name":"tokenTotalSupply","internalType":"uint256"}]},{"type":"event","name":"Approval","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":true},{"type":"address","name":"spender","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AutoLiquify","inputs":[{"type":"uint256","name":"amountPLS","internalType":"uint256","indexed":false},{"type":"uint256","name":"amountTDR","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AutoLiquifyUSDC","inputs":[{"type":"uint256","name":"amountUSDC","internalType":"uint256","indexed":false},{"type":"uint256","name":"amountTDR","internalType":"uint256","indexed":false},{"type":"uint256","name":"liquidity","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"owner","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"SetAutomatedMarketMakerPair","inputs":[{"type":"address","name":"pair","internalType":"address","indexed":true},{"type":"bool","name":"value","internalType":"bool","indexed":true}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"from","internalType":"address","indexed":true},{"type":"address","name":"to","internalType":"address","indexed":true},{"type":"uint256","name":"value","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"NoExpectationFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"NoExpectationFeeReceiver","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allowance","inputs":[{"type":"address","name":"holder","internalType":"address"},{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approve","inputs":[{"type":"address","name":"spender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approveMax","inputs":[{"type":"address","name":"spender","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"authorize","inputs":[{"type":"address","name":"adr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"autoLiquidityReceiver","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"balanceOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"burnFee","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimTDRDividend","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"clearStuckBalance","inputs":[{"type":"uint256","name":"amountPercentage","internalType":"uint256"},{"type":"address","name":"receiver","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"clearStuckTokens","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"address","name":"receiver","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"decimals","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"extraLiqFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"feeDenominator","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getCirculatingSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getLiquidityBacking","inputs":[{"type":"uint256","name":"accuracy","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getUnpaidTDREarnings","inputs":[{"type":"address","name":"shareholder","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isAuthorized","inputs":[{"type":"address","name":"adr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isAutomatedMarketMakerPairs","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isOwner","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"liftoff","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"liquidityFee","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"manualSwapBack","inputs":[{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"noExpUseWETH","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"notliftoff","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pair","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IDEXRouter"}],"name":"router","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"sellMultiplier","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAutomatedMarketMakerPair","inputs":[{"type":"address","name":"_pair","internalType":"address"},{"type":"bool","name":"_value","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDistributionCriteria","inputs":[{"type":"uint256","name":"_minPeriod","internalType":"uint256"},{"type":"uint256","name":"_minDistribution","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setDistributorSettings","inputs":[{"type":"uint256","name":"gas","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeeReceivers","inputs":[{"type":"address","name":"_autoLiquidityReceiver","internalType":"address"},{"type":"address","name":"_NoExpectationFeeReceiver","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFees","inputs":[{"type":"uint256","name":"_liquidityFee","internalType":"uint256"},{"type":"uint256","name":"_tdrRewardFee","internalType":"uint256"},{"type":"uint256","name":"_NoExpectationFee","internalType":"uint256"},{"type":"uint256","name":"_burnFee","internalType":"uint256"},{"type":"uint256","name":"_extraLiqFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setIsDividendExempt","inputs":[{"type":"address","name":"holder","internalType":"address"},{"type":"bool","name":"exempt","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setIsFeeExempt","inputs":[{"type":"address","name":"holder","internalType":"address"},{"type":"bool","name":"exempt","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setNoExpUseWETH","inputs":[{"type":"bool","name":"_useWETH","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSellMultiplier","inputs":[{"type":"uint256","name":"multiplier","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setSwapBackSettings","inputs":[{"type":"bool","name":"_enabled","internalType":"bool"},{"type":"uint256","name":"_amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"swapEnabled","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"swapThreshold","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"symbol","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract DividendDistributor"}],"name":"tdrDistributor","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"tdrRewardFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalFee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalSupply","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"tradingOpen","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transfer","inputs":[{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"transferFrom","inputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"address","name":"recipient","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"adr","internalType":"address payable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unauthorize","inputs":[{"type":"address","name":"adr","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IDEXRouter"}],"name":"v1Router","inputs":[]},{"type":"receive","stateMutability":"payable"}]
              

Contract Creation Code

0x6080604052600280546001600160a01b031990811673a1077a294dde1b09bb078844df40758a5d0f9a27179091556003805482167315d38573d2feeb82e7ad5187ab8c1d52810b1f071790556004805482167302dcdd04e3f455d838cd1249292c58f3b79e3c3c17905560058054909116610369179055600f805460ff191660011790555f6010819055600a6011819055601281905560138290556014808055916100ab90829061069d565b6100b5919061069d565b6100bf919061069d565b6015556103e86016556064601755601c805460ff60a01b19169055620f4240601e55601f805460ff19908116600190811790925560218054909116909117905534801561010a575f5ffd5b506040516149573803806149578339810160408190526101299161076c565b5f80546001600160a01b0319163390811782558152600160208190526040909120805460ff1916909117905560066101618582610873565b50600761016e8482610873565b506008805460ff191660ff84169081179091556101979061019090600a610a10565b8290610574565b60098190556101b590612710906101af906005610574565b90610600565b6020908155601a80546001600160a01b031990811673165c3410fc91ef562c50559f7d2289febed552d9908117909255601b80549091167398bf93ebf5c380c0e6ae8e192a7e2ae08edacc021790556040805163c45a015560e01b81529051919263c45a0155926004808401938290030181865afa158015610239573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061025d9190610a1b565b6002546040516364e329cb60e11b81523060048201526001600160a01b03918216602482015291169063c9c65396906044016020604051808303815f875af11580156102ab573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102cf9190610a1b565b601c80546001600160a01b0319166001600160a01b03928316179055305f908152600b60209081526040808320601a8054861685529083528184205f19905554815163c45a015560e01b815291519394169263c45a0155926004808401939192918290030181865afa158015610347573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061036b9190610a1b565b6003546040516364e329cb60e11b81523060048201526001600160a01b03918216602482015291169063c9c65396906044016020604051808303815f875af11580156103b9573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103dd9190610a1b565b601c546001600160a01b039081165f908152600e60205260408082208054600160ff199182168117909255858516845292829020805490931617909155601a549051929350169061042d9061067c565b6001600160a01b039091168152602001604051809103905ff080158015610456573d5f5f3e3d5ffd5b50601d80546001600160a01b03199081166001600160a01b03938416178255335f818152600c60209081526040808320805460ff19908116600190811790925530808652838620805483168417905588548a1686528386208054831684179055975489168552600d84528285208054821683179055601c548916855282852080548216831790558989168552828520805482168317905596845281842080548816821790556005549097168352808320805490961690961790945560188054841683179055601980549093168217909255600954818352600a845284832081905593519384529290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050505050610aa9565b5f825f0361058357505f6105fa565b5f61058e8385610a41565b90508261059b8583610a58565b146105f75760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b60648201526084015b60405180910390fd5b90505b92915050565b5f6105f783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525061064760201b60201c565b5f81836106675760405162461bcd60e51b81526004016105ee9190610a77565b505f6106738486610a58565b95945050505050565b610f84806139d383390190565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105fa576105fa610689565b634e487b7160e01b5f52604160045260245ffd5b5f5b838110156106de5781810151838201526020016106c6565b50505f910152565b5f82601f8301126106f5575f5ffd5b81516001600160401b0381111561070e5761070e6106b0565b604051601f8201601f19908116603f011681016001600160401b038111828210171561073c5761073c6106b0565b604052818152838201602001851015610753575f5ffd5b6107648260208301602087016106c4565b949350505050565b5f5f5f5f6080858703121561077f575f5ffd5b84516001600160401b03811115610794575f5ffd5b6107a0878288016106e6565b602087015190955090506001600160401b038111156107bd575f5ffd5b6107c9878288016106e6565b935050604085015160ff811681146107df575f5ffd5b6060959095015193969295505050565b600181811c9082168061080357607f821691505b60208210810361082157634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561086e57805f5260205f20601f840160051c8101602085101561084c5750805b601f840160051c820191505b8181101561086b575f8155600101610858565b50505b505050565b81516001600160401b0381111561088c5761088c6106b0565b6108a08161089a84546107ef565b84610827565b6020601f8211600181146108d2575f83156108bb5750848201515b5f19600385901b1c1916600184901b17845561086b565b5f84815260208120601f198516915b8281101561090157878501518255602094850194600190920191016108e1565b508482101561091e57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b6001815b60018411156109685780850481111561094c5761094c610689565b600184161561095a57908102905b60019390931c928002610931565b935093915050565b5f8261097e575060016105fa565b8161098a57505f6105fa565b81600181146109a057600281146109aa576109c6565b60019150506105fa565b60ff8411156109bb576109bb610689565b50506001821b6105fa565b5060208310610133831016604e8410600b84101617156109e9575081810a6105fa565b6109f55f19848461092d565b805f1904821115610a0857610a08610689565b029392505050565b5f6105f78383610970565b5f60208284031215610a2b575f5ffd5b81516001600160a01b03811681146105f7575f5ffd5b80820281158282048414176105fa576105fa610689565b5f82610a7257634e487b7160e01b5f52601260045260245ffd5b500490565b602081525f8251806020840152610a958160408501602087016106c4565b601f01601f19169190910160400192915050565b612f1d80610ab65f395ff3fe60806040526004361061032a575f3560e01c806395d89b41116101a3578063ca33e64c116100f2578063f887ea4011610092578063fe634ad01161006d578063fe634ad014610945578063fe9fbb801461095e578063fed0d2a11461097d578063ffb54a9914610992575f5ffd5b8063f887ea40146108f8578063fb6b2abb14610917578063fce589d814610930575f5ffd5b8063df20fd49116100cd578063df20fd491461087c578063f0b37c041461089b578063f2fde38b146108ba578063f708a64f146108d9575f5ffd5b8063ca33e64c146107fa578063d51ed1c814610819578063dd62ed3e14610838575f5ffd5b8063a8aa1b311161015d578063b6a5d7de11610138578063b6a5d7de14610789578063bffda982146107a8578063c191c926146107c7578063c40fedc6146107db575f5ffd5b8063a8aa1b3114610736578063a9059cbb14610755578063af2383b814610774575f5ffd5b806395d89b411461069157806398118cb4146106a55780639a7a23d6146106ba5780639d1944f5146106d9578063a4b45c00146106f8578063a7bc1de014610717575f5ffd5b806330d20cf4116102795780635ab76742116102195780636ddd1713116101f45780636ddd17131461060957806370a0823114610622578063893d20e8146106565780638d3434bd14610672575f5ffd5b80635ab76742146105b65780635db9a3d7146105cb578063658d4b7f146105ea575f5ffd5b806343cfa9a51161025457806343cfa9a5146105445780634ac800dc1461056357806356a227f214610578578063571ac8b014610597575f5ffd5b806330d20cf4146104d8578063313ce5671461050f57806338821f1914610530575f5ffd5b80631df4ccfc116102e45780632b112e49116102bf5780632b112e49146104595780632ca8a1981461046d5780632d48e8961461048c5780632f54bf6e146104ab575f5ffd5b80631df4ccfc146103f757806323b872dd1461040c578063255fe8471461042b575f5ffd5b80630445b6671461033557806304a66b481461035d57806306fdde031461037e578063095ea7b31461039f578063180b0d7e146103ce57806318160ddd146103e3575f5ffd5b3661033157005b5f5ffd5b348015610340575f5ffd5b5061034a60205481565b6040519081526020015b60405180910390f35b348015610368575f5ffd5b5061037c610377366004612a9a565b6109b2565b005b348015610389575f5ffd5b50610392610a6b565b6040516103549190612ad1565b3480156103aa575f5ffd5b506103be6103b9366004612b33565b610afb565b6040519015158152602001610354565b3480156103d9575f5ffd5b5061034a60165481565b3480156103ee575f5ffd5b5060095461034a565b348015610402575f5ffd5b5061034a60155481565b348015610417575f5ffd5b506103be610426366004612b5d565b610b67565b348015610436575f5ffd5b506103be610445366004612b9b565b600e6020525f908152604090205460ff1681565b348015610464575f5ffd5b5061034a610c25565b348015610478575f5ffd5b5061034a610487366004612b9b565b610c50565b348015610497575f5ffd5b5061037c6104a6366004612bb6565b610cbc565b3480156104b6575f5ffd5b506103be6104c5366004612b9b565b5f546001600160a01b0391821691161490565b3480156104e3575f5ffd5b50601d546104f7906001600160a01b031681565b6040516001600160a01b039091168152602001610354565b34801561051a575f5ffd5b5060085460405160ff9091168152602001610354565b34801561053b575f5ffd5b5061037c610d46565b34801561054f575f5ffd5b5061037c61055e366004612be3565b610daa565b34801561056e575f5ffd5b5061034a60125481565b348015610583575f5ffd5b5061037c610592366004612bfe565b610de2565b3480156105a2575f5ffd5b506103be6105b1366004612b9b565b610f53565b3480156105c1575f5ffd5b5061034a60145481565b3480156105d6575f5ffd5b506019546104f7906001600160a01b031681565b3480156105f5575f5ffd5b5061037c610604366004612c2c565b610f5f565b348015610614575f5ffd5b50601f546103be9060ff1681565b34801561062d575f5ffd5b5061034a61063c366004612b9b565b6001600160a01b03165f908152600a602052604090205490565b348015610661575f5ffd5b505f546001600160a01b03166104f7565b34801561067d575f5ffd5b50601b546104f7906001600160a01b031681565b34801561069c575f5ffd5b50610392610fae565b3480156106b0575f5ffd5b5061034a60105481565b3480156106c5575f5ffd5b5061037c6106d4366004612c2c565b610fbd565b3480156106e4575f5ffd5b5061037c6106f3366004612c58565b61108e565b348015610703575f5ffd5b5061037c610712366004612c6f565b61110d565b348015610722575f5ffd5b5061037c610731366004612c58565b611160565b348015610741575f5ffd5b50601c546104f7906001600160a01b031681565b348015610760575f5ffd5b506103be61076f366004612b33565b611218565b34801561077f575f5ffd5b5061034a60115481565b348015610794575f5ffd5b5061037c6107a3366004612b9b565b611224565b3480156107b3575f5ffd5b5061037c6107c2366004612c58565b611273565b3480156107d2575f5ffd5b5061037c61135f565b3480156107e6575f5ffd5b5061037c6107f5366004612c6f565b6113f9565b348015610805575f5ffd5b506018546104f7906001600160a01b031681565b348015610824575f5ffd5b5061034a610833366004612c58565b61159d565b348015610843575f5ffd5b5061034a610852366004612c6f565b6001600160a01b039182165f908152600b6020908152604080832093909416825291909152205490565b348015610887575f5ffd5b5061037c610896366004612c9b565b6115dc565b3480156108a6575f5ffd5b5061037c6108b5366004612b9b565b611618565b3480156108c5575f5ffd5b5061037c6108d4366004612b9b565b6116be565b3480156108e4575f5ffd5b5061037c6108f3366004612c2c565b61179a565b348015610903575f5ffd5b50601a546104f7906001600160a01b031681565b348015610922575f5ffd5b506021546103be9060ff1681565b34801561093b575f5ffd5b5061034a60135481565b348015610950575f5ffd5b50600f546103be9060ff1681565b348015610969575f5ffd5b506103be610978366004612b9b565b61189a565b348015610988575f5ffd5b5061034a60175481565b34801561099d575f5ffd5b50601c546103be90600160a01b900460ff1681565b6109bb3361189a565b6109e05760405162461bcd60e51b81526004016109d790612cb7565b60405180910390fd5b60108590556011849055601283905560138290556014819055610a0f81610a09858189896118b7565b906118b7565b601581905560641015610a645760405162461bcd60e51b815260206004820152601c60248201527f466565732063616e6e6f74206265206d6f7265207468616e203130250000000060448201526064016109d7565b5050505050565b606060068054610a7a90612cdc565b80601f0160208091040260200160405190810160405280929190818152602001828054610aa690612cdc565b8015610af15780601f10610ac857610100808354040283529160200191610af1565b820191905f5260205f20905b815481529060010190602001808311610ad457829003601f168201915b5050505050905090565b335f818152600b602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610b559086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600b602090815260408083203384529091528120545f1914610c10576040805180820182526016815275496e73756666696369656e7420416c6c6f77616e636560501b6020808301919091526001600160a01b0387165f908152600b82528381203382529091529190912054610bec918490611915565b6001600160a01b0385165f908152600b602090815260408083203384529091529020555b610c1b84848461194d565b90505b9392505050565b6005546001600160a01b03165f908152600a6020526040812054600954610c4b91611c92565b905090565b601d5460405163051fa63360e31b81526001600160a01b0383811660048301525f9216906328fd319890602401602060405180830381865afa158015610c98573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b619190612d14565b610cc53361189a565b610ce15760405162461bcd60e51b81526004016109d790612cb7565b601d546040516316a4744b60e11b815260048101849052602481018390526001600160a01b0390911690632d48e896906044015b5f604051808303815f87803b158015610d2c575f5ffd5b505af1158015610d3e573d5f5f3e3d5ffd5b505050505050565b601d5f9054906101000a90046001600160a01b03166001600160a01b031663f0fc6bca6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610d92575f5ffd5b505af1158015610da4573d5f5f3e3d5ffd5b50505050565b610db33361189a565b610dcf5760405162461bcd60e51b81526004016109d790612cb7565b6021805460ff1916911515919091179055565b610deb3361189a565b610e075760405162461bcd60e51b81526004016109d790612cb7565b6064821115610e4d5760405162461bcd60e51b8152602060048201526012602482015271496e76616c69642070657263656e7461676560701b60448201526064016109d7565b6001600160a01b038116610e965760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103932b1b2b4bb32b960811b60448201526064016109d7565b475f610ead6064610ea78487611cd3565b90611d51565b90505f836001600160a01b031682617530906040515f60405180830381858888f193505050503d805f8114610efd576040519150601f19603f3d011682016040523d82523d5f602084013e610f02565b606091505b5050905080610a645760405162461bcd60e51b815260206004820152601760248201527f4661696c656420746f20636c6561722062616c616e636500000000000000000060448201526064016109d7565b5f610b61825f19610afb565b610f683361189a565b610f845760405162461bcd60e51b81526004016109d790612cb7565b6001600160a01b03919091165f908152600c60205260409020805460ff1916911515919091179055565b606060078054610a7a90612cdc565b610fc63361189a565b610fe25760405162461bcd60e51b81526004016109d790612cb7565b6001600160a01b0382166110275760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b60448201526064016109d7565b6001600160a01b0382165f818152600e60209081526040808320805486151560ff199182168117909255600d90935281842080549093168117909255519092917fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a35050565b6110973361189a565b6110b35760405162461bcd60e51b81526004016109d790612cb7565b6207a12081101580156110c95750622dc6c08111155b6111085760405162461bcd60e51b815260206004820152601060248201526f476173206f7574206f662072616e676560801b60448201526064016109d7565b601e55565b6111163361189a565b6111325760405162461bcd60e51b81526004016109d790612cb7565b601880546001600160a01b039384166001600160a01b03199182161790915560198054929093169116179055565b6111693361189a565b6111855760405162461bcd60e51b81526004016109d790612cb7565b60648110156111cb5760405162461bcd60e51b81526020600482015260126024820152714d756c7469706c69657220746f6f206c6f7760701b60448201526064016109d7565b6103e88111156112135760405162461bcd60e51b815260206004820152601360248201527209aead8e8d2e0d8d2cae440e8dede40d0d2ced606b1b60448201526064016109d7565b601755565b5f610c1e33848461194d565b5f546001600160a01b0316331461124d5760405162461bcd60e51b81526004016109d790612d2b565b6001600160a01b03165f908152600160208190526040909120805460ff19169091179055565b61127c3361189a565b6112985760405162461bcd60e51b81526004016109d790612cb7565b5f811180156112b55750305f908152600a60205260409020548111155b6112f25760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016109d7565b602154610100900460ff161561133c5760405162461bcd60e51b815260206004820152600f60248201526e0416c726561647920696e207377617608c1b60448201526064016109d7565b602080549082905561134c611d92565b1561135957611359611dcf565b60205550565b5f546001600160a01b031633146113885760405162461bcd60e51b81526004016109d790612d2b565b600f5460ff166113da5760405162461bcd60e51b815260206004820152601960248201527f4d6f6f6e206d697373696f6e20616c7265616479206120676f0000000000000060448201526064016109d7565b601c805460ff60a01b1916600160a01b179055600f805460ff19169055565b6114023361189a565b61141e5760405162461bcd60e51b81526004016109d790612cb7565b306001600160a01b038316036114765760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742077697468647261772054445220697473656c6600000000000060448201526064016109d7565b6001600160a01b0381166114bf5760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103932b1b2b4bb32b960811b60448201526064016109d7565b6040516370a0823160e01b815230600482015282905f906001600160a01b038316906370a0823190602401602060405180830381865afa158015611505573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115299190612d14565b60405163a9059cbb60e01b81526001600160a01b038581166004830152602482018390529192509083169063a9059cbb906044016020604051808303815f875af1158015611579573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a649190612d4b565b5f610b616115a9610c25565b601c546001600160a01b03165f908152600a6020526040902054610ea7906115d5906002905b90611cd3565b8590611cd3565b6115e53361189a565b6116015760405162461bcd60e51b81526004016109d790612cb7565b601f805460ff191692151592909217909155602055565b5f546001600160a01b031633146116415760405162461bcd60e51b81526004016109d790612d2b565b5f546001600160a01b039081169082160361169e5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420756e617574686f72697a65206f776e6572000000000000000060448201526064016109d7565b6001600160a01b03165f908152600160205260409020805460ff19169055565b5f546001600160a01b031633146116e75760405162461bcd60e51b81526004016109d790612d2b565b6001600160a01b03811661172f5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016109d7565b5f80546001600160a01b0319166001600160a01b038316908117825580825260016020818152604093849020805460ff191690921790915591519081527f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc686163910160405180910390a150565b6117a33361189a565b6117bf5760405162461bcd60e51b81526004016109d790612cb7565b6001600160a01b03821630148015906117e65750601c546001600160a01b03838116911614155b6117ee575f5ffd5b6001600160a01b0382165f908152600d60205260409020805460ff1916821580159190911790915561185257601d54604051630a5b654b60e11b81526001600160a01b0384811660048301525f6024830152909116906314b6ca9690604401610d15565b601d546001600160a01b038381165f818152600a602052604090819020549051630a5b654b60e11b8152600481019290925260248201529116906314b6ca9690604401610d15565b6001600160a01b03165f9081526001602052604090205460ff1690565b5f806118c38385612d7a565b905083811015610c1e5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f77000000000060448201526064016109d7565b5f81848411156119385760405162461bcd60e51b81526004016109d79190612ad1565b505f6119448486612d8d565b95945050505050565b6021545f90610100900460ff16806119725750601d546001600160a01b038581169116145b15611989576119828484846123d0565b9050610c1e565b6001600160a01b0384165f9081526001602052604090205460ff161580156119c957506001600160a01b0383165f9081526001602052604090205460ff16155b15611a1e57601c54600160a01b900460ff16611a1e5760405162461bcd60e51b8152602060048201526014602482015273151c98591a5b99c81b9bdd081bdc195b881e595d60621b60448201526064016109d7565b6001600160a01b0383165f908152600e602052604090205460ff168015611a485750611a48611d92565b15611a5557611a55611dcf565b6040805180820182526014815273496e73756666696369656e742042616c616e636560601b6020808301919091526001600160a01b0387165f908152600a9091529190912054611aa6918490611915565b6001600160a01b0385165f908152600a6020526040812091909155611acb85856124a0565b611ad55782611afd565b6001600160a01b0384165f908152600e6020526040902054611afd908690859060ff166124e7565b6001600160a01b0385165f908152600a6020526040902054909150611b2290826118b7565b6001600160a01b038086165f908152600a60209081526040808320949094559188168152600d909152205460ff16611bc157601d546001600160a01b038681165f818152600a602052604090819020549051630a5b654b60e11b8152600481019290925260248201529116906314b6ca96906044015f604051808303815f87803b158015611bae575f5ffd5b505af1925050508015611bbf575060015b505b6001600160a01b0384165f908152600d602052604090205460ff16611c4d57601d546001600160a01b038581165f818152600a602052604090819020549051630a5b654b60e11b8152600481019290925260248201529116906314b6ca96906044015f604051808303815f87803b158015611c3a575f5ffd5b505af1925050508015611c4b575060015b505b836001600160a01b0316856001600160a01b03165f516020612ec85f395f51905f5283604051611c7f91815260200190565b60405180910390a3506001949350505050565b5f610c1e83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611915565b5f825f03611ce257505f610b61565b5f611ced8385612da0565b905082611cfa8583612db7565b14610c1e5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b60648201526084016109d7565b5f610c1e83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612652565b6021545f90610100900460ff16158015611dae5750601f5460ff165b8015610c4b57505060208054305f908152600a909252604090912054101590565b6021805461ff0019166101001790556015546014546020545f92611dfd92600292610ea79291839190611cd3565b90505f611e226002610ea7601554610ea7601054602054611cd390919063ffffffff16565b90505f611e4483611e3e84602054611c9290919063ffffffff16565b90611c92565b60408051600280825260608201835292935047925f9260208301908036833701905050905030815f81518110611e7c57611e7c612dd6565b6001600160a01b039283166020918202929092010152600254825191169082906001908110611ead57611ead612dd6565b6001600160a01b039283166020918202929092010152601a5460405163791ac94760e01b815291169063791ac94790611ef29086905f90869030904290600401612e2d565b5f604051808303815f87803b158015611f09575f5ffd5b505af1158015611f1b573d5f5f3e3d5ffd5b505050505f611f338347611c9290919063ffffffff16565b90505f611f6f6103e86115cf611f66611f586002601454611d5190919063ffffffff16565b601054610a09906002611d51565b60155490611c92565b90505f611f946002610ea7611f86856103e8611d51565b601054610ea7908890611cd3565b90505f611fb96002610ea7611fab866103e8611d51565b601454610ea7908990611cd3565b90505f611fd9611fcb856103e8611d51565b601154610ea7908890611cd3565b90505f611ff9611feb866103e8611d51565b601254610ea7908990611cd3565b9050601d5f9054906101000a90046001600160a01b03166001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004015f604051808303818588803b158015612048575f5ffd5b505af19350505050801561205a575060015b50601d54601e546040516001624d3b8760e01b031981526001600160a01b039092169163ffb2c479916120939160040190815260200190565b5f604051808303815f87803b1580156120aa575f5ffd5b505af19250505080156120bb575060015b5080156122725760215460ff1615612219576040805160028082526060820183525f92602083019080368337505060025482519293506001600160a01b0316918391505f9061210c5761210c612dd6565b6001600160a01b03928316602091820292909201015260045482519116908290600190811061213d5761213d612dd6565b6001600160a01b039283166020918202929092010152601b5460195460405163b6f9de9560e01b81529183169263b6f9de95928692612188925f928892909116904290600401612e68565b5f604051808303818588803b15801561219f575f5ffd5b505af1935050505080156121b1575060015b612213576019546040515f916001600160a01b03169061753090859084818181858888f193505050503d805f8114612204576040519150601f19603f3d011682016040523d82523d5f602084013e612209565b606091505b5061221392505050565b50612272565b6019546040515f916001600160a01b03169061753090849084818181858888f193505050503d805f8114612268576040519150601f19603f3d011682016040523d82523d5f602084013e61226d565b606091505b505050505b821561228257612282838c61267e565b891561235757601a5460185460405163f305d71960e01b8152306004820152602481018d90525f6044820181905260648201526001600160a01b0391821660848201524260a482015291169063f305d71990869060c40160606040518083038185885af11580156122f5573d5f5f3e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061231a9190612e9c565b505060408051868152602081018d90527f424db2872186fa7e7afa7a5e902ed3b49a2ef19c2f5431e672462495dd6b450692500160405180910390a15b4780156123b7576019546040515f916001600160a01b03169061753090849084818181858888f193505050503d805f81146123ad576040519150601f19603f3d011682016040523d82523d5f602084013e6123b2565b606091505b505050505b50506021805461ff001916905550505050505050505050565b6040805180820182526014815273496e73756666696369656e742042616c616e636560601b6020808301919091526001600160a01b0386165f908152600a90915291822054612420918490611915565b6001600160a01b038086165f908152600a6020526040808220939093559085168152205461244e90836118b7565b6001600160a01b038085165f818152600a602052604090819020939093559151908616905f516020612ec85f395f51905f529061248e9086815260200190565b60405180910390a35060019392505050565b6001600160a01b0381165f908152600c602052604081205460ff16156124c757505f610b61565b50506001600160a01b03165f908152600c602052604090205460ff161590565b5f5f826124f55760646124f9565b6017545b90505f61252e6125156064601654611cd390919063ffffffff16565b610ea7846115cf6015548a611cd390919063ffffffff16565b90505f61256361254a6064601654611cd390919063ffffffff16565b610ea7856115cf6013548b611cd390919063ffffffff16565b905080156125db576005546001600160a01b03165f908152600a602052604090205461258f90826118b7565b600580546001600160a01b039081165f908152600a6020908152604091829020949094559154915184815291811692908a16915f516020612ec85f395f51905f52910160405180910390a35b305f908152600a60205260409020546125f490836118b7565b305f818152600a6020526040908190209290925590516001600160a01b038916905f516020612ec85f395f51905f52906126319086815260200190565b60405180910390a361264781611e3e8885611c92565b979650505050505050565b5f81836126725760405162461bcd60e51b81526004016109d79190612ad1565b505f6119448486612db7565b6003546040516370a0823160e01b81523060048201526001600160a01b03909116905f9082906370a0823190602401602060405180830381865afa1580156126c8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ec9190612d14565b6040805160028082526060820183529293505f929091602083019080368337505060025482519293506001600160a01b0316918391505f9061273057612730612dd6565b6001600160a01b03928316602091820292909201015260035482519116908290600190811061276157612761612dd6565b6001600160a01b039283166020918202929092010152601b5460405163b6f9de9560e01b815291169063b6f9de959087906127a6905f90869030904290600401612e68565b5f604051808303818588803b1580156127bd575f5ffd5b505af11580156127cf573d5f5f3e3d5ffd5b50506040516370a0823160e01b81523060048201525f935061284292508591506001600160a01b038716906370a0823190602401602060405180830381865afa15801561281e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e3e9190612d14565b601a5460405163095ea7b360e01b81526001600160a01b0391821660048201525f19602482015291925085169063095ea7b3906044016020604051808303815f875af1158015612894573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128b89190612d4b565b50601a5460185460405162e8e33760e81b81526001600160a01b03878116600483015230602483015260448201859052606482018990525f6084830181905260a4830181905292811660c48301524260e483015291928392839291169063e8e3370090610104016060604051808303815f875af115801561293b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061295f9190612e9c565b6040516370a0823160e01b815230600482015292955090935091505f906001600160a01b038916906370a0823190602401602060405180830381865afa1580156129ab573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129cf9190612d14565b90508015612a4d5760195460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529089169063a9059cbb906044016020604051808303815f875af1158015612a27573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a4b9190612d4b565b505b60408051858152602081018590529081018390527f601e04dcba86d8ec3f3767c0683dac288a3fe5b84477036545d9edb1577337889060600160405180910390a150505050505050505050565b5f5f5f5f5f60a08688031215612aae575f5ffd5b505083359560208501359550604085013594606081013594506080013592509050565b602081525f82518060208401525f5b81811015612afd5760208186018101516040868401015201612ae0565b505f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114612b30575f5ffd5b50565b5f5f60408385031215612b44575f5ffd5b8235612b4f81612b1c565b946020939093013593505050565b5f5f5f60608486031215612b6f575f5ffd5b8335612b7a81612b1c565b92506020840135612b8a81612b1c565b929592945050506040919091013590565b5f60208284031215612bab575f5ffd5b8135610c1e81612b1c565b5f5f60408385031215612bc7575f5ffd5b50508035926020909101359150565b8015158114612b30575f5ffd5b5f60208284031215612bf3575f5ffd5b8135610c1e81612bd6565b5f5f60408385031215612c0f575f5ffd5b823591506020830135612c2181612b1c565b809150509250929050565b5f5f60408385031215612c3d575f5ffd5b8235612c4881612b1c565b91506020830135612c2181612bd6565b5f60208284031215612c68575f5ffd5b5035919050565b5f5f60408385031215612c80575f5ffd5b8235612c8b81612b1c565b91506020830135612c2181612b1c565b5f5f60408385031215612cac575f5ffd5b8235612b4f81612bd6565b6020808252600b908201526a085055551213d49256915160aa1b604082015260600190565b600181811c90821680612cf057607f821691505b602082108103612d0e57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612d24575f5ffd5b5051919050565b60208082526006908201526510a7aba722a960d11b604082015260600190565b5f60208284031215612d5b575f5ffd5b8151610c1e81612bd6565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610b6157610b61612d66565b81810381811115610b6157610b61612d66565b8082028115828204841417610b6157610b61612d66565b5f82612dd157634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffd5b5f8151808452602084019350602083015f5b82811015612e235781516001600160a01b0316865260209586019590910190600101612dfc565b5093949350505050565b85815284602082015260a060408201525f612e4b60a0830186612dea565b6001600160a01b0394909416606083015250608001529392505050565b848152608060208201525f612e806080830186612dea565b6001600160a01b03949094166040830152506060015292915050565b5f5f5f60608486031215612eae575f5ffd5b505081516020830151604090930151909492935091905056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220165efc3518424d09362a89319d51582904df4729026804fccdd3f5ee43870b3f64736f6c634300081c00336080604052600280546001600160a01b03191673a1077a294dde1b09bb078844df40758a5d0f9a271790556ec097ce7bc90715b34b9f1000000000600c555f600d819055600e55348015610051575f5ffd5b50604051610f84380380610f84833981016040819052610070916100d5565b6001600160a01b0381166100985773165c3410fc91ef562c50559f7d2289febed552d961009a565b805b600380546001600160a01b03929092166001600160a01b03199283161790555f80548216339081179091556001805490921617905550610102565b5f602082840312156100e5575f5ffd5b81516001600160a01b03811681146100fb575f5ffd5b9392505050565b610e758061010f5f395ff3fe6080604052600436106100d9575f3560e01c8063ce7c2ac21161007c578063efca2eed11610057578063efca2eed14610215578063f0fc6bca1461022a578063ffb2c4791461023e578063ffd49c841461025d575f5ffd5b8063ce7c2ac2146101a3578063d0e30db0146101f8578063e2d2e21914610200575f5ffd5b80632d48e896116100b75780632d48e896146101455780633a98ef39146101645780634fab0ae814610179578063997664d71461018e575f5ffd5b806311ce023d146100dd57806314b6ca961461010557806328fd319814610126575b5f5ffd5b3480156100e8575f5ffd5b506100f2600c5481565b6040519081526020015b60405180910390f35b348015610110575f5ffd5b5061012461011f366004610c2d565b610272565b005b348015610131575f5ffd5b506100f2610140366004610c55565b6103e0565b348015610150575f5ffd5b5061012461015f366004610c6e565b610466565b34801561016f575f5ffd5b506100f260085481565b348015610184575f5ffd5b506100f2600e5481565b348015610199575f5ffd5b506100f260095481565b3480156101ae575f5ffd5b506101dd6101bd366004610c55565b60076020525f908152604090208054600182015460029092015490919083565b604080519384526020840192909252908201526060016100fc565b610124610486565b34801561020b575f5ffd5b506100f2600b5481565b348015610220575f5ffd5b506100f2600a5481565b348015610235575f5ffd5b506101246106b5565b348015610249575f5ffd5b50610124610258366004610c8e565b6106c0565b348015610268575f5ffd5b506100f2600d5481565b5f546001600160a01b03163314610287575f5ffd5b6001600160a01b0382165f90815260076020526040902054156102ad576102ad826107bb565b5f811180156102d157506001600160a01b0382165f90815260076020526040902054155b1561033657600480546001600160a01b0384165f818152600560205260408120839055600183018455929092527f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b0180546001600160a01b0319169091179055610368565b8015801561035a57506001600160a01b0382165f9081526007602052604090205415155b1561036857610368826108d2565b6001600160a01b0382165f90815260076020526040902054600854610398918391610392916109e2565b90610a2c565b6008556001600160a01b0382165f9081526007602052604090208190556103be81610a8f565b6001600160a01b039092165f9081526007602052604090206001019190915550565b6001600160a01b0381165f90815260076020526040812054810361040557505f919050565b6001600160a01b0382165f9081526007602052604081205461042690610a8f565b6001600160a01b0384165f9081526007602052604090206001015490915080821161045457505f9392505050565b61045e82826109e2565b949350505050565b5f546001600160a01b0316331461047b575f5ffd5b600d91909155600e55565b5f546001600160a01b0316331461049b575f5ffd5b6001546040516370a0823160e01b81523060048201525f916001600160a01b0316906370a0823190602401602060405180830381865afa1580156104e1573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105059190610ca5565b6040805160028082526060820183529293505f929091602083019080368337505060025482519293506001600160a01b0316918391505f9061054957610549610cbc565b6001600160a01b039283166020918202929092010152600180548351921691839190811061057957610579610cbc565b6001600160a01b03928316602091820292909201015260035460405163b6f9de9560e01b815291169063b6f9de959034906105be905f90869030904290600401610cd0565b5f604051808303818588803b1580156105d5575f5ffd5b505af11580156105e7573d5f5f3e3d5ffd5b50506001546040516370a0823160e01b81523060048201525f945061066493508692506001600160a01b03909116906370a0823190602401602060405180830381865afa15801561063a573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061065e9190610ca5565b906109e2565b6009549091506106749082610a2c565b600955600854156106b0576106ac6106a360085461069d84600c54610aab90919063ffffffff16565b90610b29565b600b5490610a2c565b600b555b505050565b6106be336107bb565b565b5f546001600160a01b031633146106d5575f5ffd5b6004545f8190036106e4575050565b5f805a90505f5b84831080156106f957508381105b156107b45783600f541061070c575f600f555b61073d6004600f548154811061072457610724610cbc565b5f918252602090912001546001600160a01b0316610b6a565b15610773576107736004600f548154811061075a5761075a610cbc565b5f918252602090912001546001600160a01b03166107bb565b6107886107815a84906109e2565b8490610a2c565b92505a600f80549193505f61079c83610d4d565b919050555080806107ac90610d4d565b9150506106eb565b5050505050565b6001600160a01b0381165f9081526007602052604081205490036107dc5750565b5f6107e6826103e0565b905080156108ce57600a546107fb9082610a2c565b600a5560015460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016020604051808303815f875af115801561084e573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108729190610d65565b506001600160a01b0382165f90815260066020908152604080832042905560079091529020600201546108a59082610a2c565b6001600160a01b0383165f9081526007602052604090206002810191909155546103be90610a8f565b5050565b600480546108e290600190610d84565b815481106108f2576108f2610cbc565b5f9182526020808320909101546001600160a01b038481168452600590925260409092205460048054929093169291811061092f5761092f610cbc565b5f91825260208083209190910180546001600160a01b0319166001600160a01b0394851617905591831681526005918290526040812054600480549193929161097a90600190610d84565b8154811061098a5761098a610cbc565b5f9182526020808320909101546001600160a01b0316835282019290925260400190205560048054806109bf576109bf610d97565b5f8281526020902081015f1990810180546001600160a01b031916905501905550565b5f610a2383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250610bae565b90505b92915050565b5f80610a388385610dab565b905083811015610a235760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f77000000000060448201526064015b60405180910390fd5b5f610a26600c5461069d600b5485610aab90919063ffffffff16565b5f825f03610aba57505f610a26565b5f610ac58385610dbe565b905082610ad28583610dd5565b14610a235760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610a86565b5f610a2383836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250610be6565b600d546001600160a01b0382165f9081526006602052604081205490914291610b939190610dab565b108015610a265750600e54610ba7836103e0565b1192915050565b5f8184841115610bd15760405162461bcd60e51b8152600401610a869190610df4565b505f610bdd8486610d84565b95945050505050565b5f8183610c065760405162461bcd60e51b8152600401610a869190610df4565b505f610bdd8486610dd5565b80356001600160a01b0381168114610c28575f5ffd5b919050565b5f5f60408385031215610c3e575f5ffd5b610c4783610c12565b946020939093013593505050565b5f60208284031215610c65575f5ffd5b610a2382610c12565b5f5f60408385031215610c7f575f5ffd5b50508035926020909101359150565b5f60208284031215610c9e575f5ffd5b5035919050565b5f60208284031215610cb5575f5ffd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b5f608082018683526080602084015280865180835260a0850191506020880192505f5b81811015610d1a5783516001600160a01b0316835260209384019390920191600101610cf3565b50506001600160a01b0395909516604084015250506060015292915050565b634e487b7160e01b5f52601160045260245ffd5b5f60018201610d5e57610d5e610d39565b5060010190565b5f60208284031215610d75575f5ffd5b81518015158114610a23575f5ffd5b81810381811115610a2657610a26610d39565b634e487b7160e01b5f52603160045260245ffd5b80820180821115610a2657610a26610d39565b8082028115828204841417610a2657610a26610d39565b5f82610def57634e487b7160e01b5f52601260045260245ffd5b500490565b602081525f82518060208401525f5b81811015610e205760208186018101516040868401015201610e03565b505f604082850101526040601f19601f8301168401019150509291505056fea264697066735822122001884ac2dd628fe0b61703c5f6f0c8c8eac103594a336109bd5ec9b74147314f64736f6c634300081c0033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000010b07600000000000000000000000000000000000000000000000000000000000000000f546f6b656e5472616465722e57696e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035444520000000000000000000000000000000000000000000000000000000000

Deployed ByteCode

0x60806040526004361061032a575f3560e01c806395d89b41116101a3578063ca33e64c116100f2578063f887ea4011610092578063fe634ad01161006d578063fe634ad014610945578063fe9fbb801461095e578063fed0d2a11461097d578063ffb54a9914610992575f5ffd5b8063f887ea40146108f8578063fb6b2abb14610917578063fce589d814610930575f5ffd5b8063df20fd49116100cd578063df20fd491461087c578063f0b37c041461089b578063f2fde38b146108ba578063f708a64f146108d9575f5ffd5b8063ca33e64c146107fa578063d51ed1c814610819578063dd62ed3e14610838575f5ffd5b8063a8aa1b311161015d578063b6a5d7de11610138578063b6a5d7de14610789578063bffda982146107a8578063c191c926146107c7578063c40fedc6146107db575f5ffd5b8063a8aa1b3114610736578063a9059cbb14610755578063af2383b814610774575f5ffd5b806395d89b411461069157806398118cb4146106a55780639a7a23d6146106ba5780639d1944f5146106d9578063a4b45c00146106f8578063a7bc1de014610717575f5ffd5b806330d20cf4116102795780635ab76742116102195780636ddd1713116101f45780636ddd17131461060957806370a0823114610622578063893d20e8146106565780638d3434bd14610672575f5ffd5b80635ab76742146105b65780635db9a3d7146105cb578063658d4b7f146105ea575f5ffd5b806343cfa9a51161025457806343cfa9a5146105445780634ac800dc1461056357806356a227f214610578578063571ac8b014610597575f5ffd5b806330d20cf4146104d8578063313ce5671461050f57806338821f1914610530575f5ffd5b80631df4ccfc116102e45780632b112e49116102bf5780632b112e49146104595780632ca8a1981461046d5780632d48e8961461048c5780632f54bf6e146104ab575f5ffd5b80631df4ccfc146103f757806323b872dd1461040c578063255fe8471461042b575f5ffd5b80630445b6671461033557806304a66b481461035d57806306fdde031461037e578063095ea7b31461039f578063180b0d7e146103ce57806318160ddd146103e3575f5ffd5b3661033157005b5f5ffd5b348015610340575f5ffd5b5061034a60205481565b6040519081526020015b60405180910390f35b348015610368575f5ffd5b5061037c610377366004612a9a565b6109b2565b005b348015610389575f5ffd5b50610392610a6b565b6040516103549190612ad1565b3480156103aa575f5ffd5b506103be6103b9366004612b33565b610afb565b6040519015158152602001610354565b3480156103d9575f5ffd5b5061034a60165481565b3480156103ee575f5ffd5b5060095461034a565b348015610402575f5ffd5b5061034a60155481565b348015610417575f5ffd5b506103be610426366004612b5d565b610b67565b348015610436575f5ffd5b506103be610445366004612b9b565b600e6020525f908152604090205460ff1681565b348015610464575f5ffd5b5061034a610c25565b348015610478575f5ffd5b5061034a610487366004612b9b565b610c50565b348015610497575f5ffd5b5061037c6104a6366004612bb6565b610cbc565b3480156104b6575f5ffd5b506103be6104c5366004612b9b565b5f546001600160a01b0391821691161490565b3480156104e3575f5ffd5b50601d546104f7906001600160a01b031681565b6040516001600160a01b039091168152602001610354565b34801561051a575f5ffd5b5060085460405160ff9091168152602001610354565b34801561053b575f5ffd5b5061037c610d46565b34801561054f575f5ffd5b5061037c61055e366004612be3565b610daa565b34801561056e575f5ffd5b5061034a60125481565b348015610583575f5ffd5b5061037c610592366004612bfe565b610de2565b3480156105a2575f5ffd5b506103be6105b1366004612b9b565b610f53565b3480156105c1575f5ffd5b5061034a60145481565b3480156105d6575f5ffd5b506019546104f7906001600160a01b031681565b3480156105f5575f5ffd5b5061037c610604366004612c2c565b610f5f565b348015610614575f5ffd5b50601f546103be9060ff1681565b34801561062d575f5ffd5b5061034a61063c366004612b9b565b6001600160a01b03165f908152600a602052604090205490565b348015610661575f5ffd5b505f546001600160a01b03166104f7565b34801561067d575f5ffd5b50601b546104f7906001600160a01b031681565b34801561069c575f5ffd5b50610392610fae565b3480156106b0575f5ffd5b5061034a60105481565b3480156106c5575f5ffd5b5061037c6106d4366004612c2c565b610fbd565b3480156106e4575f5ffd5b5061037c6106f3366004612c58565b61108e565b348015610703575f5ffd5b5061037c610712366004612c6f565b61110d565b348015610722575f5ffd5b5061037c610731366004612c58565b611160565b348015610741575f5ffd5b50601c546104f7906001600160a01b031681565b348015610760575f5ffd5b506103be61076f366004612b33565b611218565b34801561077f575f5ffd5b5061034a60115481565b348015610794575f5ffd5b5061037c6107a3366004612b9b565b611224565b3480156107b3575f5ffd5b5061037c6107c2366004612c58565b611273565b3480156107d2575f5ffd5b5061037c61135f565b3480156107e6575f5ffd5b5061037c6107f5366004612c6f565b6113f9565b348015610805575f5ffd5b506018546104f7906001600160a01b031681565b348015610824575f5ffd5b5061034a610833366004612c58565b61159d565b348015610843575f5ffd5b5061034a610852366004612c6f565b6001600160a01b039182165f908152600b6020908152604080832093909416825291909152205490565b348015610887575f5ffd5b5061037c610896366004612c9b565b6115dc565b3480156108a6575f5ffd5b5061037c6108b5366004612b9b565b611618565b3480156108c5575f5ffd5b5061037c6108d4366004612b9b565b6116be565b3480156108e4575f5ffd5b5061037c6108f3366004612c2c565b61179a565b348015610903575f5ffd5b50601a546104f7906001600160a01b031681565b348015610922575f5ffd5b506021546103be9060ff1681565b34801561093b575f5ffd5b5061034a60135481565b348015610950575f5ffd5b50600f546103be9060ff1681565b348015610969575f5ffd5b506103be610978366004612b9b565b61189a565b348015610988575f5ffd5b5061034a60175481565b34801561099d575f5ffd5b50601c546103be90600160a01b900460ff1681565b6109bb3361189a565b6109e05760405162461bcd60e51b81526004016109d790612cb7565b60405180910390fd5b60108590556011849055601283905560138290556014819055610a0f81610a09858189896118b7565b906118b7565b601581905560641015610a645760405162461bcd60e51b815260206004820152601c60248201527f466565732063616e6e6f74206265206d6f7265207468616e203130250000000060448201526064016109d7565b5050505050565b606060068054610a7a90612cdc565b80601f0160208091040260200160405190810160405280929190818152602001828054610aa690612cdc565b8015610af15780601f10610ac857610100808354040283529160200191610af1565b820191905f5260205f20905b815481529060010190602001808311610ad457829003601f168201915b5050505050905090565b335f818152600b602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610b559086815260200190565b60405180910390a35060015b92915050565b6001600160a01b0383165f908152600b602090815260408083203384529091528120545f1914610c10576040805180820182526016815275496e73756666696369656e7420416c6c6f77616e636560501b6020808301919091526001600160a01b0387165f908152600b82528381203382529091529190912054610bec918490611915565b6001600160a01b0385165f908152600b602090815260408083203384529091529020555b610c1b84848461194d565b90505b9392505050565b6005546001600160a01b03165f908152600a6020526040812054600954610c4b91611c92565b905090565b601d5460405163051fa63360e31b81526001600160a01b0383811660048301525f9216906328fd319890602401602060405180830381865afa158015610c98573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b619190612d14565b610cc53361189a565b610ce15760405162461bcd60e51b81526004016109d790612cb7565b601d546040516316a4744b60e11b815260048101849052602481018390526001600160a01b0390911690632d48e896906044015b5f604051808303815f87803b158015610d2c575f5ffd5b505af1158015610d3e573d5f5f3e3d5ffd5b505050505050565b601d5f9054906101000a90046001600160a01b03166001600160a01b031663f0fc6bca6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610d92575f5ffd5b505af1158015610da4573d5f5f3e3d5ffd5b50505050565b610db33361189a565b610dcf5760405162461bcd60e51b81526004016109d790612cb7565b6021805460ff1916911515919091179055565b610deb3361189a565b610e075760405162461bcd60e51b81526004016109d790612cb7565b6064821115610e4d5760405162461bcd60e51b8152602060048201526012602482015271496e76616c69642070657263656e7461676560701b60448201526064016109d7565b6001600160a01b038116610e965760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103932b1b2b4bb32b960811b60448201526064016109d7565b475f610ead6064610ea78487611cd3565b90611d51565b90505f836001600160a01b031682617530906040515f60405180830381858888f193505050503d805f8114610efd576040519150601f19603f3d011682016040523d82523d5f602084013e610f02565b606091505b5050905080610a645760405162461bcd60e51b815260206004820152601760248201527f4661696c656420746f20636c6561722062616c616e636500000000000000000060448201526064016109d7565b5f610b61825f19610afb565b610f683361189a565b610f845760405162461bcd60e51b81526004016109d790612cb7565b6001600160a01b03919091165f908152600c60205260409020805460ff1916911515919091179055565b606060078054610a7a90612cdc565b610fc63361189a565b610fe25760405162461bcd60e51b81526004016109d790612cb7565b6001600160a01b0382166110275760405162461bcd60e51b815260206004820152600c60248201526b5a65726f206164647265737360a01b60448201526064016109d7565b6001600160a01b0382165f818152600e60209081526040808320805486151560ff199182168117909255600d90935281842080549093168117909255519092917fffa9187bf1f18bf477bd0ea1bcbb64e93b6a98132473929edfce215cd9b16fab91a35050565b6110973361189a565b6110b35760405162461bcd60e51b81526004016109d790612cb7565b6207a12081101580156110c95750622dc6c08111155b6111085760405162461bcd60e51b815260206004820152601060248201526f476173206f7574206f662072616e676560801b60448201526064016109d7565b601e55565b6111163361189a565b6111325760405162461bcd60e51b81526004016109d790612cb7565b601880546001600160a01b039384166001600160a01b03199182161790915560198054929093169116179055565b6111693361189a565b6111855760405162461bcd60e51b81526004016109d790612cb7565b60648110156111cb5760405162461bcd60e51b81526020600482015260126024820152714d756c7469706c69657220746f6f206c6f7760701b60448201526064016109d7565b6103e88111156112135760405162461bcd60e51b815260206004820152601360248201527209aead8e8d2e0d8d2cae440e8dede40d0d2ced606b1b60448201526064016109d7565b601755565b5f610c1e33848461194d565b5f546001600160a01b0316331461124d5760405162461bcd60e51b81526004016109d790612d2b565b6001600160a01b03165f908152600160208190526040909120805460ff19169091179055565b61127c3361189a565b6112985760405162461bcd60e51b81526004016109d790612cb7565b5f811180156112b55750305f908152600a60205260409020548111155b6112f25760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a5908185b5bdd5b9d60921b60448201526064016109d7565b602154610100900460ff161561133c5760405162461bcd60e51b815260206004820152600f60248201526e0416c726561647920696e207377617608c1b60448201526064016109d7565b602080549082905561134c611d92565b1561135957611359611dcf565b60205550565b5f546001600160a01b031633146113885760405162461bcd60e51b81526004016109d790612d2b565b600f5460ff166113da5760405162461bcd60e51b815260206004820152601960248201527f4d6f6f6e206d697373696f6e20616c7265616479206120676f0000000000000060448201526064016109d7565b601c805460ff60a01b1916600160a01b179055600f805460ff19169055565b6114023361189a565b61141e5760405162461bcd60e51b81526004016109d790612cb7565b306001600160a01b038316036114765760405162461bcd60e51b815260206004820152601a60248201527f43616e6e6f742077697468647261772054445220697473656c6600000000000060448201526064016109d7565b6001600160a01b0381166114bf5760405162461bcd60e51b815260206004820152601060248201526f24b73b30b634b2103932b1b2b4bb32b960811b60448201526064016109d7565b6040516370a0823160e01b815230600482015282905f906001600160a01b038316906370a0823190602401602060405180830381865afa158015611505573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115299190612d14565b60405163a9059cbb60e01b81526001600160a01b038581166004830152602482018390529192509083169063a9059cbb906044016020604051808303815f875af1158015611579573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a649190612d4b565b5f610b616115a9610c25565b601c546001600160a01b03165f908152600a6020526040902054610ea7906115d5906002905b90611cd3565b8590611cd3565b6115e53361189a565b6116015760405162461bcd60e51b81526004016109d790612cb7565b601f805460ff191692151592909217909155602055565b5f546001600160a01b031633146116415760405162461bcd60e51b81526004016109d790612d2b565b5f546001600160a01b039081169082160361169e5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420756e617574686f72697a65206f776e6572000000000000000060448201526064016109d7565b6001600160a01b03165f908152600160205260409020805460ff19169055565b5f546001600160a01b031633146116e75760405162461bcd60e51b81526004016109d790612d2b565b6001600160a01b03811661172f5760405162461bcd60e51b815260206004820152600f60248201526e496e76616c6964206164647265737360881b60448201526064016109d7565b5f80546001600160a01b0319166001600160a01b038316908117825580825260016020818152604093849020805460ff191690921790915591519081527f04dba622d284ed0014ee4b9a6a68386be1a4c08a4913ae272de89199cc686163910160405180910390a150565b6117a33361189a565b6117bf5760405162461bcd60e51b81526004016109d790612cb7565b6001600160a01b03821630148015906117e65750601c546001600160a01b03838116911614155b6117ee575f5ffd5b6001600160a01b0382165f908152600d60205260409020805460ff1916821580159190911790915561185257601d54604051630a5b654b60e11b81526001600160a01b0384811660048301525f6024830152909116906314b6ca9690604401610d15565b601d546001600160a01b038381165f818152600a602052604090819020549051630a5b654b60e11b8152600481019290925260248201529116906314b6ca9690604401610d15565b6001600160a01b03165f9081526001602052604090205460ff1690565b5f806118c38385612d7a565b905083811015610c1e5760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f77000000000060448201526064016109d7565b5f81848411156119385760405162461bcd60e51b81526004016109d79190612ad1565b505f6119448486612d8d565b95945050505050565b6021545f90610100900460ff16806119725750601d546001600160a01b038581169116145b15611989576119828484846123d0565b9050610c1e565b6001600160a01b0384165f9081526001602052604090205460ff161580156119c957506001600160a01b0383165f9081526001602052604090205460ff16155b15611a1e57601c54600160a01b900460ff16611a1e5760405162461bcd60e51b8152602060048201526014602482015273151c98591a5b99c81b9bdd081bdc195b881e595d60621b60448201526064016109d7565b6001600160a01b0383165f908152600e602052604090205460ff168015611a485750611a48611d92565b15611a5557611a55611dcf565b6040805180820182526014815273496e73756666696369656e742042616c616e636560601b6020808301919091526001600160a01b0387165f908152600a9091529190912054611aa6918490611915565b6001600160a01b0385165f908152600a6020526040812091909155611acb85856124a0565b611ad55782611afd565b6001600160a01b0384165f908152600e6020526040902054611afd908690859060ff166124e7565b6001600160a01b0385165f908152600a6020526040902054909150611b2290826118b7565b6001600160a01b038086165f908152600a60209081526040808320949094559188168152600d909152205460ff16611bc157601d546001600160a01b038681165f818152600a602052604090819020549051630a5b654b60e11b8152600481019290925260248201529116906314b6ca96906044015f604051808303815f87803b158015611bae575f5ffd5b505af1925050508015611bbf575060015b505b6001600160a01b0384165f908152600d602052604090205460ff16611c4d57601d546001600160a01b038581165f818152600a602052604090819020549051630a5b654b60e11b8152600481019290925260248201529116906314b6ca96906044015f604051808303815f87803b158015611c3a575f5ffd5b505af1925050508015611c4b575060015b505b836001600160a01b0316856001600160a01b03165f516020612ec85f395f51905f5283604051611c7f91815260200190565b60405180910390a3506001949350505050565b5f610c1e83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611915565b5f825f03611ce257505f610b61565b5f611ced8385612da0565b905082611cfa8583612db7565b14610c1e5760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b60648201526084016109d7565b5f610c1e83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612652565b6021545f90610100900460ff16158015611dae5750601f5460ff165b8015610c4b57505060208054305f908152600a909252604090912054101590565b6021805461ff0019166101001790556015546014546020545f92611dfd92600292610ea79291839190611cd3565b90505f611e226002610ea7601554610ea7601054602054611cd390919063ffffffff16565b90505f611e4483611e3e84602054611c9290919063ffffffff16565b90611c92565b60408051600280825260608201835292935047925f9260208301908036833701905050905030815f81518110611e7c57611e7c612dd6565b6001600160a01b039283166020918202929092010152600254825191169082906001908110611ead57611ead612dd6565b6001600160a01b039283166020918202929092010152601a5460405163791ac94760e01b815291169063791ac94790611ef29086905f90869030904290600401612e2d565b5f604051808303815f87803b158015611f09575f5ffd5b505af1158015611f1b573d5f5f3e3d5ffd5b505050505f611f338347611c9290919063ffffffff16565b90505f611f6f6103e86115cf611f66611f586002601454611d5190919063ffffffff16565b601054610a09906002611d51565b60155490611c92565b90505f611f946002610ea7611f86856103e8611d51565b601054610ea7908890611cd3565b90505f611fb96002610ea7611fab866103e8611d51565b601454610ea7908990611cd3565b90505f611fd9611fcb856103e8611d51565b601154610ea7908890611cd3565b90505f611ff9611feb866103e8611d51565b601254610ea7908990611cd3565b9050601d5f9054906101000a90046001600160a01b03166001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004015f604051808303818588803b158015612048575f5ffd5b505af19350505050801561205a575060015b50601d54601e546040516001624d3b8760e01b031981526001600160a01b039092169163ffb2c479916120939160040190815260200190565b5f604051808303815f87803b1580156120aa575f5ffd5b505af19250505080156120bb575060015b5080156122725760215460ff1615612219576040805160028082526060820183525f92602083019080368337505060025482519293506001600160a01b0316918391505f9061210c5761210c612dd6565b6001600160a01b03928316602091820292909201015260045482519116908290600190811061213d5761213d612dd6565b6001600160a01b039283166020918202929092010152601b5460195460405163b6f9de9560e01b81529183169263b6f9de95928692612188925f928892909116904290600401612e68565b5f604051808303818588803b15801561219f575f5ffd5b505af1935050505080156121b1575060015b612213576019546040515f916001600160a01b03169061753090859084818181858888f193505050503d805f8114612204576040519150601f19603f3d011682016040523d82523d5f602084013e612209565b606091505b5061221392505050565b50612272565b6019546040515f916001600160a01b03169061753090849084818181858888f193505050503d805f8114612268576040519150601f19603f3d011682016040523d82523d5f602084013e61226d565b606091505b505050505b821561228257612282838c61267e565b891561235757601a5460185460405163f305d71960e01b8152306004820152602481018d90525f6044820181905260648201526001600160a01b0391821660848201524260a482015291169063f305d71990869060c40160606040518083038185885af11580156122f5573d5f5f3e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061231a9190612e9c565b505060408051868152602081018d90527f424db2872186fa7e7afa7a5e902ed3b49a2ef19c2f5431e672462495dd6b450692500160405180910390a15b4780156123b7576019546040515f916001600160a01b03169061753090849084818181858888f193505050503d805f81146123ad576040519150601f19603f3d011682016040523d82523d5f602084013e6123b2565b606091505b505050505b50506021805461ff001916905550505050505050505050565b6040805180820182526014815273496e73756666696369656e742042616c616e636560601b6020808301919091526001600160a01b0386165f908152600a90915291822054612420918490611915565b6001600160a01b038086165f908152600a6020526040808220939093559085168152205461244e90836118b7565b6001600160a01b038085165f818152600a602052604090819020939093559151908616905f516020612ec85f395f51905f529061248e9086815260200190565b60405180910390a35060019392505050565b6001600160a01b0381165f908152600c602052604081205460ff16156124c757505f610b61565b50506001600160a01b03165f908152600c602052604090205460ff161590565b5f5f826124f55760646124f9565b6017545b90505f61252e6125156064601654611cd390919063ffffffff16565b610ea7846115cf6015548a611cd390919063ffffffff16565b90505f61256361254a6064601654611cd390919063ffffffff16565b610ea7856115cf6013548b611cd390919063ffffffff16565b905080156125db576005546001600160a01b03165f908152600a602052604090205461258f90826118b7565b600580546001600160a01b039081165f908152600a6020908152604091829020949094559154915184815291811692908a16915f516020612ec85f395f51905f52910160405180910390a35b305f908152600a60205260409020546125f490836118b7565b305f818152600a6020526040908190209290925590516001600160a01b038916905f516020612ec85f395f51905f52906126319086815260200190565b60405180910390a361264781611e3e8885611c92565b979650505050505050565b5f81836126725760405162461bcd60e51b81526004016109d79190612ad1565b505f6119448486612db7565b6003546040516370a0823160e01b81523060048201526001600160a01b03909116905f9082906370a0823190602401602060405180830381865afa1580156126c8573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126ec9190612d14565b6040805160028082526060820183529293505f929091602083019080368337505060025482519293506001600160a01b0316918391505f9061273057612730612dd6565b6001600160a01b03928316602091820292909201015260035482519116908290600190811061276157612761612dd6565b6001600160a01b039283166020918202929092010152601b5460405163b6f9de9560e01b815291169063b6f9de959087906127a6905f90869030904290600401612e68565b5f604051808303818588803b1580156127bd575f5ffd5b505af11580156127cf573d5f5f3e3d5ffd5b50506040516370a0823160e01b81523060048201525f935061284292508591506001600160a01b038716906370a0823190602401602060405180830381865afa15801561281e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e3e9190612d14565b601a5460405163095ea7b360e01b81526001600160a01b0391821660048201525f19602482015291925085169063095ea7b3906044016020604051808303815f875af1158015612894573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128b89190612d4b565b50601a5460185460405162e8e33760e81b81526001600160a01b03878116600483015230602483015260448201859052606482018990525f6084830181905260a4830181905292811660c48301524260e483015291928392839291169063e8e3370090610104016060604051808303815f875af115801561293b573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061295f9190612e9c565b6040516370a0823160e01b815230600482015292955090935091505f906001600160a01b038916906370a0823190602401602060405180830381865afa1580156129ab573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129cf9190612d14565b90508015612a4d5760195460405163a9059cbb60e01b81526001600160a01b039182166004820152602481018390529089169063a9059cbb906044016020604051808303815f875af1158015612a27573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612a4b9190612d4b565b505b60408051858152602081018590529081018390527f601e04dcba86d8ec3f3767c0683dac288a3fe5b84477036545d9edb1577337889060600160405180910390a150505050505050505050565b5f5f5f5f5f60a08688031215612aae575f5ffd5b505083359560208501359550604085013594606081013594506080013592509050565b602081525f82518060208401525f5b81811015612afd5760208186018101516040868401015201612ae0565b505f604082850101526040601f19601f83011684010191505092915050565b6001600160a01b0381168114612b30575f5ffd5b50565b5f5f60408385031215612b44575f5ffd5b8235612b4f81612b1c565b946020939093013593505050565b5f5f5f60608486031215612b6f575f5ffd5b8335612b7a81612b1c565b92506020840135612b8a81612b1c565b929592945050506040919091013590565b5f60208284031215612bab575f5ffd5b8135610c1e81612b1c565b5f5f60408385031215612bc7575f5ffd5b50508035926020909101359150565b8015158114612b30575f5ffd5b5f60208284031215612bf3575f5ffd5b8135610c1e81612bd6565b5f5f60408385031215612c0f575f5ffd5b823591506020830135612c2181612b1c565b809150509250929050565b5f5f60408385031215612c3d575f5ffd5b8235612c4881612b1c565b91506020830135612c2181612bd6565b5f60208284031215612c68575f5ffd5b5035919050565b5f5f60408385031215612c80575f5ffd5b8235612c8b81612b1c565b91506020830135612c2181612b1c565b5f5f60408385031215612cac575f5ffd5b8235612b4f81612bd6565b6020808252600b908201526a085055551213d49256915160aa1b604082015260600190565b600181811c90821680612cf057607f821691505b602082108103612d0e57634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215612d24575f5ffd5b5051919050565b60208082526006908201526510a7aba722a960d11b604082015260600190565b5f60208284031215612d5b575f5ffd5b8151610c1e81612bd6565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610b6157610b61612d66565b81810381811115610b6157610b61612d66565b8082028115828204841417610b6157610b61612d66565b5f82612dd157634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52603260045260245ffd5b5f8151808452602084019350602083015f5b82811015612e235781516001600160a01b0316865260209586019590910190600101612dfc565b5093949350505050565b85815284602082015260a060408201525f612e4b60a0830186612dea565b6001600160a01b0394909416606083015250608001529392505050565b848152608060208201525f612e806080830186612dea565b6001600160a01b03949094166040830152506060015292915050565b5f5f5f60608486031215612eae575f5ffd5b505081516020830151604090930151909492935091905056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220165efc3518424d09362a89319d51582904df4729026804fccdd3f5ee43870b3f64736f6c634300081c0033