BNB Price: $614.41 (-0.07%)
 

Overview

Max Total Supply

5,800,000,000ATM

Holders

1,411

Market

Price

$0.00 @ 0.000000 BNB

Onchain Market Cap

-

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Filtered by Token Holder
Null: 0x000...dEaD
Balance
2,880,473,462.621067245341459634 ATM

Value
$0.00
0x000000000000000000000000000000000000dead
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
ATMToken

Compiler Version
v0.8.19+commit.7dd6d404

Optimization Enabled:
Yes with 1 runs

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

// ╔══════════════════════════════════════════════════════════════╗
// ║  ATM Token — 自主交易矩阵 · 智能资金分配协议                ║
// ║  主合约:ERC20 + 转账钩子 + P0分配                             ║
// ║  版本:v13-split | 链:BSC | 许可证:MIT                     ║
// ╚══════════════════════════════════════════════════════════════╝

import "./ATMStorage.sol";

/// @dev 58亿固定供应,3%买卖税(仅LP交易),10池分配,bitmask标志隔离
/// @dev Admin/Keeper/gcsq functions delegated to ATMTokenExtension via fallback
contract ATMToken is ATMStorage {
    using SafeERC20 for IERC20;
    using ATMLibrary for *;

    // ═══════════ Immutable 地址 ═══════════
    address public usdt;
    address public router;
    address public factory;
    address public pair;
    address public coldWallet;
    address public p7LpRecipient;

    // ═══════════ Modifiers ═══════════

    modifier onlyCold() {
        if (msg.sender != coldWallet) revert E(1);
        _;
    }

    modifier notRenounced() {
        if (renounced) revert E(2);
        _;
    }

    modifier onlyKeeper() {
        if (!isKeeperWhitelisted[msg.sender] || isKeeperPaused[msg.sender]) revert E(3);
        _;
    }

    /// @dev Only callable via self-call (bridge from extension delegatecall)
    modifier onlySelf() {
        if (msg.sender != address(this)) revert E(8);
        _;
    }

    // ═══════════ Constructor (empty for CREATE2) ═══════════

    constructor() {}

    // ═══════════ Initialize (replaces constructor params) ═══════════

    bool private _initialized;

    function initialize(
        address _usdt,
        address _router,
        address _p1,
        address _p2,
        address _cold,
        address _owner,
        address[] memory _keepers
    ) external {
        require(!_initialized, "ALREADY_INIT");
        _initialized = true;

        usdt = _usdt;
        router = _router;
        p1Wallet = _p1;
        p2Wallet = _p2;
        coldWallet = _cold;

        address _factory = IPancakeRouter02(_router).factory();
        factory = _factory;
        pair = IPancakeFactory(_factory).createPair(address(this), _usdt);

        isHardExcluded[address(0)] = true;
        isHardExcluded[DEAD] = true;
        isHardExcluded[EXIT_HOLE] = true;
        isHardExcluded[address(this)] = true;

        isDividendExcluded[address(0)] = true;
        isDividendExcluded[DEAD] = true;
        isDividendExcluded[EXIT_HOLE] = true;
        isDividendExcluded[address(this)] = true;

        isLpPool[pair] = true;
        isRouter[_router] = true;
        isDividendExcluded[pair] = true;

        for (uint i = 0; i < _keepers.length; i++) {
            isKeeperWhitelisted[_keepers[i]] = true;
            keeperList.push(_keepers[i]);
            keeperIndex[_keepers[i]] = uint8(i);
        }
        activeKeeperCount = _keepers.length;

        _balances[_owner] = TOTAL_SUPPLY;
        emit Transfer(address(0), _owner, TOTAL_SUPPLY);

        lastReleaseTime = block.timestamp;
        lastP5ReleaseTime = block.timestamp;
        lastP5DripBlock = block.number;
        lastRebalanceTime = block.timestamp;
        lastP4DistributeTime = block.timestamp;
        lastP4QualifiedTime = block.timestamp;
        lastSettleTime = block.timestamp;

        enableAntiSync = true;
        taxRate = 3;

        _allowances[address(this)][_router] = type(uint256).max;

        tokenDistributor = new TokenDistributor();
        tokenDistributor.init(_usdt, _cold, address(this));

        // Store addresses for extension delegatecall access
        _storedUsdt = _usdt;
        _storedRouter = _router;
        _storedFactory = factory;
        _storedPair = pair;
        _storedColdWallet = _cold;
        _storedP7LpRecipient = address(0); // [DEPRECATED]

        adminWallet = _owner;
    }

    // ═══════════ ERC20 标准接口 ═══════════

    function totalSupply() external pure returns (uint256) { return TOTAL_SUPPLY; }

    function balanceOf(address account) public view returns (uint256) {
        if (account == pair && msg.sender == pair && enableAntiSync) {
            // 同block内有合法pair操作(swap/burn)时跳过检查,只拦截裸sync()
            if (_legitPairOpBlock != block.number) {
                (uint256 rATM,) = _getReserves();
                uint256 bal = _balances[pair];
                if (bal < rATM) revert E(14);
            }
        }
        return _balances[account];
    }

    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowances[owner][spender];
    }

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

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

    function transferFrom(address from, address to, uint256 amount) external returns (bool) {
        uint256 currentAllowance = _allowances[from][msg.sender];
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < amount) revert E(7);
            unchecked { _allowances[from][msg.sender] = currentAllowance - amount; }
        }
        _transfer(from, to, amount);
        return true;
    }

    // ═══════════ 核心转账逻辑 ═══════════

    function _transfer(address from, address to, uint256 amount) internal {
        if (from == address(0)) revert E(6);
        if (amount == 0) revert E(6);
        if (_balances[from] < amount) revert E(7);

        // V2: 全局暂停(keeper结算操作不受影响)
        if (paused && !isKeeperWhitelisted[from]) revert E(6);

        if (isHardExcluded[from]) {
            _rawTransfer(from, to, amount);
            return;
        }

        if ((_flags & (FLAG_RELEASING | FLAG_FOLLOWSELLING | FLAG_DORMANCY | FLAG_BLINDBOX)) != 0) {
            _rawTransfer(from, to, amount);
            return;
        }

        if (isBlacklisted[from] || isBlacklisted[to]) revert E(5);

        uint256 confiscated = _checkDormancy(from);
        // confiscated already deducted from from's balance via _rawTransfer to DEAD
        // Now cap transfer amount to remaining balance
        if (confiscated > 0) {
            uint256 remaining = _balances[from];
            if (amount > remaining) {
                amount = remaining;
            }
            if (amount == 0) return;  // 全被罚没了,静默返回不revert
        }

        if (to == DEAD && !isWhitelistBurn[from]) {
            _handleBlindBox(from, amount);
        } else if (to == EXIT_HOLE && !isWhitelistBurn[from]) {
            _handleExitEntry(from, amount);
        } else if (isLpPool[from] || isLpPool[to]) {
            {
                address _trader = isLpPool[from] ? to : from;
                if (!tradingEnabled) {
                    bool isAdd = isLpPool[to] && isRouter[msg.sender] && tx.origin == from && _isAddLiquidity(amount) > 0;
                    bool isRemove = isLpPool[from] && _isRemoveLiquidity(amount) > 0;
                    if (!isAdd && !isRemove && !isWhitelistBurn[_trader]) {
                        revert E(9);
                    }
                }
            }
            bool isAddLiq = isLpPool[to] && isRouter[msg.sender] && tx.origin == from && _isAddLiquidity(amount) > 0;
            if (!isAddLiq && isLpPool[to] && !isBlacklisted[from] && !isWhitelistBurn[from]) {
                uint256 preNetAmount = amount - (amount * taxRate / 100);
                _doFollowSell(preNetAmount);
            }
            _handleLpTrade(from, to, amount, isAddLiq);
        } else {
            _rawTransfer(from, to, amount);
            if (lastSwapTime[to] == 0 && _balances[to] > 0) {
                lastSwapTime[to] = block.timestamp;
                if (lastConfiscatedPercent[to] > 0) lastConfiscatedPercent[to] = 0;
            }
            {
                uint256 twapP = getTwapPrice();
                if (twapP > 0) {
                    uint256 usdtValue = amount * twapP / 1e18;
                    if (usdtValue >= P2P_WAKE_THRESHOLD) {
                        lastSwapTime[from] = block.timestamp;
                        lastConfiscatedPercent[from] = 0;
                        lastSwapTime[to] = block.timestamp;
                        lastConfiscatedPercent[to] = 0;
                    }
                }
            }
            _settleOnAction();
        }
    }

    function _rawTransfer(address from, address to, uint256 amount) private {
        _balances[from] -= amount;
        _balances[to] += amount;
        emit Transfer(from, to, amount);

        // K6修复:追踪ATM holder到链上数组
        if (to != address(0) && !isHardExcluded[to] && _balances[to] > 0 && !isInAtmHolderList[to]) {
            atmHolders.push(to);
            isInAtmHolderList[to] = true;
        }

        if (to != address(0) && !isHardExcluded[to] && !isLpPool[to] && !isRouter[to]) {
            if (lastSwapTime[to] == 0) {
                lastSwapTime[to] = block.timestamp;
                if (lastConfiscatedPercent[to] > 0) lastConfiscatedPercent[to] = 0;
            } else if (twapReady) {
                uint256 twapP = getTwapPrice();
                if (twapP > 0) {
                    uint256 usdtValue = amount * twapP / 1e18;
                    if (usdtValue >= P2P_WAKE_THRESHOLD) {
                        lastSwapTime[to] = block.timestamp;
                        lastConfiscatedPercent[to] = 0;
                    }
                }
            }
        }
    }

    // ═══════════ LP交易处理 ═══════════

    function _handleLpTrade(address from, address to, uint256 amount, bool isAddLiq) private {
        bool isBuy  = isLpPool[from];
        bool isSell = isLpPool[to];
        address trader_ = isBuy ? to : from;

        // 标记合法pair操作(buy/removeLiquidity时token从pair转出),让balanceOf的antiSync放行
        if (isBuy) {
            _legitPairOpBlock = block.number;
        }

        if (isSell) {
            if (isAddLiq) {
                _rawTransfer(from, to, amount);
                {
                    (, uint256 rUSDT) = _getReserves();
                    uint256 pairUsdtBal = IERC20(usdt).balanceOf(pair);
                    uint256 addedUSDT = pairUsdtBal > rUSDT ? pairUsdtBal - rUSDT : 0;
                    if (addedUSDT >= ACTIVE_TRADE_THRESHOLD) {
                        lastSwapTime[from] = block.timestamp;
                        lastConfiscatedPercent[from] = 0;
                    }
                }
                // K5修复:追踪LP holder到链上数组
                if (!isInLpHolderList[from]) {
                    lpHolders.push(from);
                    isInLpHolderList[from] = true;
                }
                _settleOnAction();
                return;
            }
        }

        if (isBuy) {
            if (_isRemoveLiquidity(amount) > 0) {
                address _feeTo = IPancakeFactory(factory).feeTo();
                address _knownFeeTo = 0xf4c21a1cB819E5F7ABe6dEFde3d118D8F3D61FA7;
                if (
                    (_feeTo != address(0) && (to == _feeTo || tx.origin == _feeTo)) ||
                    to == _knownFeeTo || tx.origin == _knownFeeTo
                ) {
                    revert E(5);
                }
                if (isWhitelistBurn[to]) {
                    _rawTransfer(from, to, amount);
                } else {
                    _rawTransfer(from, EXIT_HOLE, amount);
                    emit LPRemovalConfiscated(to, amount);
                }
                _settleOnAction();
                return;
            }
        }

        if (isWhitelistBurn[trader_]) {
            _rawTransfer(from, to, amount);
            lastSwapTime[trader_] = block.timestamp;
            lastConfiscatedPercent[trader_] = 0;
            _updateTwap();
            return;
        }

        uint256 taxAmount = amount * taxRate / 100;
        uint256 netAmount = amount - taxAmount;

        _updateTwap();

        (uint256 rATM, uint256 rUSDT) = _getReserves();
        uint256 usdtValue = ATMLibrary.getUsdtValue(amount, rATM, rUSDT);

        _rawTransfer(from, address(this), taxAmount);
        p0AccumulatedATM += taxAmount;

        _rawTransfer(from, to, netAmount);

        address trader = isBuy ? to : from;
        if (usdtValue >= ACTIVE_TRADE_THRESHOLD) {
            lastSwapTime[trader] = block.timestamp;
            lastConfiscatedPercent[trader] = 0;
        }

        if (lotteryContract != address(0) && usdtValue >= ACTIVE_TRADE_THRESHOLD) {
            if (isBuy) {
                try ILottery(lotteryContract).onBuy(trader, usdtValue) {} catch {}
            } else {
                try ILottery(lotteryContract).onSell(trader, usdtValue) {} catch {}
            }
        }

        if (isSell) {
            _dripP5toP6();
            _settleOnAction();

            // 检查pendingP0Usdt是否够阈值,够就统一分配
            _tryDistributeP0();
        }

        if (isBuy) {
            _settleOnAction();
        }
    }

    // ═══════════ 统一结算(每次用户操作搭载) ═══════════

    function _settleOnAction() private {
        // 强制结算盲盒:最多3笔
        if (blindBoxContract != address(0)) {
            IBlindBox(blindBoxContract).settleExpired(3);
        }
        // 强制结算出局
        if (block.timestamp >= lastSettleTime + SETTLE_GAP && poolP6 > 0) {
            _doSettleExits();
        }
    }

    // ═══════════ 跟卖 ═══════════

    function _doFollowSell(uint256 userNetAmount) private {
        uint256 fsAmount = userNetAmount / FOLLOW_SELL_RATIO;
        uint256 holeBal = _balances[EXIT_HOLE];
        if (fsAmount == 0 || holeBal < fsAmount) return;

        _flags |= FLAG_FOLLOWSELLING;

        _rawTransfer(EXIT_HOLE, address(this), fsAmount);

        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = usdt;

        uint256 usdtBefore = IERC20(usdt).balanceOf(address(tokenDistributor));

        IPancakeRouter02(router).swapExactTokensForTokensSupportingFeeOnTransferTokens(
            fsAmount, 0, path, address(tokenDistributor), block.timestamp
        );
        uint256 usdtReceived = IERC20(usdt).balanceOf(address(tokenDistributor)) - usdtBefore;
        if (usdtReceived > 0) {
            IERC20(usdt).transferFrom(address(tokenDistributor), address(this), usdtReceived);
            pendingP0Usdt += usdtReceived;
            emit FollowSell(address(0), fsAmount, usdtReceived);
        }

        _flags &= ~FLAG_FOLLOWSELLING;
    }

    // ═══════════ 盲盒入口 ═══════════

    function _handleBlindBox(address from, uint256 amount) private {
        if (!twapReady) revert E(6);

        _rawTransfer(from, DEAD, amount);

        if (blindBoxContract != address(0)) {
            uint256 twapP = getTwapPrice();
            if (!IBlindBox(blindBoxContract).onBlindBoxEntry(from, amount, 1e18, twapP)) revert E(8);
        }
    }

    // ═══════════ 出局入口 ═══════════

    function _handleExitEntry(address from, uint256 amount) private {
        if (isLpPool[from] || isRouter[from]) revert E(10);
        if (!twapReady) revert E(6);

        uint256 twapP = getTwapPrice();
        uint256 usdtValue = amount * twapP / 1e18;

        _rawTransfer(from, EXIT_HOLE, amount);

        if (exitQueueContract != address(0)) {
            if (!IExitQueue(exitQueueContract).onExitEntry(from, amount, usdtValue)) revert E(8);
        }

        _settleOnAction();
    }

    // ═══════════ P0 释放 ═══════════

    function _checkP0Release() private {
        if (p0AccumulatedATM == 0) return;
        if ((_flags & FLAG_RELEASING) != 0) return;
        if (gasleft() < 500000) return;

        (uint256 rATM, uint256 rUSDT) = _getReserves();
        uint256 p0ValueU = ATMLibrary.getUsdtValue(p0AccumulatedATM, rATM, rUSDT);

        if (p0ValueU >= P0_RELEASE_THRESHOLD) {
            _releaseAll(rATM, rUSDT);
        }
    }

    function _releaseAll(uint256 /* rATM */, uint256 /* rUSDT */) private {
        _flags |= FLAG_RELEASING;

        // 卖合约持有的全部ATM(包括未被p0AccumulatedATM追踪的幽灵余额)
        uint256 toSwap = _balances[address(this)];
        if (toSwap == 0) { _flags &= ~FLAG_RELEASING; return; }

        uint256 usdtBefore = IERC20(usdt).balanceOf(address(this));

        IATMSwapHelper(swapHelper).swapAndForward(address(this), usdt, toSwap, 0);
        p0AccumulatedATM = 0; // 全部卖完,清零

        uint256 usdtReceived = IERC20(usdt).balanceOf(address(this)) - usdtBefore;
        if (usdtReceived == 0) {
            _flags &= ~FLAG_RELEASING;
            return;
        }

        pendingP0Usdt += usdtReceived;
        _tryDistributeP0();
        lastReleaseTime = block.timestamp;

        _flags &= ~FLAG_RELEASING;
    }

    // ═══════════ P0 统一发放 ═══════════

    function _tryDistributeP0() private {
        if (pendingP0Usdt == 0) return;
        // 够阈值直接分
        if (pendingP0Usdt >= P0_RELEASE_THRESHOLD) {
            _executeP0Distribution(pendingP0Usdt);
            pendingP0Usdt = 0;
            lastP0DistributeTime = block.timestamp;
            return;
        }
        // 不够阈值但超时了也分(P0_DISTRIBUTE_INTERVAL)
        if (block.timestamp >= lastP0DistributeTime + P0_DISTRIBUTE_INTERVAL) {
            _executeP0Distribution(pendingP0Usdt);
            pendingP0Usdt = 0;
            lastP0DistributeTime = block.timestamp;
        }
    }

    function _executeP0Distribution(uint256 amount) private {
        _distributeP0Usdt(amount);
        _injectP3();
        _dripP5toP6();
    }

    function _distributeP0Usdt(uint256 usdtAmount) private {
        ATMLibrary.P0Allocation memory a = ATMLibrary.calcP0Distribution(usdtAmount);

        if (a.toP1 > 0 && p1Wallet != address(0)) {
            IERC20(usdt).safeTransfer(p1Wallet, a.toP1);
        }
        if (a.toP2 > 0 && p2Wallet != address(0)) {
            IERC20(usdt).safeTransfer(p2Wallet, a.toP2);
        }

        poolP3 += a.toP3;
        poolP4 += a.toP4;
        poolP5 += a.toP5;

        emit ReleaseAll(usdtAmount);
    }

    function _injectP3() private {
        if (lotteryContract == address(0) || poolP3 == 0) return;
        uint256 injection = poolP3;
        poolP3 = 0;
        (bool ok,) = lotteryContract.call(abi.encodeWithSelector(ILottery.injectP3.selector, injection));
        if (ok) {
            IERC20(usdt).safeTransfer(lotteryContract, injection);
        } else {
            poolP3 = injection;
        }
    }

    function _redistributeToP0(uint256 amount) private {
        _distributeP0Usdt(amount);
    }

    // ═══════════ P5 → P6 涓流滴灌 ═══════════

    function _dripP5toP6() private {
        if (poolP5 == 0) return;
        if (block.number < lastP5DripBlock + P5_DRIP_INTERVAL) return;

        lastP5DripBlock = block.number;

        if (poolP5 >= P5_LOW_THRESHOLD) {
            uint256 toRelease = poolP5 * P5_RELEASE_RATE / 10000;
            uint256 opsAmount = toRelease * MAINTENANCE_RATE / 10000;
            uint256 toP6 = toRelease - opsAmount;
            poolP5 -= toRelease;
            poolP6 += toP6;
            maintenancePool += opsAmount;
            p5BelowThresholdSince = 0;
            emit P5Released(toP6);
        } else {
            if (p5BelowThresholdSince == 0) {
                p5BelowThresholdSince = block.timestamp;
            }
            if (block.timestamp >= p5BelowThresholdSince + P5_DRAIN_DELAY) {
                uint256 all = poolP5;
                uint256 opsAll = all * MAINTENANCE_RATE / 10000;
                uint256 toP6All = all - opsAll;
                poolP5 = 0;
                poolP6 += toP6All;
                maintenancePool += opsAll;
                p5BelowThresholdSince = 0;
                emit P5Released(toP6All);
            }
        }
    }

    // ═══════════ 出局结算 ═══════════

    function _doSettleExits() private {
        if (exitQueueContract == address(0)) return;
        if (poolP6 == 0) return;

        uint256 available = poolP6;
        if (available == 0) return;

        IERC20(usdt).safeTransfer(exitQueueContract, available);
        poolP6 = 0; // 钱已转入ExitQueue,主合约不再记账

        (bool ok, bytes memory ret) = exitQueueContract.call(
            abi.encodeWithSelector(IExitQueue.settleExits.selector, available)
        );
        if (!ok) {
            revert("SETTLE_FAILED");
        }

        lastSettleTime = block.timestamp;
    }

    // ═══════════ 休眠没收 ═══════════

    function _checkDormancy(address user) private returns (uint256 confiscated) {
        if (isHardExcluded[user] || isWhitelistBurn[user] || isLpPool[user] || isRouter[user]) return 0;
        if (launchTimestamp == 0) return 0;

        uint256 userLastSwap = lastSwapTime[user];
        if (userLastSwap == 0) {
            if (_balances[user] == 0) return 0;
            userLastSwap = launchTimestamp;
        }

        uint256 effectiveLastSwap = userLastSwap > launchTimestamp ? userLastSwap : launchTimestamp;

        uint256 delta = ATMLibrary.calcDormancyPercent(
            effectiveLastSwap,
            lastConfiscatedPercent[user],
            DORMANCY_THRESHOLD,
            DORMANCY_INCREMENT
        );

        if (delta == 0) return 0;

        uint256 bal = _balances[user];
        if (bal == 0) return 0;
        uint256 confiscate;
        if (lastConfiscatedPercent[user] + delta >= 100) {
            confiscate = bal;
        } else {
            confiscate = bal * delta / 100;
            if (confiscate == 0) return 0;
        }

        lastConfiscatedPercent[user] += delta;

        _flags |= FLAG_DORMANCY;
        _rawTransfer(user, DEAD, confiscate);
        _flags &= ~FLAG_DORMANCY;

        emit DormancyConfiscated(user, confiscate, lastConfiscatedPercent[user]);
        return confiscate;
    }

    // ═══════════ 黑洞再平衡 ═══════════

    function _rebalanceBlackholes() private {
        uint256 deadBal = _balances[DEAD];
        uint256 exitBal = _balances[EXIT_HOLE];
        uint256 total = deadBal + exitBal;
        if (total == 0) return;

        uint256 half = total / 2;
        if (deadBal > half) {
            _rawTransfer(DEAD, EXIT_HOLE, deadBal - half);
        } else if (exitBal > half) {
            _rawTransfer(EXIT_HOLE, DEAD, exitBal - half);
        }
        lastRebalanceTime = ATMLibrary.calcAlignedTime(block.timestamp, 0); // 对齐北京时间 00:00
        emit BlackholeRebalanced(_balances[DEAD], _balances[EXIT_HOLE]);
    }

    // ═══════════ TWAP ═══════════

    function _updateTwap() private {
        (uint256 rATM, uint256 rUSDT) = _getReserves();
        if (rATM == 0) return;

        uint256 spotPrice = rUSDT * 1e18 / rATM;

        if (twapLastBlock == 0) {
            for (uint256 i = 0; i < TWAP_BLOCKS; i++) {
                twapPriceBuffer[i] = spotPrice;
            }
            twapAccumulatedBlocks = TWAP_BLOCKS;
            twapBufferIndex = 0;
            twapLastBlock = block.number;
            twapLastPrice = spotPrice;
            if (!twapReady) {
                twapReady = true;
                emit TwapReady();
            }
            return;
        }

        if (block.number <= twapLastBlock) return;

        uint256 clampedPrice = spotPrice;
        if (twapLastPrice > 0) {
            uint256 upper = twapLastPrice * (100 + TWAP_DEVIATION_MAX) / 100;
            uint256 lower = twapLastPrice * (100 - TWAP_DEVIATION_MAX) / 100;
            if (clampedPrice > upper) clampedPrice = upper;
            else if (clampedPrice < lower) clampedPrice = lower;
        }

        // 环形缓冲区:覆盖最旧槽位
        uint8 idx = twapBufferIndex;
        twapPriceBuffer[idx] = clampedPrice;
        twapBufferIndex = uint8((uint256(idx) + 1) % TWAP_BLOCKS);

        twapLastBlock = block.number;
        twapLastPrice = clampedPrice;

        if (!twapReady && twapAccumulatedBlocks >= TWAP_BLOCKS) {
            twapReady = true;
            emit TwapReady();
        }
    }

    // ═══════════ 价格工具 ═══════════

    function _getReserves() internal view returns (uint256 reserveATM, uint256 reserveUSDT) {
        (uint112 r0, uint112 r1,) = IPancakePair(pair).getReserves();
        address token0 = IPancakePair(pair).token0();
        if (token0 == address(this)) {
            reserveATM = uint256(r0);
            reserveUSDT = uint256(r1);
        } else {
            reserveATM = uint256(r1);
            reserveUSDT = uint256(r0);
        }
    }

    function _isAddLiquidity(uint256 amount) internal view returns (uint256 liquidity) {
        (uint256 rATM, uint256 rUSDT) = _getReserves();
        if (rATM == 0 || rUSDT == 0) return 0;

        uint256 pairUsdtBal = IERC20(usdt).balanceOf(pair);
        if (pairUsdtBal <= rUSDT) return 0;

        uint256 actualExcess = pairUsdtBal - rUSDT;
        uint256 expectedUSDT = (amount * rUSDT) / rATM;
        if (expectedUSDT == 0) return 0;

        uint256 lower = (expectedUSDT * 95) / 100;
        uint256 upper = (expectedUSDT * 105) / 100;
        if (actualExcess < lower || actualExcess > upper) return 0;

        (liquidity, ) = calLiquidity(pairUsdtBal, amount, rUSDT, rATM);
    }

    function _isRemoveLiquidity(uint256 amount) internal view returns (uint256 liquidity) {
        (, uint256 rUSDT) = _getReserves();
        uint256 pairUsdtBal = IERC20(usdt).balanceOf(pair);
        if (pairUsdtBal <= rUSDT) {
            liquidity = (amount * IPancakePair(pair).totalSupply()) / (_balances[pair] - amount);
        }
    }

    function calLiquidity(
        uint256 balanceOther,
        uint256 amount,
        uint256 rOther,
        uint256 rThis
    ) internal view returns (uint256 liquidity, uint256 feeToLiquidity) {
        uint256 pairTotalSupply = IPancakePair(pair).totalSupply();
        if (rThis == 0) return (0, 0);
        uint256 amountOther = amount * rOther / rThis;
        if (pairTotalSupply == 0) {
            liquidity = ATMLibrary.sqrt(amountOther * amount) - 1000;
        } else {
            liquidity = _min(
                amountOther * pairTotalSupply / rOther,
                amount * pairTotalSupply / rThis
            );
        }
    }

    function _min(uint256 a, uint256 b) private pure returns (uint256) {
        return a < b ? a : b;
    }

    // ═══════════ 用户功能入口 ═══════════

    // enterExitQueue / enterBlindBox 已移除(用户通过 transfer 到 EXIT_HOLE/DEAD 触发)

    // ═══════════ 子合约内部转账 ═══════════

    function internalTransferFrom(address from, address to, uint256 amount) external {
        if (msg.sender != blindBoxContract && msg.sender != exitQueueContract && msg.sender != lotteryContract) revert E(8);
        if (from != EXIT_HOLE && from != DEAD) revert E(6);
        _rawTransfer(from, to, amount);
    }

    // ═══════════ 出局名额管理 ═══════════

    function updateExitQuota(address user, uint256 amount) external {
        if (msg.sender != exitQueueContract) revert E(8);
        if (amount == 0) return;
        exitQuota[user] += amount;
        totalExitQuota += amount;
        if (!inExitQuotaList[user]) {
            exitQuotaHolders.push(user);
            inExitQuotaList[user] = true;
        }
    }

    function getExitQuotaHolders() external view returns (address[] memory) {
        return exitQuotaHolders;
    }

    // ═══════════ 出局失败重试(K9看门狗调用)═══════════

    /// @notice K9逐个重试失败转账
    function retryPendingClaim(address user) external onlyKeeper {
        IExitQueue(exitQueueContract).retryPendingClaim(user);
    }

    // ═══════════ P4 出局永久分红回调 ═══════════

    // onP4Decay 已移除(出局队列始终有人,Lottery奖池不会滞留)

    // ═══════════ Bridge Functions (called by extension via this.func()) ═══════════

    function doSettleExitsExt() external onlySelf {
        _doSettleExits();
    }

    function dripP5toP6Ext() external onlySelf {
        _dripP5toP6();
    }

    function tryDistributeP0Ext() external onlySelf {
        _tryDistributeP0();
    }

    function checkDormancyExt(address user) external onlySelf returns (uint256) {
        return _checkDormancy(user);
    }

    function rebalanceBlackholesExt() external onlySelf {
        _rebalanceBlackholes();
    }

    function releaseAllExt() external onlySelf {
        (uint256 rATM, uint256 rUSDT) = _getReserves();
        uint256 p0ValueU = ATMLibrary.getUsdtValue(p0AccumulatedATM, rATM, rUSDT);
        if (p0ValueU < P0_RELEASE_THRESHOLD) revert E(11);
        _releaseAll(rATM, rUSDT);
    }

    function checkP0ReleaseExt() external onlySelf {
        _checkP0Release();
    }

    function redistributeToP0Ext(uint256 amount) external onlySelf {
        _redistributeToP0(amount);
    }

    function updateTwapExt() external onlySelf {
        _updateTwap();
    }

    // ═══════════ View 函数 ═══════════

    function getTwapPrice() public view returns (uint256) {
        if (!twapReady) {
            (uint256 rATM, uint256 rUSDT) = _getReserves();
            if (rATM == 0) return 0;
            return rUSDT * 1e18 / rATM;
        }
        // V2: 取6个缓冲价格中的最低价
        uint256 minPrice = twapPriceBuffer[0];
        for (uint256 i = 1; i < TWAP_BLOCKS; i++) {
            if (twapPriceBuffer[i] < minPrice) {
                minPrice = twapPriceBuffer[i];
            }
        }
        return minPrice;
    }

    function getPrice() external view returns (uint256 reserveATM, uint256 reserveUSDT) {
        return _getReserves();
    }

    /// @notice V2: 一次性读取资金池状态
    function getPoolStatus() external view returns (
        uint256 _poolP3, uint256 _poolP4,
        uint256 _poolP5, uint256 _poolP6, uint256 _maintenancePool,
        uint256 _pendingP0Usdt, uint256 _p0AccumulatedATM,
        uint256 _twapPrice,
        uint256 _reserveATM, uint256 _reserveUSDT
    ) {
        _poolP3 = poolP3;
        _poolP4 = poolP4;
        _poolP5 = poolP5;
        _poolP6 = poolP6;
        _maintenancePool = maintenancePool;
        _pendingP0Usdt = pendingP0Usdt;
        _p0AccumulatedATM = p0AccumulatedATM;
        _twapPrice = getTwapPrice();
        (_reserveATM, _reserveUSDT) = _getReserves();
    }

    /// @notice V2: 一次性读取时间和开关状态
    function getTimingStatus() external view returns (
        uint256 _lastReleaseTime, uint256 _lastP4DistributeTime,
        uint256 _lastSettleTime, uint256 _lastRebalanceTime,
        uint256 _lastP5DripBlock,
        bool _paused, bool _tradingEnabled
    ) {
        _lastReleaseTime = lastReleaseTime;
        _lastP4DistributeTime = lastP4DistributeTime;
        _lastSettleTime = lastSettleTime;
        _lastRebalanceTime = lastRebalanceTime;
        _lastP5DripBlock = lastP5DripBlock;
        _paused = paused;
        _tradingEnabled = tradingEnabled;
    }

    function isActiveKeeper(address addr) external view returns (bool) {
        return isKeeperWhitelisted[addr] && !isKeeperPaused[addr];
    }

    // ═══════════ Extension Setup ═══════════

    function setExtension(address _ext) external {
        if (msg.sender != coldWallet) revert E(1);
        require(_ext != address(0), "ZERO_ADDR");
        extension = _ext;
    }

    // ═══════════ Fallback → Extension ═══════════

    receive() external payable {}

    fallback() external payable {
        address ext = extension;
        require(ext != address(0));
        assembly {
            calldatacopy(0, 0, calldatasize())
            let result := delegatecall(gas(), ext, 0, calldatasize(), 0, 0)
            returndatacopy(0, 0, returndatasize())
            switch result
            case 0 { revert(0, returndatasize()) }
            default { return(0, returndatasize()) }
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.4) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "../IERC20.sol";
import "../extensions/IERC20Permit.sol";
import "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
     * Revert on invalid signature.
     */
    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
        require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return
            success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

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

// ╔══════════════════════════════════════════════════════════════╗
// ║  ATM Token — 自主交易矩阵 · 智能资金分配协议                ║
// ║  ATMLibrary · 纯计算库                                       ║
// ║  版本:v13 | 链:BSC | 许可证:MIT                           ║
// ╚══════════════════════════════════════════════════════════════╝

/// @dev 纯计算辅助库,无状态变量,所有函数为 internal pure/view
library ATMLibrary {

    // ═══════════ P0 分配比例(万分比 /10000) ═══════════
    uint256 internal constant R_P1 = 300;   // 3%    — 社区营销
    uint256 internal constant R_P2 = 600;   // 6%    — 风险基金
    uint256 internal constant R_P3 = 100;   // 1%    — 抽奖注入
    uint256 internal constant R_P4 = 500;   // 5%    — 出局永久分红
    uint256 internal constant R_P5 = 8500;  // 85%   — 出局资金(余数兜底)
    // 合计: 200+500+100+500+8500+200 = 10000

    // ═══════════ 数据结构 ═══════════

    /// @dev P0分配结果:各池子应分多少USDT
    struct P0Allocation {
        uint256 toP1;
        uint256 toP2;
        uint256 toP3;
        uint256 toP4;
        uint256 toP5;
    }

    /// @dev 抽奖奖金分配比例(百分比)
    struct PrizeAllocation {
        uint256 bigPct;       // 大奖
        uint256 smallPct;     // 小奖
        uint256 sunshinePct;  // 阳光奖
        uint256 rolloverPct;  // 滚存下一轮
    }

    // ═══════════ P0 分配计算 ═══════════

    /// @notice 按万分比精确分配USDT到各池子
    /// @dev P5兜底吸收舍入误差,确保总和 = usdtAmount
    /// @param usdtAmount 待分配的USDT总额
    /// @return a 各池子分配结果
    function calcP0Distribution(uint256 usdtAmount) internal pure returns (P0Allocation memory a) {
        a.toP1 = usdtAmount * R_P1 / 10000;
        a.toP2 = usdtAmount * R_P2 / 10000;
        a.toP3 = usdtAmount * R_P3 / 10000;
        a.toP4 = usdtAmount * R_P4 / 10000;
        a.toP5 = usdtAmount - a.toP1 - a.toP2 - a.toP3 - a.toP4; // 兜底余数
    }

    // ═══════════ 休眠没收百分比计算 ═══════════

    /// @notice 计算用户本次应被没收的百分比增量
    /// @dev 递增惩罚机制:第1天扣1%,第2天扣2%...累计 = N*(N+1)/2,上限100%
    /// @param lastSwapTime 用户上次有效交易时间
    /// @param lastPercent 已没收的累计百分比
    /// @param dormancyThreshold 休眠触发阈值(如48h)
    /// @param dormancyIncrement 每多久额外没收1%(如24h)
    /// @return deltaPercent 本次新增没收百分比(0=未触发)
    function calcDormancyPercent(
        uint256 lastSwapTime,
        uint256 lastPercent,
        uint256 dormancyThreshold,
        uint256 dormancyIncrement
    ) internal view returns (uint256 deltaPercent) {
        if (lastSwapTime == 0) return 0;
        if (block.timestamp <= lastSwapTime + dormancyThreshold) return 0; // 还没超过休眠阈值

        uint256 overdue = block.timestamp - lastSwapTime - dormancyThreshold;
        uint256 days_ = overdue / dormancyIncrement;
        if (days_ == 0) days_ = 1; // 刚过阈值就算第1天

        // 累计百分比 = 1+2+3+...+N = N*(N+1)/2
        uint256 totalPercent = days_ * (days_ + 1) / 2;
        if (totalPercent > 100) totalPercent = 100; // 上限100%
        if (totalPercent <= lastPercent) return 0;   // 已经扣过了
        deltaPercent = totalPercent - lastPercent;
    }

    // ═══════════ ATM→USDT 估值 ═══════════

    /// @notice 基于LP储备的即时估值(非交易用,仅内部记账)
    /// @dev 公式:atmAmount * reserveUSDT / reserveATM
    /// @param atmAmount ATM数量
    /// @param reserveATM LP中ATM储备
    /// @param reserveUSDT LP中USDT储备
    /// @return USDT估值
    function getUsdtValue(
        uint256 atmAmount,
        uint256 reserveATM,
        uint256 reserveUSDT
    ) internal pure returns (uint256) {
        if (reserveATM == 0) return 0;
        return atmAmount * reserveUSDT / reserveATM;
    }

    // ═══════════ TWAP 价格计算 ═══════════

    /// @notice 计算时间加权平均价格
    /// @dev TWAP就绪前回退到即时价格;就绪后返回累积价格/累积块数
    /// @param cumulativePrice 累积价格总和
    /// @param accumulatedBlocks 累积的区块数
    /// @param ready TWAP是否已就绪(累积够TWAP_BLOCKS)
    /// @param reserveATM LP中ATM储备(回退用)
    /// @param reserveUSDT LP中USDT储备(回退用)
    /// @return 每ATM对应的USDT数量(1e18精度)
    function calcTwapPrice(
        uint256 cumulativePrice,
        uint256 accumulatedBlocks,
        bool ready,
        uint256 reserveATM,
        uint256 reserveUSDT
    ) internal pure returns (uint256) {
        if (ready && accumulatedBlocks > 0) {
            return cumulativePrice / accumulatedBlocks;
        }
        // 回退到即时价格
        if (reserveATM == 0) return 0;
        return reserveUSDT * 1e18 / reserveATM;
    }

    // ═══════════ 抽奖奖金分配档位 ═══════════

    /// @notice 根据是否全额发放,返回各奖项分配比例
    /// @dev 正常档: 大奖18% 小奖18% 阳光12% 滚存52%
    ///      全额档: 大奖38% 小奖37% 阳光25% 滚存0%(连续3次满时开奖后触发)
    /// @param fullPayout true=全额发放模式
    /// @return a 各奖项百分比
    function calcPrizeAllocation(bool fullPayout) internal pure returns (PrizeAllocation memory a) {
        if (fullPayout) {
            a.bigPct = 38;
            a.smallPct = 37;
            a.sunshinePct = 25;
            a.rolloverPct = 0;
        } else {
            a.bigPct = 18;
            a.smallPct = 18;
            a.sunshinePct = 12;
            a.rolloverPct = 52;
        }
    }

    // ═══════════ Optimal One-Sided LP (Zap) ═══════════

    /// @notice 计算单边加LP时应swap多少USDT买ATM,使余数最小
    /// @dev 基于AMM恒定乘积公式的最优解,适用于PancakeSwap V2 (fee=0.25%)
    ///      公式: s = (sqrt(r*(r*399000625 + A*399000000)) - r*19975) / 19950
    /// @param totalUSDT 总共可用的USDT数量
    /// @param reserveUSDT Pair中USDT储备量
    /// @return swapAmount 应swap的USDT数量
    function calcOptimalSwapAmount(
        uint256 totalUSDT,
        uint256 reserveUSDT
    ) internal pure returns (uint256) {
        uint256 a = reserveUSDT * 399000625;       // r * (d+f)^2, 其中 d=9975, f=25 (PancakeSwap 0.25% fee)
        uint256 b = totalUSDT * 399000000;          // A * 4*d*f = A * 4*9975*25*400
        uint256 c = sqrt(reserveUSDT * (a + b));    // sqrt(r * (r*(d+f)^2 + A*4*d*f))
        return (c - reserveUSDT * 19975) / 19950;   // (sqrt结果 - r*(d+f)) / (2*f), f=9975
    }

    // ═══════════ 时间对齐工具 ═══════════

    /// @notice 计算最近一次对齐时间(北京时间的某个时刻)
    /// @param ts 当前时间戳
    /// @param beijingSecondsFromMidnight 相对北京时间 00:00 的秒数偏移
    ///        0 = 北京 00:00
    ///        28800 = 北京 08:00
    ///        72000 = 北京 20:00
    function calcAlignedTime(uint256 ts, uint256 beijingSecondsFromMidnight) internal pure returns (uint256) {
        uint256 dayStartUTC8 = ts - ((ts + 28800) % 86400); // 北京时间当天00:00的UTC时闳戳
        uint256 targetToday = dayStartUTC8 + beijingSecondsFromMidnight;
        if (targetToday > ts) {
            return targetToday - 86400;
        }
        return targetToday;
    }

    /// @notice Babylonian平方根(整数近似)
    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            z = y;
            uint256 x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }
}

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

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./interfaces/IPancakeRouter02.sol";
import "./interfaces/IPancakeFactory.sol";
import "./interfaces/IPancakePair.sol";
import "./ATMLibrary.sol";
import "./interfaces/IATMInterfaces.sol";

// ═══════════ 代币中转分发器 ═══════════
contract TokenDistributor {
    address public owner;
    address public coldWallet;
    bool private _initialized;

    constructor() {}

    function init(address _usdt, address _cold, address _owner) external {
        require(!_initialized, "ALREADY_INIT");
        _initialized = true;
        owner = _owner;
        coldWallet = _cold;
        IERC20(_usdt).approve(_owner, type(uint256).max);
    }

    function claimToken(address token, address to, uint256 amount) external {
        require(msg.sender == coldWallet || msg.sender == owner, "NOT_AUTH");
        if (token == address(0)) {
            (bool s,) = to.call{value: amount}("");
            require(s, "BNB_FAIL");
        } else {
            IERC20(token).transfer(to, amount);
        }
    }

    receive() external payable {}
}

interface IATMSwapHelper {
    function swapAndForward(address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut) external returns (uint256);
    function buyAndAddLiquidity(address usdt, uint256 usdtForBuy, uint256 usdtForLP, address lpRecipient) external returns (uint256);
    function recover(address token, uint256 amount) external;
}

/// @dev Shared storage layout for ATMToken and ATMTokenExtension
/// @dev WARNING: Do NOT reorder, add, or remove variables — storage layout must match exactly
abstract contract ATMStorage {
    using SafeERC20 for IERC20;

    // ═══════════ Error ═══════════
    error E(uint8);

    // ═══════════ ERC20 常量 ═══════════
    string  public constant name     = "ATM Token";
    string  public constant symbol   = "ATM";
    uint8   public constant decimals = 18;
    uint256 public constant TOTAL_SUPPLY = 5_800_000_000e18;

    // ═══════════ 系统地址常量 ═══════════
    address public constant DEAD      = 0x000000000000000000000000000000000000dEaD;
    address public constant EXIT_HOLE = address(1);

    // ═══════════ 时间/阈值常量 ═══════════
    uint256 public constant DORMANCY_THRESHOLD     = 172800;   // 48小时
    uint256 public constant DORMANCY_INCREMENT     = 86400;    // 24小时
    uint256 public constant P5_DRIP_INTERVAL       = 588;      // 588区块(约29.4分钟)
    uint256 public constant P5_LOW_THRESHOLD       = 10e18;    // 10U
    uint256 public constant P5_RELEASE_RATE        = 200;
    uint256 public constant P5_DRAIN_DELAY         = 86400;    // 24小时
    uint256 public constant P4_RECLAIM_THRESHOLD   = 86400;    // 24小时
    uint256 public constant KEEPER_TIMELOCK        = 86400;
    uint256 public constant REBALANCE_INTERVAL     = 86400;    // 24小时
    uint256 public constant SETTLE_GAP             = 480;      // 480区块(约24分钟)
    uint256 public constant TWAP_BLOCKS            = 6;        // 6区块滑动窗口(取最低价)
    uint256 public constant TWAP_DEVIATION_MAX     = 30;
    uint256 public constant MAINTENANCE_RATE        = 800;  // 8% (800/10000) — 维护费率
    uint256 public constant KEEPER_GAS_TARGET       = 1.3 ether;  // 1.3 BNB — 固定补充目标

    // ═══════════ P0 统一发放常量 ═══════════
    uint256 public constant P0_DISTRIBUTE_INTERVAL = 86400;    // 24小时
    uint256 public constant P0_RELEASE_THRESHOLD   = 200e18;   // 200U

    // ═══════════ 业务阈值常量 ═══════════
    uint256 public constant ACTIVE_TRADE_THRESHOLD = 10e18;    // 10U
    uint256 public constant P4_MIN_HOLDING         = 100e18;   // 100U
    uint256 public constant P2P_WAKE_THRESHOLD     = 1000e18;  // 1000U
    uint256 public constant FOLLOW_SELL_RATIO      = 5;

    // ═══════════ 税率常量 ═══════════
    uint256 internal constant MAX_TAX_RATE = 100;

    // ═══════════ Flags (bitmask) ═══════════
    uint256 internal constant FLAG_RELEASING         = 1 << 0;
    uint256 internal constant FLAG_FOLLOWSELLING     = 1 << 1;
    uint256 internal constant FLAG_DORMANCY          = 1 << 2;
    uint256 internal constant FLAG_LOCKED            = 1 << 3;
    uint256 internal constant FLAG_BLINDBOX          = 1 << 4;
    uint256 internal constant FLAG_VIA_PAYABLE_ENTRY = 1 << 5;

    // ═══════════ ERC20 状态 ═══════════
    mapping(address => uint256) internal _balances;
    mapping(address => mapping(address => uint256)) internal _allowances;

    // ═══════════ 可变钱包地址 ═══════════
    address public p1Wallet;
    address public p2Wallet;

    // ═══════════ 子合约地址 ═══════════
    address public blindBoxContract;
    address public exitQueueContract;
    address public lotteryContract;
    address public swapHelper;
    TokenDistributor public tokenDistributor;

    // ═══════════ Flags 状态 ═══════════
    uint256 internal _flags;

    // ═══════════ 地址名单 ═══════════
    mapping(address => bool) public isHardExcluded;
    mapping(address => bool) public isBlacklisted;
    mapping(address => bool) public isWhitelistBurn;
    mapping(address => bool) public isLpPool;
    mapping(address => bool) public isRouter;
    mapping(address => bool) public isDividendExcluded;

    // ═══════════ Keeper 白名单 ═══════════
    mapping(address => bool) public isKeeperWhitelisted;
    mapping(address => bool) public isKeeperPaused;
    uint256 public activeKeeperCount;
    address[] public keeperList;

    // ═══════════ [DEPRECATED] Keeper Gas/Profit 账本(保留slot兼容) ═══════════
    mapping(address => uint256) internal keeperGasBalance;       // deprecated
    mapping(address => uint256) internal keeperProfitBalance;    // deprecated
    uint256 internal currentGasKeeperIndex;                      // deprecated
    uint256 internal currentProfitKeeperIndex;                   // deprecated
    mapping(uint8 => uint256) internal keeperGasTarget;          // deprecated
    mapping(uint8 => uint256) internal keeperGasReserve;         // deprecated
    mapping(address => uint8) public keeperIndex;

    // ═══════════ Pool 余额(USDT 内部记账) ═══════════
    uint256 public poolP3;
    uint256 public poolP4;
    uint256 public poolP5;
    uint256 public poolP6;
    uint256 public poolP7;               // [DEPRECATED] LP组建(已废弃,保留slot兼容)
    uint256 public lastLpReflowTime;     // [DEPRECATED] 保留slot兼容

    // ═══════════ P0 状态 ═══════════
    uint256 public p0AccumulatedATM;
    uint256 public lastReleaseTime;
    uint256 private __deprecated_p0DecayLevel;

    // ═══════════ Keeper Gas 累积 ═══════════
    uint256 internal keeperGasAccumulatedATM;  // [DEPRECATED] 不再累积,保留slot兼容

    // ═══════════ P0 Pending 发放 ═══════════
    uint256 public pendingP0Usdt;
    uint256 public lastP0DistributeTime;

    // ═══════════ [DEPRECATED] P6 Gas 追踪 ═══════════
    uint256 internal p6PendingGasIncome;  // deprecated — 不再从P6扣Gas

    // ═══════════ P5 状态 ═══════════
    uint256 public lastP5ReleaseTime;
    uint256 public lastP5DripBlock;
    uint256 public p5BelowThresholdSince;

    // ═══════════ 休眠 ═══════════
    mapping(address => uint256) public lastSwapTime;
    mapping(address => uint256) public lastConfiscatedPercent;
    uint256 public launchTimestamp;

    // ═══════════ P4 出局分红 ═══════════
    mapping(address => uint256) public exitQuota;
    uint256 public totalExitQuota;
    uint256 public lastP4DistributeTime;
    uint256 public lastP4QualifiedTime;

    // K4修复:链上记录exitQuota持有者,distributeP4不再需要链下扫描
    address[] public exitQuotaHolders;
    mapping(address => bool) public inExitQuotaList;

    // ═══════════ 链上记录LP holder ═══════════
    address[] public lpHolders;
    mapping(address => bool) public isInLpHolderList;

    // ═══════════ K6修复:链上记录ATM holder,休眠扫描不再需要链下扫描 ═══════════
    address[] public atmHolders;
    mapping(address => bool) public isInAtmHolderList;

    // ═══════════ 休眠扫描游标 ═══════════
    uint256 public dormancyCursor;



    // ═══════════ 黑洞再平衡 ═══════════
    uint256 public lastRebalanceTime;

    // ═══════════ TWAP ═══════════
    uint256 public twapCumulativePrice;          // V2: 已废弃,保留slot兼容
    uint256 public twapLastBlock;
    uint256 public twapLastPrice;
    bool    public twapReady;
    uint256 internal twapAccumulatedBlocks;       // V2: 缓冲区中有效条目数(≤TWAP_BLOCKS)
    uint256[6] internal twapPriceBuffer;          // V2: 环形缓冲区(6个价格槽位)
    uint8 public twapBufferIndex;                 // V2: 下一个写入位置

    // ═══════════ 结算 ═══════════
    uint256 public lastSettleTime;

    // ═══════════ 权限/开关 ═══════════
    bool public renounced;
    bool public paused;              // V2: 全局暂停开关
    bool public tradingEnabled;
    bool public enableAntiSync;
    uint256 public taxRate;
    // @deprecated slot preserved for storage layout compatibility
    uint256 internal __deprecated_killBlockDuration;

    // ═══════════ Extension (set post-deployment) ═══════════
    address public extension;

    // ═══════════ Stored addresses (for extension delegatecall access) ═══════════
    address internal _storedUsdt;
    address internal _storedRouter;
    address internal _storedFactory;
    address internal _storedPair;
    address internal _storedColdWallet;
    address internal _storedP7LpRecipient;

    // ═══════════ 维护费池 ═══════════
    uint256 public maintenancePool;

    // ═══════════ AntiSync:合法pair操作标记 ═══════════
    uint256 internal _legitPairOpBlock;

    // ═══════════ Admin Wallet ═══════════
    address public adminWallet;

    // ═══════════ Events ═══════════
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event ReleaseAll(uint256 usdtAmount);
    event P5Released(uint256 amount);
    event DormancyConfiscated(address indexed user, uint256 amount, uint256 totalPercent);
    event LPRemovalConfiscated(address indexed user, uint256 atmAmount);
    event FollowSell(address indexed seller, uint256 atmSold, uint256 usdtReceived);
    event KeeperPaused(address indexed keeper);
    event KeeperUnpaused(address indexed keeper);
    event KeeperReplaced(address indexed oldAddr, address indexed newAddr);
    event BlackholeRebalanced(uint256 deadBal, uint256 exitBal);
    event ReclaimTriggered(uint8 pool, uint256 amount);
    event Renounced();
    event PoolsWithdrawn(uint256 usdtAmount, uint256 atmCleared, uint256 lotteryRecovered, uint256 exitQueueRecovered);
    event TwapReady();
    event KeeperRefueled(address indexed keeper, uint256 usdtSpent, uint256 bnbReceived);

    // ═══════════ Shared Modifiers ═══════════
    modifier globalLock() {
        if ((_flags & FLAG_LOCKED) != 0) revert E(4);
        _flags |= FLAG_LOCKED;
        _;
        _flags &= ~FLAG_LOCKED;
    }

}

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

/// @notice ATM主合约对外接口(子合约调用用)
interface IATMToken {
    /// @notice 从黑洞地址转出代币(盲盒赔付/出局结算用)
    function internalTransferFrom(address from, address to, uint256 amount) external;
    /// @notice 获取USDT地址
    function usdt() external view returns (address);
    /// @notice 获取LP交易对地址
    function pair() external view returns (address);
    /// @notice 获取LP储备量(用于价格计算)
    function getPrice() external view returns (uint256 reserveATM, uint256 reserveUSDT);
    /// @notice 查询余额
    function balanceOf(address account) external view returns (uint256);
    /// @notice 总供应量
    function totalSupply() external view returns (uint256);
    /// @notice 增加用户出局名额(结算成功时调用)
    function updateExitQuota(address user, uint256 amount) external;
    /// @notice 检查是否为活跃Keeper
    function isActiveKeeper(address addr) external view returns (bool);
    /// @notice 获取ATM持币者列表(K6修复)
    function getAtmHolders() external view returns (address[] memory);
    /// @notice 获取ATM持币者数量(K6修复)
    function getAtmHoldersCount() external view returns (uint256);
}

/// @notice 盲盒模块接口
interface IBlindBox {
    /// @notice 用户下注入口(ATMToken转账钩子调用)
    function onBlindBoxEntry(address user, uint256 amount, uint256 twapBase, uint256 twapPrice) external returns (bool);
    /// @notice 结算单笔注单
    function settle(uint256 betId) external;
    /// @notice 结算指定ID的注单(Keeper专用,用于只结算赢的)
    function settleBet(uint256 betId) external;
    /// @notice 批量结算注单
    function batchSettle(uint256 fromId, uint256 toId) external;
    /// @notice 结算最多maxCount笔已过期的待开奖注单(仅ATM合约或Keeper可调)
    function settleExpired(uint256 maxCount) external;
}

/// @notice 出局队列模块接口
interface IExitQueue {
    /// @notice 用户排队入口(ATMToken转账钩子调用)
    function onExitEntry(address user, uint256 amount, uint256 usdtValue) external returns (bool);
    /// @notice 结算出局队列,返回实际消耗的USDT
    function settleExits(uint256 availableUSDT) external returns (uint256 used);
    /// @notice 查看队头信息
    function getQueueHead() external view returns (address user, uint256 usdtOwed);
    /// @notice 退还未使用的USDT到ATMToken
    function returnUnusedUSDT() external;
    /// @notice K9重试失败转账
    function retryPendingClaim(address user) external;
    /// @notice 查询待重试数量
    function getPendingClaimCount() external view returns (uint256);
    /// @notice 查询待重试地址列表
    function getPendingClaimUsers(uint256 offset, uint256 limit) external view returns (address[] memory users, uint256[] memory amounts);
    /// @notice V2: 替换队列中用户地址
    function replaceQueueUser(address oldUser, address newUser) external;
}

/// @notice 抽奖模块接口
interface ILottery {
    /// @notice 买入回调(更新倒计时+发票)
    function onBuy(address user, uint256 usdtValue) external;
    /// @notice 卖出回调(扣票+更新倒计时)
    function onSell(address user, uint256 usdtValue) external;
    /// @notice P3注入奖池
    function injectP3(uint256 amount) external;
    /// @notice 一键提取全部奖池USDT
    function withdrawAll() external returns (uint256 amount);
}

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

interface IPancakeFactory {
    function createPair(address tokenA, address tokenB) external returns (address pair);
    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function feeTo() external view returns (address);
}

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

interface IPancakePair {
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function sync() external;
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function transfer(address to, uint value) external returns (bool);
    function approve(address spender, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
}

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

interface IPancakeRouter02 {
    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 removeLiquidity(
        address tokenA, address tokenB,
        uint liquidity, uint amountAMin, uint amountBMin,
        address to, uint deadline
    ) external returns (uint amountA, uint amountB);
    
    function swapExactTokensForTokens(
        uint amountIn, uint amountOutMin,
        address[] calldata path, address to, uint deadline
    ) external returns (uint[] memory amounts);
    
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn, uint amountOutMin,
        address[] calldata path, address to, uint deadline
    ) external;
    
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn, uint amountOutMin,
        address[] calldata path, address to, uint deadline
    ) external;

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

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

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint8","name":"","type":"uint8"}],"name":"E","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"deadBal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exitBal","type":"uint256"}],"name":"BlackholeRebalanced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalPercent","type":"uint256"}],"name":"DormancyConfiscated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"atmSold","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdtReceived","type":"uint256"}],"name":"FollowSell","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"keeper","type":"address"}],"name":"KeeperPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"keeper","type":"address"},{"indexed":false,"internalType":"uint256","name":"usdtSpent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bnbReceived","type":"uint256"}],"name":"KeeperRefueled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldAddr","type":"address"},{"indexed":true,"internalType":"address","name":"newAddr","type":"address"}],"name":"KeeperReplaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"keeper","type":"address"}],"name":"KeeperUnpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"atmAmount","type":"uint256"}],"name":"LPRemovalConfiscated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"P5Released","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"usdtAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"atmCleared","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lotteryRecovered","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"exitQueueRecovered","type":"uint256"}],"name":"PoolsWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"pool","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReclaimTriggered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"usdtAmount","type":"uint256"}],"name":"ReleaseAll","type":"event"},{"anonymous":false,"inputs":[],"name":"Renounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[],"name":"TwapReady","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"ACTIVE_TRADE_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEAD","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DORMANCY_INCREMENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DORMANCY_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXIT_HOLE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FOLLOW_SELL_RATIO","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KEEPER_GAS_TARGET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"KEEPER_TIMELOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAINTENANCE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P0_DISTRIBUTE_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P0_RELEASE_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P2P_WAKE_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P4_MIN_HOLDING","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P4_RECLAIM_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P5_DRAIN_DELAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P5_DRIP_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P5_LOW_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P5_RELEASE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REBALANCE_INTERVAL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SETTLE_GAP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TWAP_BLOCKS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TWAP_DEVIATION_MAX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"activeKeeperCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"atmHolders","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blindBoxContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"checkDormancyExt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"checkP0ReleaseExt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"coldWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"doSettleExitsExt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dormancyCursor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dripP5toP6Ext","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableAntiSync","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exitQueueContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"exitQuota","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"exitQuotaHolders","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"extension","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExitQuotaHolders","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolStatus","outputs":[{"internalType":"uint256","name":"_poolP3","type":"uint256"},{"internalType":"uint256","name":"_poolP4","type":"uint256"},{"internalType":"uint256","name":"_poolP5","type":"uint256"},{"internalType":"uint256","name":"_poolP6","type":"uint256"},{"internalType":"uint256","name":"_maintenancePool","type":"uint256"},{"internalType":"uint256","name":"_pendingP0Usdt","type":"uint256"},{"internalType":"uint256","name":"_p0AccumulatedATM","type":"uint256"},{"internalType":"uint256","name":"_twapPrice","type":"uint256"},{"internalType":"uint256","name":"_reserveATM","type":"uint256"},{"internalType":"uint256","name":"_reserveUSDT","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrice","outputs":[{"internalType":"uint256","name":"reserveATM","type":"uint256"},{"internalType":"uint256","name":"reserveUSDT","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTimingStatus","outputs":[{"internalType":"uint256","name":"_lastReleaseTime","type":"uint256"},{"internalType":"uint256","name":"_lastP4DistributeTime","type":"uint256"},{"internalType":"uint256","name":"_lastSettleTime","type":"uint256"},{"internalType":"uint256","name":"_lastRebalanceTime","type":"uint256"},{"internalType":"uint256","name":"_lastP5DripBlock","type":"uint256"},{"internalType":"bool","name":"_paused","type":"bool"},{"internalType":"bool","name":"_tradingEnabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTwapPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"inExitQuotaList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_usdt","type":"address"},{"internalType":"address","name":"_router","type":"address"},{"internalType":"address","name":"_p1","type":"address"},{"internalType":"address","name":"_p2","type":"address"},{"internalType":"address","name":"_cold","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address[]","name":"_keepers","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"internalTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isActiveKeeper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isDividendExcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isHardExcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isInAtmHolderList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isInLpHolderList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isKeeperPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isKeeperWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isLpPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isRouter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isWhitelistBurn","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"keeperIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"keeperList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastConfiscatedPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastLpReflowTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastP0DistributeTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastP4DistributeTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastP4QualifiedTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastP5DripBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastP5ReleaseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRebalanceTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastReleaseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastSettleTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastSwapTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lotteryContract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lpHolders","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maintenancePool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"p0AccumulatedATM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"p1Wallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"p2Wallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"p5BelowThresholdSince","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"p7LpRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingP0Usdt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolP3","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolP4","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolP5","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolP6","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolP7","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebalanceBlackholesExt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"redistributeToP0Ext","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"releaseAllExt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounced","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"retryPendingClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_ext","type":"address"}],"name":"setExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapHelper","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenDistributor","outputs":[{"internalType":"contract TokenDistributor","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalExitQuota","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"tradingEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"tryDistributeP0Ext","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"twapBufferIndex","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapCumulativePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapLastBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapLastPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"twapReady","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"updateExitQuota","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateTwapExt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6080806040523461001757615ac490816200001d8239f35b600080fdfe60806040526004361015610015575b3661558b57005b60003560e01c80630307bc001461075257806303fd2a451461074d57806305fe13fc1461074857806306fdde0314610743578063095ea7b31461073e5780630fc6a11c14610739578063127ac4e01461073457806317b67bff1461072f57806318160ddd1461063557806318a6bc321461072a5780631cc8e626146107255780631f1cc015146107205780632224768d1461071b57806323b872dd14610716578063255a2e541461071157806325cf72d11461070c5780632cd75952146107075780632d5537b0146107025780632d7c3bfa146106fd5780632de7204e146106f85780632f48ab7d146106f3578063313ce567146106ee57806331f438c2146106e957806333beb1ba146106e457806335630eda14610540578063357cc5db146106df57806336b19cd7146106da5780633810df90146106d557806338e539fe146106d05780633b61b8fe146106cb5780633b85db47146106c65780633baa4ebc146106c15780633d4bc713146106bc57806342a82b4f146106b7578063444486b2146106b257806345697add146106ad5780634ada218b146106a85780634dde09b6146106a35780634ece7c061461069e5780634f94f16c146105cc5780635465178f14610699578063567ff369146106945780635bd713b51461068f5780635c2da7cd146105405780635c975abb1461068a578063627e4ab61461068557806365cf7c9b14610680578063677967611461067b5780636be13c92146106765780636e963ace146106715780636f741f2a1461066c57806370a0823114610667578063771a3a1d1461066257806377a405a61461065d5780637a955537146106585780637f79496c146106535780638696d1fe1461064e5780638c1f2fcc146106495780638c689788146106445780638cd877861461063f5780638f4586831461063a578063902d55a514610635578063935cac391461063057806395d89b411461062b578063979ab6ff1461062657806397d039ad1461062157806398d5fdca1461061c5780639aff712a146106175780639d0b31bf146106125780639f0d7eb81461060d578063a7b9a5f914610608578063a7c4b5d514610603578063a8aa1b31146105fe578063a9059cbb146105f9578063ab622d9a146105f4578063abdc688b146105ef578063ae72bd7e146105ea578063b206e81914610540578063b29c662a146105e5578063b4ee3cbf146105e0578063b970ce4e146105db578063bb0dc9db14610540578063bc945e1c146105d6578063befcefbe146105d1578063bf0d8212146105cc578063c45a0155146105c7578063c56da4b8146105c2578063c58fb143146105bd578063c674fff4146105b8578063c68890c3146105b3578063c7aaaa75146105ae578063c867e210146105a9578063cf5b67fc146105a4578063d232c2201461059f578063d5bc13be1461059a578063d76a39b114610595578063d937ed3714610590578063d9ca21d51461058b578063da73157d14610586578063dd4f3c4614610581578063dd62ed3e1461057c578063dfaf734a14610577578063dfff8d6314610572578063e980f8521461056d578063e9e5cf7314610568578063ea9b717e14610563578063ec4515dd1461055e578063ec7ef6f614610559578063eee2bfa014610554578063f3d7d2821461054f578063f76a105a14610540578063f887ea401461054a578063fab46cd614610545578063fb5189ac14610540578063fd8565b91461053b578063fdcd987d14610536578063fe2d5af5146105315763fe575a870361000e576122c0565b61229f565b61225d565b612234565b611140565b61220b565b6121e2565b6121a0565b612185565b612165565b61211b565b6120f2565b6120d4565b612077565b612057565b612039565b611fe6565b611fc8565b611f7e565b611f60565b611f44565b611f02565b611edf565b611ebc565b611e93565b611e73565b611e56565b611e14565b611df7565b611dd9565b611dbd565b611d94565b6114d6565b611d76565b611d52565b611d2c565b611d03565b611cda565b611cbc565b611c9e565b611bfb565b611bd1565b611ba8565b611b85565b611b67565b611b1d565b611b00565b611abe565b611a95565b611a66565b611a48565b611a0c565b61195f565b610abf565b61191d565b6118ff565b6118e1565b6118c3565b611881565b61180b565b6117c1565b61176e565b611750565b61168b565b611649565b611620565b6115f7565b6115b5565b611597565b611577565b611551565b611533565b611515565b6114f9565b611499565b611479565b611453565b61141c565b6113f9565b611318565b6112e5565b6112c5565b6112a1565b611283565b611265565b611249565b611220565b61115e565b611123565b6110ff565b6110e3565b6110ba565b61107a565b61105c565b611033565b611015565b610ff7565b610fb5565b610f1f565b610e93565b610e56565b610b0f565b610ae6565b610a48565b610a2a565b610a01565b610984565b610931565b6107fe565b6107a4565b610767565b600091031261076257565b600080fd5b34610762576000366003190112610762576020602f54604051908152f35b6001600160a01b031690565b6001600160a01b03909116815260200190565b3461076257600036600319011261076257602060405161dead8152f35b90815180825260208080930193019160005b8281106107e1575050505090565b83516001600160a01b0316855293810193928101926001016107d3565b34610762576000806003193601126108795760405180918260325480845260208094019060328452848420935b8582821061085a57505050610842925003836108c5565b6108566040519282849384528301906107c1565b0390f35b85546001600160a01b031684526001958601958895509301920161082b565b80fd5b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116108a557604052565b61087c565b604081019081106001600160401b038211176108a557604052565b601f909101601f19168101906001600160401b038211908210176108a557604052565b6020808252825181830181905290939260005b82811061091d57505060409293506000838284010152601f8019910116010190565b8181018601518482016040015285016108fb565b3461076257600036600319011261076257610856604051610951816108aa565b600981526820aa26902a37b5b2b760b91b6020820152604051918291826108e8565b6001600160a01b0381160361076257565b34610762576040366003190112610762576004356109a181610973565b60243590336000526001602052816109bd826040600020610e3f565b556040519182526001600160a01b03169033907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590602090a3602060405160018152f35b34610762576000366003190112610762576007546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020602654604051908152f35b3461076257600036600319011261076257303303610aa657680ad78ebc5ac6200000610a7e610a75614d77565b90602154613ce9565b10610a8d57610a8b615308565b005b6040516321c38c0960e21b8152600b6004820152602490fd5b6040516321c38c0960e21b815260086004820152602490fd5b346107625760003660031901126107625760206040516b12bda5c60552e7c7a80000008152f35b34610762576000366003190112610762576008546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020603854604051908152f35b600160009081526020527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d90565b61dead600090815260205260008051602062005a6f83398151915290565b6001600160a01b0316600090815260208190526040902090565b61dead600052600a6020527f20677881080440a9b3c87e826370bb5d9c2f74efd4dede686d52d77a6a09f8bb90565b6001600052600a6020527fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bc790565b6001600160a01b03166000908152600a6020526040902090565b6001600160a01b03166000908152600f6020526040902090565b6001600160a01b03166000908152600d6020526040902090565b6001600160a01b03166000908152600e6020526040902090565b6001600160a01b0316600090815260106020526040902090565b6001600160a01b03166000908152600b6020526040902090565b6001600160a01b03166000908152600c6020526040902090565b6001600052602b6020527ffcc3d43705633578a5e8f1b6d6f38d08eb8cb891174edcc94b1a54972a1aebbd90565b61dead600052602b6020527fcb067d08c3b0752a639a17b312edc0e4384bd60a697642bbd8bdd8260a31a34790565b6001600160a01b03166000908152602b6020526040902090565b6001600052602c6020527fa1f88ee5f5d946e3956f6291445d84cd8aea2bf6c57f4f4ac349f7a33888264390565b61dead600052602c6020527fe59ee55b272e0a0ceadcbcef22910224ebf112343a13eb9b581203f0fbdd8e0690565b6001600160a01b03166000908152602c6020526040902090565b600160005260376020527f8e0cc0f1f0504b4cb44a23b328568106915b169e79003737a7b094503cdbeeb090565b61dead60005260376020527f1403828e2002138cf2c0587ee09995d5d8f06540752d9ee5757863861cf6948690565b6001600160a01b0316600090815260376020526040902090565b6001600160a01b0316600090815260356020526040902090565b6001600160a01b0316600090815260336020526040902090565b9060018060a01b0316600052602052604060002090565b3461076257602036600319011261076257600435610e7381610973565b60018060a01b0316600052602e6020526020604060002054604051908152f35b3461076257602036600319011261076257600435610eb081610973565b6001600160a01b031660009081526010602052604090205460ff1680610ede575b6020906040519015158152f35b50601160205260406000205460ff1615610ed1565b606090600319011261076257600435610f0b81610973565b90602435610f1881610973565b9060443590565b3461076257610f2d36610ef3565b9060018060a01b03831692836000526001602052610f5060406000203390610e3f565b549360018501610f71575b50610f669350612d3e565b602060405160018152f35b838510610f9c57610f66948491600052600160205203610f95336040600020610e3f565b5538610f5b565b6040516321c38c0960e21b815260076004820152602490fd5b3461076257602036600319011261076257600435610fd281610973565b60018060a01b0316600052600f602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576020601f54604051908152f35b34610762576000366003190112610762576020605154604051908152f35b3461076257600036600319011261076257604a546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020602954604051908152f35b346107625760203660031901126107625760043561109781610973565b60018060a01b0316600052601a602052602060ff60406000205416604051908152f35b34610762576000366003190112610762576054546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257602060405160128152f35b3461076257600036600319011261076257602060405168056bc75e2d631000008152f35b346107625760003660031901126107625760206040516103208152f35b34610762576000366003190112610762576020604051620151808152f35b346107625760203660031901126107625760043561117b81610973565b600090338252601060205260ff60408320541615801561120d575b6111f4576005546001600160a01b0390811691839190833b156111f05760249083604051958694859363357cc5db60e01b85521660048401525af180156111eb576111df575080f35b6111e890610892565b80f35b612355565b8280fd5b6040516321c38c0960e21b815260036004820152602490fd5b50601160205260ff604083205416611196565b34610762576000366003190112610762576053546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257602060405160018152f35b34610762576000366003190112610762576020603a54604051908152f35b34610762576000366003190112610762576020603c54604051908152f35b34610762576000366003190112610762576020604051680ad78ebc5ac62000008152f35b3461076257600036600319011261076257303303610aa657610a8b6154d1565b3461076257600036600319011261076257602060405160058152f35b6001600160401b0381116108a55760051b60200190565b346107625760e03660031901126107625760043561133581610973565b60243561134181610973565b60443561134d81610973565b60643561135981610973565b6084359061136682610973565b60a4359261137384610973565b60c435946001600160401b03861161076257366023870112156107625785600401359661139f88611301565b966113ad60405198896108c5565b88885260209860248a8a019160051b8301019136831161076257602401905b8282106113e057505050610a8b97506125a9565b8a809183356113ee81610973565b8152019101906113cc565b3461076257600036600319011261076257602060ff603d54166040519015158152f35b346107625760203660031901126107625760043561143981610973565b303303610aa65761144b602091614957565b604051908152f35b3461076257600036600319011261076257602060ff60475460101c166040519015158152f35b3461076257600036600319011261076257303303610aa657610a8b614889565b34610762576020366003190112610762576004356114b681610973565b60018060a01b0316600052602b6020526020604060002054604051908152f35b34610762576000366003190112610762576020604051678ac7230489e800008152f35b3461076257600036600319011261076257602060405160068152f35b34610762576000366003190112610762576020601254604051908152f35b34610762576000366003190112610762576020602554604051908152f35b3461076257600036600319011261076257602060ff60475460081c166040519015158152f35b3461076257600036600319011261076257303303610aa657610a8b6142a1565b34610762576000366003190112610762576020602d54604051908152f35b34610762576020366003190112610762576004356115d281610973565b60018060a01b03166000526011602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576058546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576002546040516001600160a01b039091168152602090f35b346107625760203660031901126107625760043561166681610973565b60018060a01b0316600052600d602052602060ff604060002054166040519015158152f35b34610762576020366003190112610762576004356116a881610973565b6116b3605754610785565b6001600160a01b0381811690831681149081611746575b5080611737575b6116f3575b6108566116e283610b79565b546040519081529081906020820190565b60525443146116d65761170e611707614d77565b5091610b79565b541061171a57386116d6565b6040516321c38c0960e21b8152600e6004820152602490fd5b0390fd5b5060475460181c60ff166116d1565b90503314386116ca565b34610762576000366003190112610762576020604854604051908152f35b346107625760203660031901126107625760043561178b81610973565b60018060a01b0316600052602c6020526020604060002054604051908152f35b634e487b7160e01b600052603260045260246000fd5b3461076257602036600319011261076257600435603654811015610762576036600052600080516020620059af83398151915201546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257610140601b54601c54601d5490601e546051546025546021549161183e615514565b93611847614d77565b979096604051998a5260208a015260408901526060880152608087015260a086015260c085015260e0840152610100830152610120820152f35b346107625760203660031901126107625760043561189e81610973565b60018060a01b03166000526037602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576020601d54604051908152f35b34610762576000366003190112610762576020604654604051908152f35b34610762576000366003190112610762576020602a54604051908152f35b346107625760203660031901126107625760043561193a81610973565b60018060a01b0316600052600c602052602060ff604060002054166040519015158152f35b346107625761196d36610ef3565b9061198161197c600454610785565b610785565b331415806119f5575b806119de575b610aa6576001600160a01b038316600181141590816119d1575b506119b857610a8b926137b4565b6040516321c38c0960e21b815260066004820152602490fd5b61dead91501415386119aa565b506119ed61197c600654610785565b331415611990565b50611a0461197c600554610785565b33141561198a565b3461076257600036600319011261076257610856604051611a2c816108aa565b600381526241544d60e81b6020820152604051918291826108e8565b346107625760003660031901126107625760206040516202a3008152f35b34610762576000366003190112610762576020601c54604051908152f35b908152602081019190915260400190565b3461076257600036600319011261076257611aae614d77565b9061085660405192839283611a84565b3461076257602036600319011261076257600435611adb81610973565b60018060a01b03166000526033602052602060ff604060002054166040519015158152f35b3461076257600036600319011261076257602060405161024c8152f35b3461076257602036600319011261076257600435603454811015610762576034600052600080516020620059cf83398151915201546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020601b54604051908152f35b3461076257602036600319011261076257303303610aa657610a8b600435614300565b34610762576000366003190112610762576057546040516001600160a01b039091168152602090f35b3461076257604036600319011261076257610f66600435611bf181610973565b6024359033612d3e565b3461076257602036600319011261076257600435611c1881610973565b6058546001600160a01b039081163303611c8557811615611c5457604a80546001600160a01b0319166001600160a01b03909216919091179055005b60405162461bcd60e51b81526020600482015260096024820152682d22a927afa0a2222960b91b6044820152606490fd5b6040516321c38c0960e21b815260016004820152602490fd5b34610762576000366003190112610762576020602154604051908152f35b34610762576000366003190112610762576020602854604051908152f35b34610762576000366003190112610762576006546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576003546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257602060ff60475460181c166040519015158152f35b34610762576000366003190112610762576020604051683635c9adc5dea000008152f35b34610762576000366003190112610762576020603054604051908152f35b34610762576000366003190112610762576056546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257602060405160c88152f35b34610762576000366003190112610762576020601e54604051908152f35b346107625760003660031901126107625760208054604051908152f35b3461076257602036600319011261076257600435611e3181610973565b60018060a01b03166000526035602052602060ff604060002054166040519015158152f35b346107625760003660031901126107625760206040516101e08152f35b3461076257600036600319011261076257303303610aa657610a8b615217565b3461076257604036600319011261076257610a8b600435611eb381610973565b6024359061519e565b3461076257600036600319011261076257602060ff604754166040519015158152f35b3461076257600036600319011261076257602060405167120a871cc00200008152f35b3461076257602036600319011261076257600435611f1f81610973565b60018060a01b0316600052600a602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576020604051601e8152f35b34610762576000366003190112610762576020603954604051908152f35b346107625760203660031901126107625760043560325481101561076257603260005260008051602062005a0f83398151915201546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020603b54604051908152f35b3461076257604036600319011261076257602061203060043561200881610973565b6024359061201582610973565b6001600160a01b031660009081526001845260409020610e3f565b54604051908152f35b34610762576000366003190112610762576020602254604051908152f35b3461076257600036600319011261076257303303610aa657610a8b614b86565b346107625760003660031901126107625760e060225460ff60305460465460395460295491604754936040519687526020870152604086015260608501526080840152818160081c16151560a084015260101c16151560c0820152f35b34610762576000366003190112610762576020603154604051908152f35b34610762576000366003190112610762576005546040516001600160a01b039091168152602090f35b3461076257602036600319011261076257600435601354811015610762576013600052600080516020620059ef83398151915201546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257303303610aa657610a8b614778565b3461076257600036600319011261076257602061144b615514565b34610762576020366003190112610762576004356121bd81610973565b60018060a01b0316600052600e602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576055546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576004546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576059546040516001600160a01b039091168152602090f35b346107625760203660031901126107625760043561227a81610973565b60018060a01b03166000526010602052602060ff604060002054166040519015158152f35b3461076257600036600319011261076257602060ff60455416604051908152f35b34610762576020366003190112610762576004356122dd81610973565b60018060a01b0316600052600b602052602060ff604060002054166040519015158152f35b1561230957565b60405162461bcd60e51b815260206004820152600c60248201526b1053149150511657d253925560a21b6044820152606490fd5b90816020910312610762575161235281610973565b90565b6040513d6000823e3d90fd5b805460ff19166001179055565b634e487b7160e01b600052601160045260246000fd5b60001981146123935760010190565b61236e565b8051156123a55760200190565b6117ab565b8051600110156123a55760400190565b80518210156123a55760209160051b010190565b601354600160401b8110156108a55760018101806013558110156123a5576013600052600080516020620059ef8339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b603654600160401b8110156108a55760018101806036558110156123a5576036600052600080516020620059af8339815191520180546001600160a01b0319166001179055565b603654600160401b8110156108a55760018101806036558110156123a5576036600052600080516020620059af8339815191520180546001600160a01b03191661dead179055565b603654600160401b8110156108a55760018101806036558110156123a5576036600052600080516020620059af8339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b603454600160401b8110156108a55760018101806034558110156123a5576034600052600080516020620059cf8339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b603254600160401b8110156108a55760018101806032558110156123a557603260005260008051602062005a0f8339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b91926126416126639295979896946125d66125d16125cd60595460ff9060a01c1690565b1590565b612302565b6059805460ff60a01b1916600160a01b179055605480546001600160a01b0319166001600160a01b038716179055605580546001600160a01b0319166001600160a01b038916179055600280546001600160a01b0319166001600160a01b0392909216919091179055565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b605880546001600160a01b0319166001600160a01b03871617905560405163c45a015560e01b81526001600160a01b0395906020908181600481898c165afa9081156111eb57600091612be6575b50605680546001600160a01b0319166001600160a01b0383161790556040516364e329cb60e11b81523060048201526001600160a01b038516602482015290829082908160008c82604481010393165af19081156111eb5761273992600092612bb9575b5050605780546001600160a01b0319166001600160a01b0392909216919091179055565b60008052600a6020526127707f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e3612361565b612361565b61277b61276b610b93565b61278661276b610bc2565b61279261276b30610bf0565b60008052600f6020526127c47ff4803e074bd026baaf6ed2e288c9515f68c72fb7216eebdd7cae1718a53ec375612361565b61dead600052600f6020526127f87f99629f56119585bf27511b6b7d295dffb54757453fcc3dabcf51d92028301f10612361565b6001600052600f60205261282b7f169f97de0d9a84d840042b17d3c6b9638b3d6fd9024c9eb0c7a306a17b49f88f612361565b61283761276b30610c0a565b61284d61276b612848605754610785565b610c24565b61285961276b85610c3e565b61286f61276b61286a605754610785565b610c0a565b60005b875181101561290357806128a461276b61289f6128926128fe958d6123ba565b516001600160a01b031690565b610c58565b6128b96128b4612892838c6123ba565b6123ce565b6128f960ff82166128ea6128d0612892858e6123ba565b6001600160a01b03166000908152601a6020526040902090565b9060ff1660ff19825416179055565b612384565b612872565b50919395612915909591939551601255565b61293261292185610b79565b6b12bda5c60552e7c7a80000009055565b600060008051602062005a4f833981519152604051928616928061296681906b12bda5c60552e7c7a8000000602083019252565b0390a361297242602255565b61297b42602855565b61298443602955565b61298d42603955565b61299642603055565b61299f42603155565b6129a842604655565b6129c0630100000063ff000000196047541617604755565b6129ca6003604855565b3060009081526001602052604090206129ef906129e8908690610e3f565b6000199055565b6040516103f28082016001600160401b038111838210176108a5578291620055bd833903906000f080156111eb57600880546001600160a01b0319166001600160a01b03909216919091179055612a4a61197c600854610785565b803b156107625760405163184b955960e01b81526001600160a01b03848116600483015283166024820152306044820152906000908290606490829084905af19485156111eb57612ac8612b6c94612aea93612b9e98612ba0575b50604b80546001600160a01b0319166001600160a01b0392909216919091179055565b604c80546001600160a01b0319166001600160a01b0392909216919091179055565b612b1a612af8605654610785565b604d80546001600160a01b0319166001600160a01b0392909216919091179055565b612b4a612b28605754610785565b604e80546001600160a01b0319166001600160a01b0392909216919091179055565b604f80546001600160a01b0319166001600160a01b0392909216919091179055565b605080546001600160a01b0319169055605380546001600160a01b0319166001600160a01b0392909216919091179055565b565b80612bad612bb392610892565b80610757565b38612aa5565b612bd89250803d10612bdf575b612bd081836108c5565b81019061233d565b3880612715565b503d612bc6565b612bfd9150823d8411612bdf57612bd081836108c5565b386126b1565b906102589182810292818404149015171561239357565b9060648202918083046064149015171561239357565b906101f49182810292818404149015171561239357565b906103209182810292818404149015171561239357565b9060c882029180830460c8149015171561239357565b90670de0b6b3a76400009182810292818404149015171561239357565b90605f820291808304605f149015171561239357565b9060698202918083046069149015171561239357565b9060828202918083046082149015171561239357565b9060468202918083046046149015171561239357565b8181029291811591840414171561239357565b634e487b7160e01b600052601260045260246000fd5b8115612d1c570490565b612cfc565b6103e71981019190821161239357565b9190820391821161239357565b91906001600160a01b03808416919082156119b85783156119b85783612d6386610b79565b5410610f9c5760475460081c60ff1680613159575b6119b857612d8f612d8886610bf0565b5460ff1690565b61314d5760176009541661314d57612da9612d8886610c72565b801561313b575b61312257612dbd85614957565b6130fb575b811661dead8114806130e6575b15612de057505050612b9e916140bd565b600114806130d1575b15612df9575050612b9e91614190565b612e08612d8885949394610c24565b80156130bf575b15612fe357612e20612d8885610c24565b15612fdd57805b604754612e389060101c60ff161590565b612f14575b50612b9e93612e4e612d8883610c24565b9384612f00575b84612ef6575b5083612ee3575b831580612ed1575b80612ebc575b80612ea7575b1561384057612ea2612e9d612e97612e9060485487612ce9565b6064900490565b85612d31565b613e16565b613840565b50612eb76125cd612d8883610c8c565b612e76565b50612ecc6125cd612d8883610c72565b612e70565b50612ede612d8883610c24565b612e6a565b9250612eee82614e62565b151592612e62565b3214935038612e5b565b9350612f0e612d8833610c3e565b93612e55565b612f20612d8883610c24565b9081612fc9575b81612fbf575b81612fac575b612f3f612d8887610c24565b9182612f99575b159182612f90575b5081612f79575b50612f605738612e3d565b6040516321c38c0960e21b815260096004820152602490fd5b612f8a9150612d886125cd91610c8c565b38612f55565b15915038612f4e565b9150612fa484614f67565b151591612f46565b9050612fb783614e62565b151590612f33565b3285149150612f2d565b9050612fd7612d8833610c3e565b90612f27565b83612e27565b929150612ff18184846137b4565b612ffa83610d03565b5415806130ad575b613082575b61300f615514565b80613021575b50505050612b9e613d06565b61303861304691683635c9adc5dea0000093612ce9565b670de0b6b3a7640000900490565b1015613054575b8080613015565b6000918261306f61307a934261306982610d03565b55610d7a565b554261306982610d03565b55388061304d565b4261308c84610d03565b5561309683610d7a565b54156130075760006130a784610d7a565b55613007565b506130b783610b79565b541515613002565b506130cc612d8882610c24565b612e0f565b506130e16125cd612d8886610c8c565b612de9565b506130f66125cd612d8887610c8c565b612dcf565b61310485610b79565b5480851161311a575b5083612dc2575050505050565b93503861310d565b6040516321c38c0960e21b815260056004820152602490fd5b50613148612d8883610c72565b612db0565b509050612b9e926137b4565b506131696125cd612d8887610c58565b612d78565b906101e0820180921161239357565b9061024c820180921161239357565b9062015180820180921161239357565b906001820180921161239357565b9190820180921161239357565b6001906131c381610b79565b6131ce848254612d31565b90556131d8610b2d565b6131e38482546131aa565b905560008051602062005a4f83398151915260405191838060a01b0316918061321186829190602083019252565b0390a36132226125cd612d88610bc2565b8061337f575b8061336b575b613353575b6132416125cd612d88610bc2565b80613317575b806132db575b6132545750565b61325c610ca6565b5461328857504261326b610ca6565b55613274610d1d565b5461327b57565b6000613285610d1d565b55565b603d5460ff16613296575b50565b61329e615514565b806132a8575b5050565b6130386132bf91683635c9adc5dea0000093612ce9565b10156132c757565b426132d0610ca6565b556000613285610d1d565b506001600052600e6020526133126125cd7fa7c5ba7114a813b50159add3a36832908dc83db71d0b9a24c2ad0f83be958207612d88565b61324d565b506001600052600d60205261334e6125cd7ffd54ff1ed53f34a900b24c5ba64f85761163b5d82d98a47b9bd80e45466993c5612d88565b613247565b61335b612421565b61336661276b610d94565b613233565b5061337a6125cd612d88610d94565b61322e565b50613388610b2d565b541515613228565b90613399610b2d565b6133a4828254612d31565b90556133af82610b79565b6133ba8282546131aa565b90556040518181526001600160a01b03831690819060019060008051602062005a4f8339815191529080602081015b0390a315158080613527575b80613515575b80613500575b6134e6575b806134d1575b806134bc575b806134a7575b613420575050565b61342982610d03565b5461345657504261343982610d03565b5561344381610d7a565b5461344b5750565b613285600091610d7a565b603d5460ff16613464575050565b61346c615514565b80613477575b505050565b61303861348e91683635c9adc5dea0000093612ce9565b10156134975750565b6132856000914261306982610d03565b506134b76125cd612d8884610c3e565b613418565b506134cc6125cd612d8884610c24565b613412565b506134e16125cd612d8884610bf0565b61340c565b6134ef836124b0565b6134fb61276b84610df1565b613406565b506135106125cd612d8885610df1565b613401565b5061351f83610b79565b5415156133fb565b506135376125cd612d8885610bf0565b6133f5565b61dead9061354981610b79565b613554848254612d31565b905561355e610b5b565b6135698482546131aa565b90556040518381526001600160a01b039091169060008051602062005a4f8339815191529080602081015b0390a36135a56125cd612d88610b93565b806136ff575b806136eb575b6136d3575b6135c46125cd612d88610b93565b80613696575b80613659575b6135d75750565b6135df610cd4565b546136085750426135ee610cd4565b556135f7610d4b565b546135fe57565b6000613285610d4b565b603d5460ff166136155750565b61361d615514565b80613626575050565b61303861363d91683635c9adc5dea0000093612ce9565b101561364557565b4261364e610cd4565b556000613285610d4b565b5061dead600052600e6020526136916125cd7ff77e91909e61d18f67b875b2bfcae1f683a8d555e55382e3a6b082e2c59ea57a612d88565b6135d0565b5061dead600052600d6020526136ce6125cd7fdc7fafdc41998a74ecacb8f8bd877011aba1f1d03a3a0d37a2e7879a393b1d6a612d88565b6135ca565b6136db612468565b6136e661276b610dc2565b6135b6565b506136fa6125cd612d88610dc2565b6135b1565b50613708610b5b565b5415156135ab565b613718610b2d565b613723828254612d31565b905561372d610b5b565b6137388282546131aa565b905561dead600160008051602062005a4f8339815191526040518061359486829190602083019252565b61376a610b5b565b613775828254612d31565b905561377f610b2d565b61378a8282546131aa565b9055600161dead60008051602062005a4f8339815191526040518061321186829190602083019252565b60008051602062005a4f833981519152909291926137d181610b79565b6137dc848254612d31565b90556137e784610b79565b6137f28482546131aa565b90556040518381526001600160a01b038581169384939091169180602081016133e9565b90816020910312610762575190565b6001600160a01b039091168152602081019190915260400190565b92919061384f612d8885610c24565b93848061385e612d8885610c24565b958115613ce1578685935b613cd3575b613bac575b50613a66575b613885612d8882610c8c565b613a3e57506138e761389c612e9060485486612ce9565b936138e06138db6138c76138b08885612d31565b936138b9614b86565b6138c1614d77565b91613ce9565b966138d38130886137b4565b6021546131aa565b602155565b83836137b4565b8415613a3757505b678ac7230489e8000082101580613a1b575b6006546001600160a01b039061391690610785565b16908115159081613a13575b5061395b575b50505061393e575b61393657565b612b9e613d06565b613946614778565b61394e613d06565b6139566142a1565b613930565b84156139c5575061397361197c61197c600654610785565b91823b156107625761399f9260009283604051809681958294636695575360e01b845260048401613825565b03925af16139b2575b505b388080613928565b80612bad6139bf92610892565b386139a8565b91823b15610762576139f19260009283604051809681958294636c706f9760e11b845260048401613825565b03925af1613a00575b506139aa565b80612bad613a0d92610892565b386139fa565b905038613922565b42613a2583610d03565b556000613a3183610d7a565b55613901565b90506138ef565b929060009550613a5d945091613a53926137b4565b4261306982610d03565b55612b9e614b86565b613a6f84614f67565b156138795750935090915060046020613a8f61197c61197c605654610785565b604051622fcfcb60e31b815292839182905afa9081156111eb57600091613b8e575b506001600160a01b039081168015159081613b6f575b508015613b50575b8015613b33575b61312257613ae6612d8883610c8c565b15613af55750613936926137b4565b90613b22837f7bb65d2a35e8a1815efe8e603e65dfaac438d631890c2669944316c08d25c94394956131b7565b6040519384521691602090a2613936565b5073f4c21a1cb819e5f7abe6defde3d118d8f3d61fa73214613ad6565b5073f4c21a1cb819e5f7abe6defde3d118d8f3d61fa781831614613acf565b838316811491508115613b84575b5038613ac7565b9050321438613b7d565b613ba6915060203d8111612bdf57612bd081836108c5565b38613ab1565b9050613bb9578538613873565b50809450613bc793506137b4565b613c0e613bd2614d77565b90506020613be761197c61197c605454610785565b613bf2605754610785565b9060405180809681946370a0823160e01b835260048301610791565b03915afa9081156111eb57678ac7230489e8000092600092613ca3575b5060009181811115613c9c57613c419250612d31565b1015613c80575b613c576125cd612d8883610e0b565b613c65575b50612b9e613d06565b61276b81613c75613c7a93612503565b610e0b565b38613c5c565b42613c8a82610d03565b556000613c9682610d7a565b55613c48565b5050613c41565b613cc591925060203d8111613ccc575b613cbd81836108c5565b810190613816565b9038613c2b565b503d613cb3565b613cdc43605255565b61386e565b868493613869565b90918215613cfe57613cfa91612ce9565b0490565b505050600090565b6004546001600160a01b0390613d1b90610785565b1680613d50575b50613d2e60465461316e565b42101580613d45575b613d3d57565b612b9e614889565b50601e541515613d37565b803b15610762576040516343b20f5960e11b815260036004820152906000908290602490829084905af180156111eb5715613d225780612bad613d9292610892565b38613d22565b60405190606082016001600160401b038111838210176108a55760405260028252604082602036910137565b90608092613dea919695949683526000602084015260a0604084015260a08301906107c1565b6001600160a01b0390951660608201520152565b90816020910312610762575180151581036107625790565b60059004613e22610b2d565b548180159182156140b3575b505061329357613e42600260095417600955565b613e4c8130613390565b613e54613d98565b90613e7130613e6284612398565b6001600160a01b039091169052565b613e7c605454610785565b613e8981613e62856123aa565b613e9761197c600854610785565b916040519384936370a0823160e01b9384865260209586918180613ebe8660048301610791565b03916001600160a01b03165afa9586156111eb57600096614094575b50613eec61197c61197c605554610785565b91823b1561076257613f1b9260009283604051809681958294635c11d79560e01b845242918b60048601613dc4565b03925af180156111eb57614081575b50613f3c61197c61197c605454610785565b91613f4b61197c600854610785565b94604051918252848280613f628960048301610791565b0381875afa80156111eb57613f7f92600091614064575b50612d31565b9182613f9a575b5050505050612b9e60021960095416600955565b6040516323b872dd60e01b81526001600160a01b03959095166004860152306024860152604485018390528390859060649082906000905af19283156111eb576000947fec997f3558959d8bb505856e4e9c2b51cddd13280b4d310f948423b65333269a94614036575b505061401a614015836025546131aa565b602555565b61402960405192839283611a84565b0390a23880808080613f86565b8161405592903d1061405d575b61404d81836108c5565b810190613dfe565b503880614004565b503d614043565b61407b9150863d8811613ccc57613cbd81836108c5565b38613f79565b80612bad61408e92610892565b38613f2a565b6140ac919650853d8711613ccc57613cbd81836108c5565b9438613eda565b1090508138613e2e565b906140cd6125cd603d5460ff1690565b6119b8576140db818361353c565b6004546001600160a01b03906140f090610785565b1691826140fc57505050565b61415792602092600061410d615514565b604051634054b82d60e01b81526001600160a01b0390951660048601526024850192909252670de0b6b3a76400006044850152606484019190915291938492839182906084820190565b03925af19081156111eb57600091614172575b5015610aa657565b61418a915060203d811161405d5761404d81836108c5565b3861416a565b61419c612d8882610c24565b801561428f575b614276576141b66125cd603d5460ff1690565b6119b8576141ce6130386141c8615514565b84612ce9565b6141d883836131b7565b6005546001600160a01b03906141ed90610785565b16806141ff5750505050612b9e613d06565b60405163044f421360e21b81526001600160a01b039390931660048401526024830193909352604482015290602090829060649082906000905af19081156111eb57600091614258575b5015610aa65738808080613015565b614270915060203d811161405d5761404d81836108c5565b38614249565b6040516321c38c0960e21b8152600a6004820152602490fd5b5061429c612d8882610c3e565b6141a3565b602554801561329357680ad78ebc5ac62000008110156142fb5750602654620151808101809111612393574210156142d557565b6142e0602554614300565b6142e86146cf565b6142f0614778565b600060255542602655565b6142e0905b6143aa7f5832bbcb6ff6598fdb2e6a73e2da2488ce3586bafac1c488349afae01d4eef4f9161439a61439560806143368461461b565b805180151580614419575b6143f6575b506020810151801515806143d8575b6143af575b5061437361436e6040830151601b546131aa565b601b55565b61438b6143866060830151601c546131aa565b601c55565b0151601d546131aa565b601d55565b6040519081529081906020820190565b0390a1565b6143d2906143c161197c605454610785565b6143cc600354610785565b90614437565b3861435a565b506003546001600160a01b03906143ee90610785565b161515614355565b6144139061440861197c605454610785565b6143cc600254610785565b38614346565b506002546001600160a01b039061442f90610785565b161515614341565b6144c39160008060405193614471856144636020998a83019763a9059cbb60e01b895260248401613825565b03601f1981018752866108c5565b60018060a01b03169260405194614487866108aa565b8786527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656488870152519082855af16144bd61454b565b9161458a565b805190828215928315614533575b505050156144dc5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b6145439350820181019101613dfe565b3882816144d1565b3d15614585573d906001600160401b0382116108a55760405191614579601f8201601f1916602001846108c5565b82523d6000602084013e565b606090565b919290156145ec575081511561459e575090565b3b156145a75790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156145ff5750805190602001fd5b60405162461bcd60e51b815290819061173390600483016108e8565b604051919060a083016001600160401b038111848210176108a5576040526000835260208301600081526040840191600083526060850190600082526080860193600085528661012c94858402958487041484151715612393576146c36146c3946146c3936127106146cb9904815261469e61469683612c03565b612710900490565b84526146ac61469683612c1a565b86526146ba61469683612c30565b88525190612d31565b905190612d31565b9052565b6006546001600160a01b03906146e490610785565b1615801561476e575b612b9e57601b546146fe6000601b55565b60008061470c600654610785565b60405163c6233ff160e01b602082019081526024820186905290839061473f81604481015b03601f1981018352826108c5565b51925af161474b61454b565b501561436e57612b9e9061476361197c605454610785565b6143cc600654610785565b50601b54156146ed565b601d5415612b9e5761478b60295461317d565b4310612b9e5761479a43602955565b601d54678ac7230489e80000116148215760008051602062005a2f8339815191526143aa601d546148176148126147d361469684612c5e565b6147f66143956147e561469684612c47565b926147f08482612d31565b96612d31565b61480a61480585601e546131aa565b601e55565b6051546131aa565b605155565b61439a6000602a55565b602a541561487b575b614835602a5461318c565b42101561483e57565b60008051602062005a2f8339815191526143aa601d5461481761481261487061486961469685612c47565b8094612d31565b926147f66000601d55565b61488442602a55565b61482a565b614894600554610785565b6001600160a01b0381161561329357601e549081156132a457816148c960009384936148c461197c605454610785565b614437565b6148d36000601e55565b6148de600554610785565b90826040516149078161473160208201956314c09ad360e01b8752602483019190602083019252565b51925af161491361454b565b501561492257612b9e42604655565b60405162461bcd60e51b815260206004820152600d60248201526c14d15515131157d19052531151609a1b6044820152606490fd5b614963612d8882610bf0565b8015614adc575b8015614aca575b8015614ab8575b614ab257602d548015614a8e5761498e82610d03565b548015614a9c575b6149b49180821115614a9557505b6149ad83610d7a565b5490614aee565b908115614a8e576149c481610b79565b548015613cfe578260646149e1826149db86610d7a565b546131aa565b10614a735750915b6149fd6149f583610d7a565b9182546131aa565b9055614a0d600460095417600955565b614a17828261353c565b614a2660041960095416600955565b7fc03f12425768299fe839696a84577384499b39ac70e7cccc7cb889f2ad7a5a75614a6d614a5383610d7a565b546040516001600160a01b03909416939182918683611a84565b0390a290565b612e9090614a8092612ce9565b91826149e957505050600090565b5050600090565b90506149a4565b50614aa682610b79565b5415614a8e5780614996565b50600090565b50614ac5612d8882610c3e565b614978565b50614ad7612d8882610c24565b614971565b50614ae9612d8882610c8c565b61496a565b8015614a8e576202a300810180821161239357421115614a8e574203428111612393576202a2ff198101908111612393576201518090048015614b6c575b614b4281614b3c614b489361319c565b90612ce9565b60011c90565b9060648211614b63575b80821115614a8e5761235291612d31565b60649150614b52565b506001614b2c565b60068110156123a557603f0190600090565b614b8e614d77565b9080156132a457614ba1614ba692612c74565b612d12565b603b5415614cdf57603b5443111561329357603c54614c3a918082614c9b575b509050614c2c614c1c614c16614c0f60ff614be360455460ff1690565b614c0987614bf083614b74565b90919082549060031b91821b91600019901b1916179055565b1661319c565b6006900690565b60ff1690565b60ff1660ff196045541617604555565b614c3543603b55565b603c55565b614c496125cd603d5460ff1690565b80614c8e575b614c5557565b614c67600160ff19603d541617603d55565b7f7facd5a4cc79b4d9a41bfa74d8dd0812d4f600fc300cb4df723bc45d6d63f279600080a1565b506006603e541015614c4f565b614cb3612e90614cad612e9086612cbd565b94612cd3565b9083811115614cc7575050505b8038614bc6565b8192935010614cd7575b50614cc0565b905038614cd1565b60005b60068110614d175750614d0890614cf96006603e55565b614c2c60ff1960455416604555565b614c4f6125cd603d5460ff1690565b806128f983614bf0614d2894614b74565b614ce2565b51906001600160701b038216820361076257565b9081606091031261076257614d5581614d2d565b916040614d6460208401614d2d565b92015163ffffffff811681036107625790565b614d8861197c61197c605754610785565b90604051630240bc6b60e21b8152606081600481865afa9283156111eb576000918294614e26575b50602060049160405192838092630dfe168160e01b82525afa9081156111eb57600091614e08575b506001600160a01b03163003614df8576001600160701b03908116921690565b6001600160701b03928316921690565b614e20915060203d8111612bdf57612bd081836108c5565b38614dd8565b600491945060209250614e4f9060603d8111614e5b575b614e4781836108c5565b810190614d41565b50929092949150614db0565b503d614e3d565b614e6a614d77565b81158015614f5f575b613cfe57614eb46020614e8d61197c61197c605454610785565b614e98605754610785565b9060405180809581946370a0823160e01b835260048301610791565b03915afa9081156111eb57600091614f41575b5081811115614f385781614eda91612d31565b614ee883614ba18487612ce9565b8015614f2e57614f06612e90614f00612e9084612c91565b92612ca7565b908210918215614f24575b5050613cfe57614f209261506c565b5090565b1190503880614f11565b5050505050600090565b50505050600090565b614f59915060203d8111613ccc57613cbd81836108c5565b38614ec7565b508015614e73565b90600091614f73614d77565b9050614f8661197c61197c605454610785565b91614f92605754610785565b9160405180946370a0823160e01b825260209586918180614fb68960048301610791565b03915afa9081156111eb5760009161504f575b501115614fd557505050565b6040516318160ddd60e01b81529394509192909183826004816001600160a01b0387165afa9182156111eb5761502061502c936150269261235297600092615032575b505083612ce9565b93610b79565b54612d31565b90612d12565b6150489250803d10613ccc57613cbd81836108c5565b3880615018565b6150669150853d8711613ccc57613cbd81836108c5565b38614fc9565b6000926004602061508461197c61197c605754610785565b6040516318160ddd60e01b815292839182905afa9081156111eb57600091615114575b508115615107576150bc82614ba18686612ce9565b93816150e2575050506150d56150da916150df93612ce9565b615132565b612d21565b91565b816150fb614ba192614ba161510196956150df99612ce9565b94612ce9565b9061518c565b5050505050600090600090565b61512c915060203d8111613ccc57613cbd81836108c5565b386150a7565b906000600383111561517f575081600181811c8181018091116123935791905b84831061515e57505050565b91935090838015612d1c5780830490810180911161239357811c9190615152565b9161518657565b60019150565b9080821015615199575090565b905090565b6005549091906001600160a01b039081163303610aa6578115613472576151ec916151e7918416600052602e60205260406000206151dd8282546131aa565b9055602f546131aa565b602f55565b6151fb6125cd612d8883610e25565b6152025750565b61276b81615212612b9e93612556565b610e25565b61dead600090815260205260008051602062005a6f8339815191525461523b610b2d565b54908181018082116123935780156134725760011c91828211156152c0575061526c9161526791612d31565b613762565b61527d615278426152ea565b603955565b7f1b74b18b9514ee657221984e5fa7fce353871ae28b1538a2c385cafe7b04b6d96152a6610b5b565b546152af610b2d565b54906143aa60405192839283611a84565b90508181116152d1575b505061526c565b6152e3916152de91612d31565b613710565b38806152ca565b61708081018082116123935762015180900681039081116123935790565b615316600160095417600955565b61531f30610b79565b54801561546457615331605454610785565b6040516370a0823160e01b808252602093918481806153533060048301610791565b03816001600160a01b0388165afa9283156111eb5785916000946154ae575b506153ce92939461538a61197c61197c600754610785565b604051635fdae95360e01b81523060048201526001600160a01b03909216602483015260448201929092526000606482018190529093849291839182906084820190565b03925af180156111eb57615491575b506153e86000602155565b826153fa61197c61197c605454610785565b604051928352829081806154113060048301610791565b03915afa9081156111eb5761542f93600092615474575b5050612d31565b801561546457614015615444916025546131aa565b61544c6142a1565b61545542602255565b612b9e60011960095416600955565b50612b9e60011960095416600955565b61548a9250803d10613ccc57613cbd81836108c5565b3880615428565b6154a790843d8611613ccc57613cbd81836108c5565b50386153dd565b6153ce9394506154ca90833d8511613ccc57613cbd81836108c5565b9392615372565b602154801561329357600160095416613293576207a1205a1061329357615504680ad78ebc5ac6200000916138c1614d77565b101561550c57565b612b9e615308565b60ff603d54161561557457603f5460015b60068110615531575090565b8161553b82614b74565b919054600392831b1c10615559575b5061555490612384565b615525565b81925061556861555492614b74565b9054911b1c919061554a565b61557c614d77565b8115614a8e57613cfa90612c74565b604a546001600160a01b03168015610762576000808092368280378136915af43d82803e156155b8573d90f35b3d90fdfe60808060405234610016576103d6908161001c8239f35b600080fdfe6080604081815260049182361015610022575b505050361561002057600080fd5b005b600092833560e01c918263125bfb66146101cb57508163184b9559146100b0575080636be13c921461008857638da5cb5b1461005e5780610012565b34610084578160031936011261008457905490516001600160a01b039091168152602090f35b5080fd5b503461008457816003193601126100845760015490516001600160a01b039091168152602090f35b919050346101c75760603660031901126101c7576100cc61031e565b916100d5610339565b6001600160a01b036044358181169392908490036101c35760015460ff8160a01c166101915787546001600160a01b031916851788556001600160a81b03191690821617600160a01b17600155835163095ea7b360e01b815291820192909252600019602482015292602091849160449183918891165af1908115610188575061015d575080f35b61017d9060203d8111610181575b610175818361034f565b810190610388565b5080f35b503d61016b565b513d84823e3d90fd5b855162461bcd60e51b8152602081860152600c60248201526b1053149150511657d253925560a21b6044820152606490fd5b8680fd5b8280fd5b909291503461031a57606036600319011261031a576101e861031e565b6101f0610339565b6001546001600160a01b0393604435939185163314801561030e575b156102e2575083169286929190846102ae5750829350829182915af13d156102a9573d6001600160401b03811161029657825190610254601f8201601f19166020018361034f565b81528460203d92013e5b1561026857505080f35b906020606492519162461bcd60e51b8352820152600860248201526710939097d190525360c21b6044820152fd5b634e487b7160e01b855260418452602485fd5b61025e565b926020946044938751988996879563a9059cbb60e01b8752169085015260248401525af1908115610188575061015d575080f35b62461bcd60e51b8152602087820152600860248201526709c9ea8be82aaa8960c31b6044820152606490fd5b5084885416331461020c565b8380fd5b600435906001600160a01b038216820361033457565b600080fd5b602435906001600160a01b038216820361033457565b601f909101601f19168101906001600160401b0382119082101761037257604052565b634e487b7160e01b600052604160045260246000fd5b9081602091031261033457518015158103610334579056fea26469706673582212209ff6a4a71713e11d36586a99f40c05251aa8975e9f0197b5338b2df6a7d37b7464736f6c634300081300334a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b846bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c166de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a09011df491316f14931039edfd4f8964c9a443b862f02d4c7611d18c2bc4e6ff6979e39dc9055eb3a039f535355a237af25d2fbee7c191e6f241230987ef52ec79cddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef44ad89ba62b98ff34f51403ac22759b55759460c0bb5521eb4b6ee3cff49cf83a26469706673582212205715d65010455f214a29e6775969e8d7a9e685bd1aa89115b7de242dd207a78864736f6c63430008130033

Deployed Bytecode

0x60806040526004361015610015575b3661558b57005b60003560e01c80630307bc001461075257806303fd2a451461074d57806305fe13fc1461074857806306fdde0314610743578063095ea7b31461073e5780630fc6a11c14610739578063127ac4e01461073457806317b67bff1461072f57806318160ddd1461063557806318a6bc321461072a5780631cc8e626146107255780631f1cc015146107205780632224768d1461071b57806323b872dd14610716578063255a2e541461071157806325cf72d11461070c5780632cd75952146107075780632d5537b0146107025780632d7c3bfa146106fd5780632de7204e146106f85780632f48ab7d146106f3578063313ce567146106ee57806331f438c2146106e957806333beb1ba146106e457806335630eda14610540578063357cc5db146106df57806336b19cd7146106da5780633810df90146106d557806338e539fe146106d05780633b61b8fe146106cb5780633b85db47146106c65780633baa4ebc146106c15780633d4bc713146106bc57806342a82b4f146106b7578063444486b2146106b257806345697add146106ad5780634ada218b146106a85780634dde09b6146106a35780634ece7c061461069e5780634f94f16c146105cc5780635465178f14610699578063567ff369146106945780635bd713b51461068f5780635c2da7cd146105405780635c975abb1461068a578063627e4ab61461068557806365cf7c9b14610680578063677967611461067b5780636be13c92146106765780636e963ace146106715780636f741f2a1461066c57806370a0823114610667578063771a3a1d1461066257806377a405a61461065d5780637a955537146106585780637f79496c146106535780638696d1fe1461064e5780638c1f2fcc146106495780638c689788146106445780638cd877861461063f5780638f4586831461063a578063902d55a514610635578063935cac391461063057806395d89b411461062b578063979ab6ff1461062657806397d039ad1461062157806398d5fdca1461061c5780639aff712a146106175780639d0b31bf146106125780639f0d7eb81461060d578063a7b9a5f914610608578063a7c4b5d514610603578063a8aa1b31146105fe578063a9059cbb146105f9578063ab622d9a146105f4578063abdc688b146105ef578063ae72bd7e146105ea578063b206e81914610540578063b29c662a146105e5578063b4ee3cbf146105e0578063b970ce4e146105db578063bb0dc9db14610540578063bc945e1c146105d6578063befcefbe146105d1578063bf0d8212146105cc578063c45a0155146105c7578063c56da4b8146105c2578063c58fb143146105bd578063c674fff4146105b8578063c68890c3146105b3578063c7aaaa75146105ae578063c867e210146105a9578063cf5b67fc146105a4578063d232c2201461059f578063d5bc13be1461059a578063d76a39b114610595578063d937ed3714610590578063d9ca21d51461058b578063da73157d14610586578063dd4f3c4614610581578063dd62ed3e1461057c578063dfaf734a14610577578063dfff8d6314610572578063e980f8521461056d578063e9e5cf7314610568578063ea9b717e14610563578063ec4515dd1461055e578063ec7ef6f614610559578063eee2bfa014610554578063f3d7d2821461054f578063f76a105a14610540578063f887ea401461054a578063fab46cd614610545578063fb5189ac14610540578063fd8565b91461053b578063fdcd987d14610536578063fe2d5af5146105315763fe575a870361000e576122c0565b61229f565b61225d565b612234565b611140565b61220b565b6121e2565b6121a0565b612185565b612165565b61211b565b6120f2565b6120d4565b612077565b612057565b612039565b611fe6565b611fc8565b611f7e565b611f60565b611f44565b611f02565b611edf565b611ebc565b611e93565b611e73565b611e56565b611e14565b611df7565b611dd9565b611dbd565b611d94565b6114d6565b611d76565b611d52565b611d2c565b611d03565b611cda565b611cbc565b611c9e565b611bfb565b611bd1565b611ba8565b611b85565b611b67565b611b1d565b611b00565b611abe565b611a95565b611a66565b611a48565b611a0c565b61195f565b610abf565b61191d565b6118ff565b6118e1565b6118c3565b611881565b61180b565b6117c1565b61176e565b611750565b61168b565b611649565b611620565b6115f7565b6115b5565b611597565b611577565b611551565b611533565b611515565b6114f9565b611499565b611479565b611453565b61141c565b6113f9565b611318565b6112e5565b6112c5565b6112a1565b611283565b611265565b611249565b611220565b61115e565b611123565b6110ff565b6110e3565b6110ba565b61107a565b61105c565b611033565b611015565b610ff7565b610fb5565b610f1f565b610e93565b610e56565b610b0f565b610ae6565b610a48565b610a2a565b610a01565b610984565b610931565b6107fe565b6107a4565b610767565b600091031261076257565b600080fd5b34610762576000366003190112610762576020602f54604051908152f35b6001600160a01b031690565b6001600160a01b03909116815260200190565b3461076257600036600319011261076257602060405161dead8152f35b90815180825260208080930193019160005b8281106107e1575050505090565b83516001600160a01b0316855293810193928101926001016107d3565b34610762576000806003193601126108795760405180918260325480845260208094019060328452848420935b8582821061085a57505050610842925003836108c5565b6108566040519282849384528301906107c1565b0390f35b85546001600160a01b031684526001958601958895509301920161082b565b80fd5b634e487b7160e01b600052604160045260246000fd5b6001600160401b0381116108a557604052565b61087c565b604081019081106001600160401b038211176108a557604052565b601f909101601f19168101906001600160401b038211908210176108a557604052565b6020808252825181830181905290939260005b82811061091d57505060409293506000838284010152601f8019910116010190565b8181018601518482016040015285016108fb565b3461076257600036600319011261076257610856604051610951816108aa565b600981526820aa26902a37b5b2b760b91b6020820152604051918291826108e8565b6001600160a01b0381160361076257565b34610762576040366003190112610762576004356109a181610973565b60243590336000526001602052816109bd826040600020610e3f565b556040519182526001600160a01b03169033907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590602090a3602060405160018152f35b34610762576000366003190112610762576007546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020602654604051908152f35b3461076257600036600319011261076257303303610aa657680ad78ebc5ac6200000610a7e610a75614d77565b90602154613ce9565b10610a8d57610a8b615308565b005b6040516321c38c0960e21b8152600b6004820152602490fd5b6040516321c38c0960e21b815260086004820152602490fd5b346107625760003660031901126107625760206040516b12bda5c60552e7c7a80000008152f35b34610762576000366003190112610762576008546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020603854604051908152f35b600160009081526020527fada5013122d395ba3c54772283fb069b10426056ef8ca54750cb9bb552a59e7d90565b61dead600090815260205260008051602062005a6f83398151915290565b6001600160a01b0316600090815260208190526040902090565b61dead600052600a6020527f20677881080440a9b3c87e826370bb5d9c2f74efd4dede686d52d77a6a09f8bb90565b6001600052600a6020527fbbc70db1b6c7afd11e79c0fb0051300458f1a3acb8ee9789d9b6b26c61ad9bc790565b6001600160a01b03166000908152600a6020526040902090565b6001600160a01b03166000908152600f6020526040902090565b6001600160a01b03166000908152600d6020526040902090565b6001600160a01b03166000908152600e6020526040902090565b6001600160a01b0316600090815260106020526040902090565b6001600160a01b03166000908152600b6020526040902090565b6001600160a01b03166000908152600c6020526040902090565b6001600052602b6020527ffcc3d43705633578a5e8f1b6d6f38d08eb8cb891174edcc94b1a54972a1aebbd90565b61dead600052602b6020527fcb067d08c3b0752a639a17b312edc0e4384bd60a697642bbd8bdd8260a31a34790565b6001600160a01b03166000908152602b6020526040902090565b6001600052602c6020527fa1f88ee5f5d946e3956f6291445d84cd8aea2bf6c57f4f4ac349f7a33888264390565b61dead600052602c6020527fe59ee55b272e0a0ceadcbcef22910224ebf112343a13eb9b581203f0fbdd8e0690565b6001600160a01b03166000908152602c6020526040902090565b600160005260376020527f8e0cc0f1f0504b4cb44a23b328568106915b169e79003737a7b094503cdbeeb090565b61dead60005260376020527f1403828e2002138cf2c0587ee09995d5d8f06540752d9ee5757863861cf6948690565b6001600160a01b0316600090815260376020526040902090565b6001600160a01b0316600090815260356020526040902090565b6001600160a01b0316600090815260336020526040902090565b9060018060a01b0316600052602052604060002090565b3461076257602036600319011261076257600435610e7381610973565b60018060a01b0316600052602e6020526020604060002054604051908152f35b3461076257602036600319011261076257600435610eb081610973565b6001600160a01b031660009081526010602052604090205460ff1680610ede575b6020906040519015158152f35b50601160205260406000205460ff1615610ed1565b606090600319011261076257600435610f0b81610973565b90602435610f1881610973565b9060443590565b3461076257610f2d36610ef3565b9060018060a01b03831692836000526001602052610f5060406000203390610e3f565b549360018501610f71575b50610f669350612d3e565b602060405160018152f35b838510610f9c57610f66948491600052600160205203610f95336040600020610e3f565b5538610f5b565b6040516321c38c0960e21b815260076004820152602490fd5b3461076257602036600319011261076257600435610fd281610973565b60018060a01b0316600052600f602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576020601f54604051908152f35b34610762576000366003190112610762576020605154604051908152f35b3461076257600036600319011261076257604a546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020602954604051908152f35b346107625760203660031901126107625760043561109781610973565b60018060a01b0316600052601a602052602060ff60406000205416604051908152f35b34610762576000366003190112610762576054546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257602060405160128152f35b3461076257600036600319011261076257602060405168056bc75e2d631000008152f35b346107625760003660031901126107625760206040516103208152f35b34610762576000366003190112610762576020604051620151808152f35b346107625760203660031901126107625760043561117b81610973565b600090338252601060205260ff60408320541615801561120d575b6111f4576005546001600160a01b0390811691839190833b156111f05760249083604051958694859363357cc5db60e01b85521660048401525af180156111eb576111df575080f35b6111e890610892565b80f35b612355565b8280fd5b6040516321c38c0960e21b815260036004820152602490fd5b50601160205260ff604083205416611196565b34610762576000366003190112610762576053546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257602060405160018152f35b34610762576000366003190112610762576020603a54604051908152f35b34610762576000366003190112610762576020603c54604051908152f35b34610762576000366003190112610762576020604051680ad78ebc5ac62000008152f35b3461076257600036600319011261076257303303610aa657610a8b6154d1565b3461076257600036600319011261076257602060405160058152f35b6001600160401b0381116108a55760051b60200190565b346107625760e03660031901126107625760043561133581610973565b60243561134181610973565b60443561134d81610973565b60643561135981610973565b6084359061136682610973565b60a4359261137384610973565b60c435946001600160401b03861161076257366023870112156107625785600401359661139f88611301565b966113ad60405198896108c5565b88885260209860248a8a019160051b8301019136831161076257602401905b8282106113e057505050610a8b97506125a9565b8a809183356113ee81610973565b8152019101906113cc565b3461076257600036600319011261076257602060ff603d54166040519015158152f35b346107625760203660031901126107625760043561143981610973565b303303610aa65761144b602091614957565b604051908152f35b3461076257600036600319011261076257602060ff60475460101c166040519015158152f35b3461076257600036600319011261076257303303610aa657610a8b614889565b34610762576020366003190112610762576004356114b681610973565b60018060a01b0316600052602b6020526020604060002054604051908152f35b34610762576000366003190112610762576020604051678ac7230489e800008152f35b3461076257600036600319011261076257602060405160068152f35b34610762576000366003190112610762576020601254604051908152f35b34610762576000366003190112610762576020602554604051908152f35b3461076257600036600319011261076257602060ff60475460081c166040519015158152f35b3461076257600036600319011261076257303303610aa657610a8b6142a1565b34610762576000366003190112610762576020602d54604051908152f35b34610762576020366003190112610762576004356115d281610973565b60018060a01b03166000526011602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576058546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576002546040516001600160a01b039091168152602090f35b346107625760203660031901126107625760043561166681610973565b60018060a01b0316600052600d602052602060ff604060002054166040519015158152f35b34610762576020366003190112610762576004356116a881610973565b6116b3605754610785565b6001600160a01b0381811690831681149081611746575b5080611737575b6116f3575b6108566116e283610b79565b546040519081529081906020820190565b60525443146116d65761170e611707614d77565b5091610b79565b541061171a57386116d6565b6040516321c38c0960e21b8152600e6004820152602490fd5b0390fd5b5060475460181c60ff166116d1565b90503314386116ca565b34610762576000366003190112610762576020604854604051908152f35b346107625760203660031901126107625760043561178b81610973565b60018060a01b0316600052602c6020526020604060002054604051908152f35b634e487b7160e01b600052603260045260246000fd5b3461076257602036600319011261076257600435603654811015610762576036600052600080516020620059af83398151915201546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257610140601b54601c54601d5490601e546051546025546021549161183e615514565b93611847614d77565b979096604051998a5260208a015260408901526060880152608087015260a086015260c085015260e0840152610100830152610120820152f35b346107625760203660031901126107625760043561189e81610973565b60018060a01b03166000526037602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576020601d54604051908152f35b34610762576000366003190112610762576020604654604051908152f35b34610762576000366003190112610762576020602a54604051908152f35b346107625760203660031901126107625760043561193a81610973565b60018060a01b0316600052600c602052602060ff604060002054166040519015158152f35b346107625761196d36610ef3565b9061198161197c600454610785565b610785565b331415806119f5575b806119de575b610aa6576001600160a01b038316600181141590816119d1575b506119b857610a8b926137b4565b6040516321c38c0960e21b815260066004820152602490fd5b61dead91501415386119aa565b506119ed61197c600654610785565b331415611990565b50611a0461197c600554610785565b33141561198a565b3461076257600036600319011261076257610856604051611a2c816108aa565b600381526241544d60e81b6020820152604051918291826108e8565b346107625760003660031901126107625760206040516202a3008152f35b34610762576000366003190112610762576020601c54604051908152f35b908152602081019190915260400190565b3461076257600036600319011261076257611aae614d77565b9061085660405192839283611a84565b3461076257602036600319011261076257600435611adb81610973565b60018060a01b03166000526033602052602060ff604060002054166040519015158152f35b3461076257600036600319011261076257602060405161024c8152f35b3461076257602036600319011261076257600435603454811015610762576034600052600080516020620059cf83398151915201546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020601b54604051908152f35b3461076257602036600319011261076257303303610aa657610a8b600435614300565b34610762576000366003190112610762576057546040516001600160a01b039091168152602090f35b3461076257604036600319011261076257610f66600435611bf181610973565b6024359033612d3e565b3461076257602036600319011261076257600435611c1881610973565b6058546001600160a01b039081163303611c8557811615611c5457604a80546001600160a01b0319166001600160a01b03909216919091179055005b60405162461bcd60e51b81526020600482015260096024820152682d22a927afa0a2222960b91b6044820152606490fd5b6040516321c38c0960e21b815260016004820152602490fd5b34610762576000366003190112610762576020602154604051908152f35b34610762576000366003190112610762576020602854604051908152f35b34610762576000366003190112610762576006546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576003546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257602060ff60475460181c166040519015158152f35b34610762576000366003190112610762576020604051683635c9adc5dea000008152f35b34610762576000366003190112610762576020603054604051908152f35b34610762576000366003190112610762576056546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257602060405160c88152f35b34610762576000366003190112610762576020601e54604051908152f35b346107625760003660031901126107625760208054604051908152f35b3461076257602036600319011261076257600435611e3181610973565b60018060a01b03166000526035602052602060ff604060002054166040519015158152f35b346107625760003660031901126107625760206040516101e08152f35b3461076257600036600319011261076257303303610aa657610a8b615217565b3461076257604036600319011261076257610a8b600435611eb381610973565b6024359061519e565b3461076257600036600319011261076257602060ff604754166040519015158152f35b3461076257600036600319011261076257602060405167120a871cc00200008152f35b3461076257602036600319011261076257600435611f1f81610973565b60018060a01b0316600052600a602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576020604051601e8152f35b34610762576000366003190112610762576020603954604051908152f35b346107625760203660031901126107625760043560325481101561076257603260005260008051602062005a0f83398151915201546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576020603b54604051908152f35b3461076257604036600319011261076257602061203060043561200881610973565b6024359061201582610973565b6001600160a01b031660009081526001845260409020610e3f565b54604051908152f35b34610762576000366003190112610762576020602254604051908152f35b3461076257600036600319011261076257303303610aa657610a8b614b86565b346107625760003660031901126107625760e060225460ff60305460465460395460295491604754936040519687526020870152604086015260608501526080840152818160081c16151560a084015260101c16151560c0820152f35b34610762576000366003190112610762576020603154604051908152f35b34610762576000366003190112610762576005546040516001600160a01b039091168152602090f35b3461076257602036600319011261076257600435601354811015610762576013600052600080516020620059ef83398151915201546040516001600160a01b039091168152602090f35b3461076257600036600319011261076257303303610aa657610a8b614778565b3461076257600036600319011261076257602061144b615514565b34610762576020366003190112610762576004356121bd81610973565b60018060a01b0316600052600e602052602060ff604060002054166040519015158152f35b34610762576000366003190112610762576055546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576004546040516001600160a01b039091168152602090f35b34610762576000366003190112610762576059546040516001600160a01b039091168152602090f35b346107625760203660031901126107625760043561227a81610973565b60018060a01b03166000526010602052602060ff604060002054166040519015158152f35b3461076257600036600319011261076257602060ff60455416604051908152f35b34610762576020366003190112610762576004356122dd81610973565b60018060a01b0316600052600b602052602060ff604060002054166040519015158152f35b1561230957565b60405162461bcd60e51b815260206004820152600c60248201526b1053149150511657d253925560a21b6044820152606490fd5b90816020910312610762575161235281610973565b90565b6040513d6000823e3d90fd5b805460ff19166001179055565b634e487b7160e01b600052601160045260246000fd5b60001981146123935760010190565b61236e565b8051156123a55760200190565b6117ab565b8051600110156123a55760400190565b80518210156123a55760209160051b010190565b601354600160401b8110156108a55760018101806013558110156123a5576013600052600080516020620059ef8339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b603654600160401b8110156108a55760018101806036558110156123a5576036600052600080516020620059af8339815191520180546001600160a01b0319166001179055565b603654600160401b8110156108a55760018101806036558110156123a5576036600052600080516020620059af8339815191520180546001600160a01b03191661dead179055565b603654600160401b8110156108a55760018101806036558110156123a5576036600052600080516020620059af8339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b603454600160401b8110156108a55760018101806034558110156123a5576034600052600080516020620059cf8339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b603254600160401b8110156108a55760018101806032558110156123a557603260005260008051602062005a0f8339815191520180546001600160a01b0319166001600160a01b03909216919091179055565b91926126416126639295979896946125d66125d16125cd60595460ff9060a01c1690565b1590565b612302565b6059805460ff60a01b1916600160a01b179055605480546001600160a01b0319166001600160a01b038716179055605580546001600160a01b0319166001600160a01b038916179055600280546001600160a01b0319166001600160a01b0392909216919091179055565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b605880546001600160a01b0319166001600160a01b03871617905560405163c45a015560e01b81526001600160a01b0395906020908181600481898c165afa9081156111eb57600091612be6575b50605680546001600160a01b0319166001600160a01b0383161790556040516364e329cb60e11b81523060048201526001600160a01b038516602482015290829082908160008c82604481010393165af19081156111eb5761273992600092612bb9575b5050605780546001600160a01b0319166001600160a01b0392909216919091179055565b60008052600a6020526127707f13da86008ba1c6922daee3e07db95305ef49ebced9f5467a0b8613fcc6b343e3612361565b612361565b61277b61276b610b93565b61278661276b610bc2565b61279261276b30610bf0565b60008052600f6020526127c47ff4803e074bd026baaf6ed2e288c9515f68c72fb7216eebdd7cae1718a53ec375612361565b61dead600052600f6020526127f87f99629f56119585bf27511b6b7d295dffb54757453fcc3dabcf51d92028301f10612361565b6001600052600f60205261282b7f169f97de0d9a84d840042b17d3c6b9638b3d6fd9024c9eb0c7a306a17b49f88f612361565b61283761276b30610c0a565b61284d61276b612848605754610785565b610c24565b61285961276b85610c3e565b61286f61276b61286a605754610785565b610c0a565b60005b875181101561290357806128a461276b61289f6128926128fe958d6123ba565b516001600160a01b031690565b610c58565b6128b96128b4612892838c6123ba565b6123ce565b6128f960ff82166128ea6128d0612892858e6123ba565b6001600160a01b03166000908152601a6020526040902090565b9060ff1660ff19825416179055565b612384565b612872565b50919395612915909591939551601255565b61293261292185610b79565b6b12bda5c60552e7c7a80000009055565b600060008051602062005a4f833981519152604051928616928061296681906b12bda5c60552e7c7a8000000602083019252565b0390a361297242602255565b61297b42602855565b61298443602955565b61298d42603955565b61299642603055565b61299f42603155565b6129a842604655565b6129c0630100000063ff000000196047541617604755565b6129ca6003604855565b3060009081526001602052604090206129ef906129e8908690610e3f565b6000199055565b6040516103f28082016001600160401b038111838210176108a5578291620055bd833903906000f080156111eb57600880546001600160a01b0319166001600160a01b03909216919091179055612a4a61197c600854610785565b803b156107625760405163184b955960e01b81526001600160a01b03848116600483015283166024820152306044820152906000908290606490829084905af19485156111eb57612ac8612b6c94612aea93612b9e98612ba0575b50604b80546001600160a01b0319166001600160a01b0392909216919091179055565b604c80546001600160a01b0319166001600160a01b0392909216919091179055565b612b1a612af8605654610785565b604d80546001600160a01b0319166001600160a01b0392909216919091179055565b612b4a612b28605754610785565b604e80546001600160a01b0319166001600160a01b0392909216919091179055565b604f80546001600160a01b0319166001600160a01b0392909216919091179055565b605080546001600160a01b0319169055605380546001600160a01b0319166001600160a01b0392909216919091179055565b565b80612bad612bb392610892565b80610757565b38612aa5565b612bd89250803d10612bdf575b612bd081836108c5565b81019061233d565b3880612715565b503d612bc6565b612bfd9150823d8411612bdf57612bd081836108c5565b386126b1565b906102589182810292818404149015171561239357565b9060648202918083046064149015171561239357565b906101f49182810292818404149015171561239357565b906103209182810292818404149015171561239357565b9060c882029180830460c8149015171561239357565b90670de0b6b3a76400009182810292818404149015171561239357565b90605f820291808304605f149015171561239357565b9060698202918083046069149015171561239357565b9060828202918083046082149015171561239357565b9060468202918083046046149015171561239357565b8181029291811591840414171561239357565b634e487b7160e01b600052601260045260246000fd5b8115612d1c570490565b612cfc565b6103e71981019190821161239357565b9190820391821161239357565b91906001600160a01b03808416919082156119b85783156119b85783612d6386610b79565b5410610f9c5760475460081c60ff1680613159575b6119b857612d8f612d8886610bf0565b5460ff1690565b61314d5760176009541661314d57612da9612d8886610c72565b801561313b575b61312257612dbd85614957565b6130fb575b811661dead8114806130e6575b15612de057505050612b9e916140bd565b600114806130d1575b15612df9575050612b9e91614190565b612e08612d8885949394610c24565b80156130bf575b15612fe357612e20612d8885610c24565b15612fdd57805b604754612e389060101c60ff161590565b612f14575b50612b9e93612e4e612d8883610c24565b9384612f00575b84612ef6575b5083612ee3575b831580612ed1575b80612ebc575b80612ea7575b1561384057612ea2612e9d612e97612e9060485487612ce9565b6064900490565b85612d31565b613e16565b613840565b50612eb76125cd612d8883610c8c565b612e76565b50612ecc6125cd612d8883610c72565b612e70565b50612ede612d8883610c24565b612e6a565b9250612eee82614e62565b151592612e62565b3214935038612e5b565b9350612f0e612d8833610c3e565b93612e55565b612f20612d8883610c24565b9081612fc9575b81612fbf575b81612fac575b612f3f612d8887610c24565b9182612f99575b159182612f90575b5081612f79575b50612f605738612e3d565b6040516321c38c0960e21b815260096004820152602490fd5b612f8a9150612d886125cd91610c8c565b38612f55565b15915038612f4e565b9150612fa484614f67565b151591612f46565b9050612fb783614e62565b151590612f33565b3285149150612f2d565b9050612fd7612d8833610c3e565b90612f27565b83612e27565b929150612ff18184846137b4565b612ffa83610d03565b5415806130ad575b613082575b61300f615514565b80613021575b50505050612b9e613d06565b61303861304691683635c9adc5dea0000093612ce9565b670de0b6b3a7640000900490565b1015613054575b8080613015565b6000918261306f61307a934261306982610d03565b55610d7a565b554261306982610d03565b55388061304d565b4261308c84610d03565b5561309683610d7a565b54156130075760006130a784610d7a565b55613007565b506130b783610b79565b541515613002565b506130cc612d8882610c24565b612e0f565b506130e16125cd612d8886610c8c565b612de9565b506130f66125cd612d8887610c8c565b612dcf565b61310485610b79565b5480851161311a575b5083612dc2575050505050565b93503861310d565b6040516321c38c0960e21b815260056004820152602490fd5b50613148612d8883610c72565b612db0565b509050612b9e926137b4565b506131696125cd612d8887610c58565b612d78565b906101e0820180921161239357565b9061024c820180921161239357565b9062015180820180921161239357565b906001820180921161239357565b9190820180921161239357565b6001906131c381610b79565b6131ce848254612d31565b90556131d8610b2d565b6131e38482546131aa565b905560008051602062005a4f83398151915260405191838060a01b0316918061321186829190602083019252565b0390a36132226125cd612d88610bc2565b8061337f575b8061336b575b613353575b6132416125cd612d88610bc2565b80613317575b806132db575b6132545750565b61325c610ca6565b5461328857504261326b610ca6565b55613274610d1d565b5461327b57565b6000613285610d1d565b55565b603d5460ff16613296575b50565b61329e615514565b806132a8575b5050565b6130386132bf91683635c9adc5dea0000093612ce9565b10156132c757565b426132d0610ca6565b556000613285610d1d565b506001600052600e6020526133126125cd7fa7c5ba7114a813b50159add3a36832908dc83db71d0b9a24c2ad0f83be958207612d88565b61324d565b506001600052600d60205261334e6125cd7ffd54ff1ed53f34a900b24c5ba64f85761163b5d82d98a47b9bd80e45466993c5612d88565b613247565b61335b612421565b61336661276b610d94565b613233565b5061337a6125cd612d88610d94565b61322e565b50613388610b2d565b541515613228565b90613399610b2d565b6133a4828254612d31565b90556133af82610b79565b6133ba8282546131aa565b90556040518181526001600160a01b03831690819060019060008051602062005a4f8339815191529080602081015b0390a315158080613527575b80613515575b80613500575b6134e6575b806134d1575b806134bc575b806134a7575b613420575050565b61342982610d03565b5461345657504261343982610d03565b5561344381610d7a565b5461344b5750565b613285600091610d7a565b603d5460ff16613464575050565b61346c615514565b80613477575b505050565b61303861348e91683635c9adc5dea0000093612ce9565b10156134975750565b6132856000914261306982610d03565b506134b76125cd612d8884610c3e565b613418565b506134cc6125cd612d8884610c24565b613412565b506134e16125cd612d8884610bf0565b61340c565b6134ef836124b0565b6134fb61276b84610df1565b613406565b506135106125cd612d8885610df1565b613401565b5061351f83610b79565b5415156133fb565b506135376125cd612d8885610bf0565b6133f5565b61dead9061354981610b79565b613554848254612d31565b905561355e610b5b565b6135698482546131aa565b90556040518381526001600160a01b039091169060008051602062005a4f8339815191529080602081015b0390a36135a56125cd612d88610b93565b806136ff575b806136eb575b6136d3575b6135c46125cd612d88610b93565b80613696575b80613659575b6135d75750565b6135df610cd4565b546136085750426135ee610cd4565b556135f7610d4b565b546135fe57565b6000613285610d4b565b603d5460ff166136155750565b61361d615514565b80613626575050565b61303861363d91683635c9adc5dea0000093612ce9565b101561364557565b4261364e610cd4565b556000613285610d4b565b5061dead600052600e6020526136916125cd7ff77e91909e61d18f67b875b2bfcae1f683a8d555e55382e3a6b082e2c59ea57a612d88565b6135d0565b5061dead600052600d6020526136ce6125cd7fdc7fafdc41998a74ecacb8f8bd877011aba1f1d03a3a0d37a2e7879a393b1d6a612d88565b6135ca565b6136db612468565b6136e661276b610dc2565b6135b6565b506136fa6125cd612d88610dc2565b6135b1565b50613708610b5b565b5415156135ab565b613718610b2d565b613723828254612d31565b905561372d610b5b565b6137388282546131aa565b905561dead600160008051602062005a4f8339815191526040518061359486829190602083019252565b61376a610b5b565b613775828254612d31565b905561377f610b2d565b61378a8282546131aa565b9055600161dead60008051602062005a4f8339815191526040518061321186829190602083019252565b60008051602062005a4f833981519152909291926137d181610b79565b6137dc848254612d31565b90556137e784610b79565b6137f28482546131aa565b90556040518381526001600160a01b038581169384939091169180602081016133e9565b90816020910312610762575190565b6001600160a01b039091168152602081019190915260400190565b92919061384f612d8885610c24565b93848061385e612d8885610c24565b958115613ce1578685935b613cd3575b613bac575b50613a66575b613885612d8882610c8c565b613a3e57506138e761389c612e9060485486612ce9565b936138e06138db6138c76138b08885612d31565b936138b9614b86565b6138c1614d77565b91613ce9565b966138d38130886137b4565b6021546131aa565b602155565b83836137b4565b8415613a3757505b678ac7230489e8000082101580613a1b575b6006546001600160a01b039061391690610785565b16908115159081613a13575b5061395b575b50505061393e575b61393657565b612b9e613d06565b613946614778565b61394e613d06565b6139566142a1565b613930565b84156139c5575061397361197c61197c600654610785565b91823b156107625761399f9260009283604051809681958294636695575360e01b845260048401613825565b03925af16139b2575b505b388080613928565b80612bad6139bf92610892565b386139a8565b91823b15610762576139f19260009283604051809681958294636c706f9760e11b845260048401613825565b03925af1613a00575b506139aa565b80612bad613a0d92610892565b386139fa565b905038613922565b42613a2583610d03565b556000613a3183610d7a565b55613901565b90506138ef565b929060009550613a5d945091613a53926137b4565b4261306982610d03565b55612b9e614b86565b613a6f84614f67565b156138795750935090915060046020613a8f61197c61197c605654610785565b604051622fcfcb60e31b815292839182905afa9081156111eb57600091613b8e575b506001600160a01b039081168015159081613b6f575b508015613b50575b8015613b33575b61312257613ae6612d8883610c8c565b15613af55750613936926137b4565b90613b22837f7bb65d2a35e8a1815efe8e603e65dfaac438d631890c2669944316c08d25c94394956131b7565b6040519384521691602090a2613936565b5073f4c21a1cb819e5f7abe6defde3d118d8f3d61fa73214613ad6565b5073f4c21a1cb819e5f7abe6defde3d118d8f3d61fa781831614613acf565b838316811491508115613b84575b5038613ac7565b9050321438613b7d565b613ba6915060203d8111612bdf57612bd081836108c5565b38613ab1565b9050613bb9578538613873565b50809450613bc793506137b4565b613c0e613bd2614d77565b90506020613be761197c61197c605454610785565b613bf2605754610785565b9060405180809681946370a0823160e01b835260048301610791565b03915afa9081156111eb57678ac7230489e8000092600092613ca3575b5060009181811115613c9c57613c419250612d31565b1015613c80575b613c576125cd612d8883610e0b565b613c65575b50612b9e613d06565b61276b81613c75613c7a93612503565b610e0b565b38613c5c565b42613c8a82610d03565b556000613c9682610d7a565b55613c48565b5050613c41565b613cc591925060203d8111613ccc575b613cbd81836108c5565b810190613816565b9038613c2b565b503d613cb3565b613cdc43605255565b61386e565b868493613869565b90918215613cfe57613cfa91612ce9565b0490565b505050600090565b6004546001600160a01b0390613d1b90610785565b1680613d50575b50613d2e60465461316e565b42101580613d45575b613d3d57565b612b9e614889565b50601e541515613d37565b803b15610762576040516343b20f5960e11b815260036004820152906000908290602490829084905af180156111eb5715613d225780612bad613d9292610892565b38613d22565b60405190606082016001600160401b038111838210176108a55760405260028252604082602036910137565b90608092613dea919695949683526000602084015260a0604084015260a08301906107c1565b6001600160a01b0390951660608201520152565b90816020910312610762575180151581036107625790565b60059004613e22610b2d565b548180159182156140b3575b505061329357613e42600260095417600955565b613e4c8130613390565b613e54613d98565b90613e7130613e6284612398565b6001600160a01b039091169052565b613e7c605454610785565b613e8981613e62856123aa565b613e9761197c600854610785565b916040519384936370a0823160e01b9384865260209586918180613ebe8660048301610791565b03916001600160a01b03165afa9586156111eb57600096614094575b50613eec61197c61197c605554610785565b91823b1561076257613f1b9260009283604051809681958294635c11d79560e01b845242918b60048601613dc4565b03925af180156111eb57614081575b50613f3c61197c61197c605454610785565b91613f4b61197c600854610785565b94604051918252848280613f628960048301610791565b0381875afa80156111eb57613f7f92600091614064575b50612d31565b9182613f9a575b5050505050612b9e60021960095416600955565b6040516323b872dd60e01b81526001600160a01b03959095166004860152306024860152604485018390528390859060649082906000905af19283156111eb576000947fec997f3558959d8bb505856e4e9c2b51cddd13280b4d310f948423b65333269a94614036575b505061401a614015836025546131aa565b602555565b61402960405192839283611a84565b0390a23880808080613f86565b8161405592903d1061405d575b61404d81836108c5565b810190613dfe565b503880614004565b503d614043565b61407b9150863d8811613ccc57613cbd81836108c5565b38613f79565b80612bad61408e92610892565b38613f2a565b6140ac919650853d8711613ccc57613cbd81836108c5565b9438613eda565b1090508138613e2e565b906140cd6125cd603d5460ff1690565b6119b8576140db818361353c565b6004546001600160a01b03906140f090610785565b1691826140fc57505050565b61415792602092600061410d615514565b604051634054b82d60e01b81526001600160a01b0390951660048601526024850192909252670de0b6b3a76400006044850152606484019190915291938492839182906084820190565b03925af19081156111eb57600091614172575b5015610aa657565b61418a915060203d811161405d5761404d81836108c5565b3861416a565b61419c612d8882610c24565b801561428f575b614276576141b66125cd603d5460ff1690565b6119b8576141ce6130386141c8615514565b84612ce9565b6141d883836131b7565b6005546001600160a01b03906141ed90610785565b16806141ff5750505050612b9e613d06565b60405163044f421360e21b81526001600160a01b039390931660048401526024830193909352604482015290602090829060649082906000905af19081156111eb57600091614258575b5015610aa65738808080613015565b614270915060203d811161405d5761404d81836108c5565b38614249565b6040516321c38c0960e21b8152600a6004820152602490fd5b5061429c612d8882610c3e565b6141a3565b602554801561329357680ad78ebc5ac62000008110156142fb5750602654620151808101809111612393574210156142d557565b6142e0602554614300565b6142e86146cf565b6142f0614778565b600060255542602655565b6142e0905b6143aa7f5832bbcb6ff6598fdb2e6a73e2da2488ce3586bafac1c488349afae01d4eef4f9161439a61439560806143368461461b565b805180151580614419575b6143f6575b506020810151801515806143d8575b6143af575b5061437361436e6040830151601b546131aa565b601b55565b61438b6143866060830151601c546131aa565b601c55565b0151601d546131aa565b601d55565b6040519081529081906020820190565b0390a1565b6143d2906143c161197c605454610785565b6143cc600354610785565b90614437565b3861435a565b506003546001600160a01b03906143ee90610785565b161515614355565b6144139061440861197c605454610785565b6143cc600254610785565b38614346565b506002546001600160a01b039061442f90610785565b161515614341565b6144c39160008060405193614471856144636020998a83019763a9059cbb60e01b895260248401613825565b03601f1981018752866108c5565b60018060a01b03169260405194614487866108aa565b8786527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656488870152519082855af16144bd61454b565b9161458a565b805190828215928315614533575b505050156144dc5750565b6084906040519062461bcd60e51b82526004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152fd5b6145439350820181019101613dfe565b3882816144d1565b3d15614585573d906001600160401b0382116108a55760405191614579601f8201601f1916602001846108c5565b82523d6000602084013e565b606090565b919290156145ec575081511561459e575090565b3b156145a75790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156145ff5750805190602001fd5b60405162461bcd60e51b815290819061173390600483016108e8565b604051919060a083016001600160401b038111848210176108a5576040526000835260208301600081526040840191600083526060850190600082526080860193600085528661012c94858402958487041484151715612393576146c36146c3946146c3936127106146cb9904815261469e61469683612c03565b612710900490565b84526146ac61469683612c1a565b86526146ba61469683612c30565b88525190612d31565b905190612d31565b9052565b6006546001600160a01b03906146e490610785565b1615801561476e575b612b9e57601b546146fe6000601b55565b60008061470c600654610785565b60405163c6233ff160e01b602082019081526024820186905290839061473f81604481015b03601f1981018352826108c5565b51925af161474b61454b565b501561436e57612b9e9061476361197c605454610785565b6143cc600654610785565b50601b54156146ed565b601d5415612b9e5761478b60295461317d565b4310612b9e5761479a43602955565b601d54678ac7230489e80000116148215760008051602062005a2f8339815191526143aa601d546148176148126147d361469684612c5e565b6147f66143956147e561469684612c47565b926147f08482612d31565b96612d31565b61480a61480585601e546131aa565b601e55565b6051546131aa565b605155565b61439a6000602a55565b602a541561487b575b614835602a5461318c565b42101561483e57565b60008051602062005a2f8339815191526143aa601d5461481761481261487061486961469685612c47565b8094612d31565b926147f66000601d55565b61488442602a55565b61482a565b614894600554610785565b6001600160a01b0381161561329357601e549081156132a457816148c960009384936148c461197c605454610785565b614437565b6148d36000601e55565b6148de600554610785565b90826040516149078161473160208201956314c09ad360e01b8752602483019190602083019252565b51925af161491361454b565b501561492257612b9e42604655565b60405162461bcd60e51b815260206004820152600d60248201526c14d15515131157d19052531151609a1b6044820152606490fd5b614963612d8882610bf0565b8015614adc575b8015614aca575b8015614ab8575b614ab257602d548015614a8e5761498e82610d03565b548015614a9c575b6149b49180821115614a9557505b6149ad83610d7a565b5490614aee565b908115614a8e576149c481610b79565b548015613cfe578260646149e1826149db86610d7a565b546131aa565b10614a735750915b6149fd6149f583610d7a565b9182546131aa565b9055614a0d600460095417600955565b614a17828261353c565b614a2660041960095416600955565b7fc03f12425768299fe839696a84577384499b39ac70e7cccc7cb889f2ad7a5a75614a6d614a5383610d7a565b546040516001600160a01b03909416939182918683611a84565b0390a290565b612e9090614a8092612ce9565b91826149e957505050600090565b5050600090565b90506149a4565b50614aa682610b79565b5415614a8e5780614996565b50600090565b50614ac5612d8882610c3e565b614978565b50614ad7612d8882610c24565b614971565b50614ae9612d8882610c8c565b61496a565b8015614a8e576202a300810180821161239357421115614a8e574203428111612393576202a2ff198101908111612393576201518090048015614b6c575b614b4281614b3c614b489361319c565b90612ce9565b60011c90565b9060648211614b63575b80821115614a8e5761235291612d31565b60649150614b52565b506001614b2c565b60068110156123a557603f0190600090565b614b8e614d77565b9080156132a457614ba1614ba692612c74565b612d12565b603b5415614cdf57603b5443111561329357603c54614c3a918082614c9b575b509050614c2c614c1c614c16614c0f60ff614be360455460ff1690565b614c0987614bf083614b74565b90919082549060031b91821b91600019901b1916179055565b1661319c565b6006900690565b60ff1690565b60ff1660ff196045541617604555565b614c3543603b55565b603c55565b614c496125cd603d5460ff1690565b80614c8e575b614c5557565b614c67600160ff19603d541617603d55565b7f7facd5a4cc79b4d9a41bfa74d8dd0812d4f600fc300cb4df723bc45d6d63f279600080a1565b506006603e541015614c4f565b614cb3612e90614cad612e9086612cbd565b94612cd3565b9083811115614cc7575050505b8038614bc6565b8192935010614cd7575b50614cc0565b905038614cd1565b60005b60068110614d175750614d0890614cf96006603e55565b614c2c60ff1960455416604555565b614c4f6125cd603d5460ff1690565b806128f983614bf0614d2894614b74565b614ce2565b51906001600160701b038216820361076257565b9081606091031261076257614d5581614d2d565b916040614d6460208401614d2d565b92015163ffffffff811681036107625790565b614d8861197c61197c605754610785565b90604051630240bc6b60e21b8152606081600481865afa9283156111eb576000918294614e26575b50602060049160405192838092630dfe168160e01b82525afa9081156111eb57600091614e08575b506001600160a01b03163003614df8576001600160701b03908116921690565b6001600160701b03928316921690565b614e20915060203d8111612bdf57612bd081836108c5565b38614dd8565b600491945060209250614e4f9060603d8111614e5b575b614e4781836108c5565b810190614d41565b50929092949150614db0565b503d614e3d565b614e6a614d77565b81158015614f5f575b613cfe57614eb46020614e8d61197c61197c605454610785565b614e98605754610785565b9060405180809581946370a0823160e01b835260048301610791565b03915afa9081156111eb57600091614f41575b5081811115614f385781614eda91612d31565b614ee883614ba18487612ce9565b8015614f2e57614f06612e90614f00612e9084612c91565b92612ca7565b908210918215614f24575b5050613cfe57614f209261506c565b5090565b1190503880614f11565b5050505050600090565b50505050600090565b614f59915060203d8111613ccc57613cbd81836108c5565b38614ec7565b508015614e73565b90600091614f73614d77565b9050614f8661197c61197c605454610785565b91614f92605754610785565b9160405180946370a0823160e01b825260209586918180614fb68960048301610791565b03915afa9081156111eb5760009161504f575b501115614fd557505050565b6040516318160ddd60e01b81529394509192909183826004816001600160a01b0387165afa9182156111eb5761502061502c936150269261235297600092615032575b505083612ce9565b93610b79565b54612d31565b90612d12565b6150489250803d10613ccc57613cbd81836108c5565b3880615018565b6150669150853d8711613ccc57613cbd81836108c5565b38614fc9565b6000926004602061508461197c61197c605754610785565b6040516318160ddd60e01b815292839182905afa9081156111eb57600091615114575b508115615107576150bc82614ba18686612ce9565b93816150e2575050506150d56150da916150df93612ce9565b615132565b612d21565b91565b816150fb614ba192614ba161510196956150df99612ce9565b94612ce9565b9061518c565b5050505050600090600090565b61512c915060203d8111613ccc57613cbd81836108c5565b386150a7565b906000600383111561517f575081600181811c8181018091116123935791905b84831061515e57505050565b91935090838015612d1c5780830490810180911161239357811c9190615152565b9161518657565b60019150565b9080821015615199575090565b905090565b6005549091906001600160a01b039081163303610aa6578115613472576151ec916151e7918416600052602e60205260406000206151dd8282546131aa565b9055602f546131aa565b602f55565b6151fb6125cd612d8883610e25565b6152025750565b61276b81615212612b9e93612556565b610e25565b61dead600090815260205260008051602062005a6f8339815191525461523b610b2d565b54908181018082116123935780156134725760011c91828211156152c0575061526c9161526791612d31565b613762565b61527d615278426152ea565b603955565b7f1b74b18b9514ee657221984e5fa7fce353871ae28b1538a2c385cafe7b04b6d96152a6610b5b565b546152af610b2d565b54906143aa60405192839283611a84565b90508181116152d1575b505061526c565b6152e3916152de91612d31565b613710565b38806152ca565b61708081018082116123935762015180900681039081116123935790565b615316600160095417600955565b61531f30610b79565b54801561546457615331605454610785565b6040516370a0823160e01b808252602093918481806153533060048301610791565b03816001600160a01b0388165afa9283156111eb5785916000946154ae575b506153ce92939461538a61197c61197c600754610785565b604051635fdae95360e01b81523060048201526001600160a01b03909216602483015260448201929092526000606482018190529093849291839182906084820190565b03925af180156111eb57615491575b506153e86000602155565b826153fa61197c61197c605454610785565b604051928352829081806154113060048301610791565b03915afa9081156111eb5761542f93600092615474575b5050612d31565b801561546457614015615444916025546131aa565b61544c6142a1565b61545542602255565b612b9e60011960095416600955565b50612b9e60011960095416600955565b61548a9250803d10613ccc57613cbd81836108c5565b3880615428565b6154a790843d8611613ccc57613cbd81836108c5565b50386153dd565b6153ce9394506154ca90833d8511613ccc57613cbd81836108c5565b9392615372565b602154801561329357600160095416613293576207a1205a1061329357615504680ad78ebc5ac6200000916138c1614d77565b101561550c57565b612b9e615308565b60ff603d54161561557457603f5460015b60068110615531575090565b8161553b82614b74565b919054600392831b1c10615559575b5061555490612384565b615525565b81925061556861555492614b74565b9054911b1c919061554a565b61557c614d77565b8115614a8e57613cfa90612c74565b604a546001600160a01b03168015610762576000808092368280378136915af43d82803e156155b8573d90f35b3d90fdfe60808060405234610016576103d6908161001c8239f35b600080fdfe6080604081815260049182361015610022575b505050361561002057600080fd5b005b600092833560e01c918263125bfb66146101cb57508163184b9559146100b0575080636be13c921461008857638da5cb5b1461005e5780610012565b34610084578160031936011261008457905490516001600160a01b039091168152602090f35b5080fd5b503461008457816003193601126100845760015490516001600160a01b039091168152602090f35b919050346101c75760603660031901126101c7576100cc61031e565b916100d5610339565b6001600160a01b036044358181169392908490036101c35760015460ff8160a01c166101915787546001600160a01b031916851788556001600160a81b03191690821617600160a01b17600155835163095ea7b360e01b815291820192909252600019602482015292602091849160449183918891165af1908115610188575061015d575080f35b61017d9060203d8111610181575b610175818361034f565b810190610388565b5080f35b503d61016b565b513d84823e3d90fd5b855162461bcd60e51b8152602081860152600c60248201526b1053149150511657d253925560a21b6044820152606490fd5b8680fd5b8280fd5b909291503461031a57606036600319011261031a576101e861031e565b6101f0610339565b6001546001600160a01b0393604435939185163314801561030e575b156102e2575083169286929190846102ae5750829350829182915af13d156102a9573d6001600160401b03811161029657825190610254601f8201601f19166020018361034f565b81528460203d92013e5b1561026857505080f35b906020606492519162461bcd60e51b8352820152600860248201526710939097d190525360c21b6044820152fd5b634e487b7160e01b855260418452602485fd5b61025e565b926020946044938751988996879563a9059cbb60e01b8752169085015260248401525af1908115610188575061015d575080f35b62461bcd60e51b8152602087820152600860248201526709c9ea8be82aaa8960c31b6044820152606490fd5b5084885416331461020c565b8380fd5b600435906001600160a01b038216820361033457565b600080fd5b602435906001600160a01b038216820361033457565b601f909101601f19168101906001600160401b0382119082101761037257604052565b634e487b7160e01b600052604160045260246000fd5b9081602091031261033457518015158103610334579056fea26469706673582212209ff6a4a71713e11d36586a99f40c05251aa8975e9f0197b5338b2df6a7d37b7464736f6c634300081300334a11f94e20a93c79f6ec743a1954ec4fc2c08429ae2122118bf234b2185c81b846bddb1178e94d7f2892ff5f366840eb658911794f2c3a44c450aa2c505186c166de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a09011df491316f14931039edfd4f8964c9a443b862f02d4c7611d18c2bc4e6ff6979e39dc9055eb3a039f535355a237af25d2fbee7c191e6f241230987ef52ec79cddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef44ad89ba62b98ff34f51403ac22759b55759460c0bb5521eb4b6ee3cff49cf83a26469706673582212205715d65010455f214a29e6775969e8d7a9e685bd1aa89115b7de242dd207a78864736f6c63430008130033

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

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