ETH Price: $4,000.88 (+2.88%)

Token

ERC-20: All-In-One (AI1)
 

Overview

Max Total Supply

100,000,000 AI1

Holders

117

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 9 Decimals)

Balance
0.000006204 AI1

Value
$0.00
0x200c534ffcf4bdc60d360f0f8520350f81f9ee5d
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
AI1

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 12 : ai1Labs.sol
/**
 * 
 * Revolutionizing Trading with AI Innovation and Rewards
 *
 * Website: ai1.wtf
 * 
 * Docs: docs.ai1.wtf
 * 
 * X: x.com/ai1Labs
 * 
 * Telegram: t.me/ai1Labs
 * 
 */
//SPDX-License-Identifier: UNLICENSED

pragma solidity ^0.8.15;

import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/interfaces/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol";

import "./ai1Jackpots.sol";

contract AI1 is Context, IERC20, Ownable {

    event Bought(address indexed buyer, uint256 amount);
    event Sold(address indexed seller, uint256 amount);
    // Constants
    string private constant _name = "All-In-One";
    string private constant _symbol = "AI1";
    // 0, 1, 2
    uint8 private constant _bl = 2;
    // Standard decimals
    uint8 private constant _decimals = 9;
    // 100 mil
    uint256 private constant totalTokens = 100_000_000 * 10**9;

    // Mappings
    mapping(address => uint256) private tokensOwned;
    mapping(address => mapping(address => uint256)) private _allowances;
    mapping(address => uint256) private botBalance;
    struct PendingJackpots {
        uint256 jackpotAmount;
        uint256 taxAmount;
        address triggeringAccount;
    }

    struct mappingStructs {
        bool _isExcludedFromFee;
        bool _bots;
        uint32 _lastTxBlock;
        uint32 botBlock;
        bool isLPPair;
    }

    
    mapping(address => mappingStructs) mappedAddresses;

    // Arrays
    address[] private holders;
    address[] private jackpotExclusions;
    PendingJackpots[] public jackpotsPendingSubmission;
    // Global variables

    // Block of 256 bits
    address payable private _feeAddrWallet1;
    uint32 private openBlock;
    uint32 private transferTax = 0;
    uint32 private taxRatio = 1000;
    // Storage block closed


    // Block of 256 bits
    address private _controller;
    uint32 private maxTxDivisor = 1;
    uint32 private maxWalletDivisor = 1;
    bool private tradingOpen;
    bool private inSwap = false;
    bool private swapEnabled = false;
    bool private cooldownEnabled = false;
    // Storage block closed

    // Block of 256 bits
    address payable private _AI1JackpotCA;
    uint32 maxTaxSellDivisor = 1000;
    bool disableAddToBlocklist = false;
    bool removedLimits = false;
    // 48 bits left

    
    // Block of 256 bits
    uint32 private jackpotRatio = 0;
    uint32 private buyTax = 30000;
    uint32 private sellTax = 30000;
    // Heaps left




    
    IUniswapV2Router02 private uniswapV2Router;

    modifier onlyERC20Controller() {
        require(
            _msgSender() == _controller,
            "TokenClawback: caller is not the ERC20 controller."
        );
        _;
    }

    constructor() Ownable(_msgSender()) {
        // ERC20 controller
        _controller = payable(0x3ca370666Eac2A44E59Ea1118c8C088b4E3618Cc);
        // Marketing 
        _feeAddrWallet1 = payable(0x3ca370666Eac2A44E59Ea1118c8C088b4E3618Cc);
        // 85% to msgSender

        tokensOwned[_msgSender()] = totalTokens*85/100;
        // 10% to 0x60f1E8061495af2D5E1D2e3E10f5f6304937A19F
        tokensOwned[0x60f1E8061495af2D5E1D2e3E10f5f6304937A19F] = totalTokens/10;
        // 5% to 0x3ca370666Eac2A44E59Ea1118c8C088b4E3618Cc, the tax wallet
        tokensOwned[0x3ca370666Eac2A44E59Ea1118c8C088b4E3618Cc] = totalTokens/20;
        // Create the Jackpot CA -  set the bot address
        AI1Jackpots jpca = new AI1Jackpots(_msgSender());
        // Change owner to the msgSender
        jpca.transferOwnership(_msgSender());
        // Stash the address so we can send eth to it
        _AI1JackpotCA = payable(address(jpca));
        // Set the struct values
        // Push all these accounts to excluded
        jackpotExclusions.push(_msgSender());
        jackpotExclusions.push(_AI1JackpotCA);
        jackpotExclusions.push(address(this));
        // Push the 10% and 5% wallets to jackpot exclusions
        jackpotExclusions.push(_feeAddrWallet1);
        jackpotExclusions.push(0x60f1E8061495af2D5E1D2e3E10f5f6304937A19F);
        mappedAddresses[_msgSender()] = mappingStructs({
            _isExcludedFromFee: true,
            _bots: false,
            _lastTxBlock: 0,
            botBlock: 0,
            isLPPair: false
        });
        mappedAddresses[_AI1JackpotCA] = mappingStructs({
            _isExcludedFromFee: true,
            _bots: false,
            _lastTxBlock: 0,
            botBlock: 0,
            isLPPair: false
        });
        mappedAddresses[address(this)] = mappingStructs({
            _isExcludedFromFee: true,
            _bots: false,
            _lastTxBlock: 0,
            botBlock: 0,
            isLPPair: false
        });
        mappedAddresses[_feeAddrWallet1] = mappingStructs({
            _isExcludedFromFee: true,
            _bots: false,
            _lastTxBlock: 0,
            botBlock: 0,
            isLPPair: false
        });
        // 85% transfer emit
        emit Transfer(address(0), _msgSender(), totalTokens*85/100);
        // 10% transfer emit
        emit Transfer(address(0), 0x60f1E8061495af2D5E1D2e3E10f5f6304937A19F, totalTokens/10);
        // 5% transfer emit
        emit Transfer(address(0), 0x3ca370666Eac2A44E59Ea1118c8C088b4E3618Cc, totalTokens/20);
      
    }

    function name() public pure returns (string memory) {
        return _name;
    }

    function symbol() public pure returns (string memory) {
        return _symbol;
    }

    function decimals() public pure returns (uint8) {
        return _decimals;
    }

    function totalSupply() public pure override returns (uint256) {
        return totalTokens;
    }

    function balanceOf(address account) public view override returns (uint256) {
        return abBalance(account);
    }


    function transfer(address recipient, uint256 amount)
        public
        override
        returns (bool)
    {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

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

    function approve(address spender, uint256 amount)
        public
        override
        returns (bool)
    {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()] - amount);
        return true;
    }

    /// @notice Sets cooldown status. Only callable by owner.
    /// @param onoff The boolean to set.
    function setCooldownEnabled(bool onoff) external onlyOwner {
        cooldownEnabled = onoff;
    }


    function createPair() public onlyOwner {
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(
            0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
        );
        IUniswapV2Factory(_uniswapV2Router.factory()).createPair(address(this), _uniswapV2Router.WETH());
    }

    /// @notice Starts trading. Only callable by owner.
    function openTrading() public onlyOwner {
        require(!swapEnabled, "AI1: Trading is already open.");
        IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(
            0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
        );
        uniswapV2Router = _uniswapV2Router;
        _approve(address(this), address(uniswapV2Router), totalTokens);
        address uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).getPair(address(this), _uniswapV2Router.WETH());
        uniswapV2Router.addLiquidityETH{value: address(this).balance}(
            address(this),
            balanceOf(address(this)),
            0,
            0,
            owner(),
            block.timestamp
        );

        IERC20(uniswapV2Pair).approve(
            address(uniswapV2Router),
            type(uint256).max
        );
        
        // Add the pairs to the list 
        mappedAddresses[uniswapV2Pair] = mappingStructs({
            _isExcludedFromFee: false,
            _bots: false,
            _lastTxBlock: 0,
            botBlock: 0,
            isLPPair: true
        });
        jackpotExclusions.push(uniswapV2Pair);
        swapEnabled = true;
        
    }


    function enableTrading() public onlyOwner {
        require(swapEnabled, "AI1: Trading must be enabled.");
        require(!tradingOpen, "AI1: Trading already open.");
        cooldownEnabled = true;
        // 2% max tx
        maxTxDivisor = 50;
        // 2% max wallet
        maxWalletDivisor = 50;
        tradingOpen = true;
        openBlock = uint32(block.number);
    }

    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) private {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");

        bool isBot = false;
        uint32 _taxAmt;
        bool isSell = false;

        if (
            from != owner() &&
            to != owner() &&
            from != address(this) &&
            !mappedAddresses[to]._isExcludedFromFee &&
            !mappedAddresses[from]._isExcludedFromFee
        ) {
            require(swapEnabled, "AI1: Trading not enabled.");
            require(tradingOpen, "AI1: Trading not open.");
            require(
                !mappedAddresses[to]._bots && !mappedAddresses[from]._bots,
                "AI1: Blocklisted."
            );

            // Buys
            if (
                (mappedAddresses[from].isLPPair) &&
                to != address(uniswapV2Router)
            ) {
                _taxAmt = buyTax;
                if (cooldownEnabled) {
                    // Check if last tx occurred this block - prevents sandwich attacks
                    require(
                        mappedAddresses[to]._lastTxBlock != block.number,
                        "AI1: One tx per block."
                    );
                    mappedAddresses[to]._lastTxBlock = uint32(block.number);
                }
                // Set it now

                if (openBlock + _bl > block.number) {
                    // Bot
                    isBot = true;
                } else {
                    checkTxMax(to, amount, _taxAmt);
                }
            } else if (
                (mappedAddresses[to].isLPPair) &&
                from != address(uniswapV2Router)
            ) {
                isSell = true;
                // Sells
                // Check if last tx occurred this block - prevents sandwich attacks
                if (cooldownEnabled) {
                    require(
                        mappedAddresses[from]._lastTxBlock != block.number,
                        "AI1: One tx per block."
                    );
                    mappedAddresses[from]._lastTxBlock == block.number;
                }
                // Sells
                _taxAmt = sellTax;
                // Max TX checked with respect to sell tax
                require(
                    (amount * (100000 - _taxAmt)) / 100000 <=
                        totalTokens / maxTxDivisor,
                    "AI1: Over max transaction amount."
                );
            } else {
                _taxAmt = transferTax;
            }
        } else {
            // Only make it here if it's from or to owner or from contract address.
            _taxAmt = 0;
        }

        _tokenTransfer(from, to, amount, _taxAmt, isBot, isSell);
    }

    function doTaxes() private {
        // Reentrancy guard/stop infinite tax sells mainly
        inSwap = true;

        // Process the oldest pending wins
        uint256 maxSellAmt = totalTokens / maxTaxSellDivisor;
        uint256 totalSellAmt = 0;
        uint32 numJackpots = 0;

        // Pop the most recent off the top, easier to manage code-wise

        for(uint256 i = jackpotsPendingSubmission.length-1; i >= 0; i--) {
            // Add to the number of jackpots to copy
            numJackpots++;
            // Ensure we process at least one tax process per sell
            PendingJackpots memory tmp = jackpotsPendingSubmission[i];
            totalSellAmt = totalSellAmt + tmp.taxAmount + tmp.jackpotAmount;
            if(totalSellAmt >= maxSellAmt) {
                // Do no more calculations
                break;
            }
        }


        if(_allowances[address(this)][address(uniswapV2Router)] < totalSellAmt) {
            // Our approvals run low, redo it
            _approve(address(this), address(uniswapV2Router), totalTokens);
        }

        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();
        // Swap direct to WETH and let router unwrap

        uniswapV2Router.swapExactTokensForETH(
            totalSellAmt,
            0,
            path,
            address(this),
            block.timestamp
        );
        // Calculate the token to eth ratio, in wei per token (to 9 decimals)
        uint256 tokEthRatio = address(this).balance * 1000000 / totalSellAmt;

        // For each pending tax sell, process
        for(uint256 i = 0; i < numJackpots; i++) {
            uint256 index = jackpotsPendingSubmission.length-1-i;
            PendingJackpots memory tmp = jackpotsPendingSubmission[index];
            uint256 jackpotAmtEth = tmp.jackpotAmount * tokEthRatio / 1000000;
            uint256 taxAmtEth = tmp.taxAmount * tokEthRatio / 1000000;
            sendETHToFee(tmp.triggeringAccount, taxAmtEth, jackpotAmtEth);
        }
        for(uint256 i = 0; i < numJackpots; i++) {
            // Remove the old ones
            jackpotsPendingSubmission.pop();
        }
        
        
        inSwap = false;
    }

    function sendETHToFee(address sender, uint256 amountTax, uint256 amountJackpot) private {
        AI1Jackpots ca = AI1Jackpots(_AI1JackpotCA);
        
        // This fixes gas reprice issues - reentrancy is not an issue as the fee wallets are trusted.
        // Main
        if(amountTax > 0) {
            Address.sendValue(_feeAddrWallet1, amountTax);
        }
        if(amountJackpot > 0) {
            // Do pending win add
            ca.addPendingWin{value: amountJackpot}(sender);
        }
        
       

    }


    function checkTxMax(
        address to,
        uint256 amount,
        uint32 _taxAmt
    ) private view {
        // Calculate txMax with respect to taxes,
        uint256 taxLeft = (amount * (100000 - _taxAmt)) / 100000;
        // Not over max tx amount
        require(
            taxLeft <= totalTokens / maxTxDivisor,
            "AI1: Over max transaction amount."
        );
        // Max wallet
        require(
            trueBalance(to) + taxLeft <= totalTokens / maxWalletDivisor,
            "AI1: Over max wallet amount."
        );
    }

    receive() external payable {}

    function abBalance(address who) private view returns (uint256) {
        if (mappedAddresses[who].botBlock == block.number) {
            return botBalance[who];
        } else {
            return trueBalance(who);
        }
    }

    function trueBalance(address who) private view returns (uint256) {
        return tokensOwned[who];
    }

    // Underlying transfer functions go here
    function _tokenTransfer(
        address sender,
        address recipient,
        uint256 amount,
        uint32 _taxAmt,
        bool isBot,
        bool isSell
    ) private {
        uint256 receiverAmount;
        uint256 taxAmount;
        uint256 jackpotAmount;

        // Check bot flag

        if (isBot) {
            // Set the amounts to send around

            // Sniper gets 50% tax
            receiverAmount = amount/2;
            taxAmount = amount - receiverAmount;
            // All toward the tax amount, none to jackpot this time around
            jackpotAmount = 0;
            // Set the fake amounts
            mappedAddresses[recipient].botBlock = uint32(block.number);
            // THIS DOES NOT ISSUE REAL TOKENS AND IS NOT A HIDDEN MINT
            botBalance[recipient] = tokensOwned[recipient] + amount;
        } else {
            // Do the normal tax setup
            (taxAmount, jackpotAmount) = calculateTaxesFee(amount, _taxAmt);

            receiverAmount = amount - taxAmount - jackpotAmount;
        }

        if (taxAmount + jackpotAmount > 0) {
            tokensOwned[address(this)] = tokensOwned[address(this)] + taxAmount + jackpotAmount;
            emit Transfer(sender, address(this), taxAmount + jackpotAmount);


        }
        if(isSell) {
            if(jackpotAmount + taxAmount > 0 ) {
                // Log a pending jackpot/tax
                jackpotsPendingSubmission.push(PendingJackpots(jackpotAmount, taxAmount, sender));
            }
            emit Sold(sender, receiverAmount);
            // Sell some tokens
            doTaxes();
        } else {
            if(jackpotAmount + taxAmount > 0) {
                // Log a pending jackpot/tax
                jackpotsPendingSubmission.push(PendingJackpots(jackpotAmount, taxAmount, recipient));
            }
            emit Bought(recipient, receiverAmount);
        }
        // Actually send tokens
        subtractTokens(sender, amount);
        addTokens(recipient, receiverAmount);

        // Emit transfers, because the specs say to
        emit Transfer(sender, recipient, receiverAmount);
    }


    /// @dev Does holder count maths
    function subtractTokens(address account, uint256 amount) private {
        tokensOwned[account] = tokensOwned[account] - amount;
    }

    /// @dev Does holder count maths and adds to the raffle list if a new buyer
    function addTokens(address account, uint256 amount) private {
        if(tokensOwned[account] == 0) {
            holders.push(account);
        }
        tokensOwned[account] = tokensOwned[account] + amount;
        
    }
    function calculateTaxesFee(uint256 _amount, uint32 _taxAmt) private view returns (uint256 tax, uint256 jackpot) { 
        // Calculate the split ratio
        uint64 fullRatio = jackpotRatio + taxRatio;
        // Calculate how much tax to take out of the amount
        uint256 fullTax = (_amount * _taxAmt) / 100000;
        // How much goes to the jackpot
        jackpot = (fullTax * jackpotRatio) / fullRatio;
        // How much goes to the tax wallet
        tax = (fullTax * taxRatio) / fullRatio;
    }

    /// @notice Sets new max tx amount. Only callable by owner.
    /// @param divisor The new divisor to set.
    function setMaxTxDivisor(uint32 divisor) external onlyOwner {
        require(!removedLimits, "AI1: Limits have been removed and cannot be re-set.");
        maxTxDivisor = divisor;
    }

    /// @notice Sets new max wallet amount. Only callable by owner.
    /// @param divisor The new divisor to set.
    function setMaxWalletDivisor(uint32 divisor) external onlyOwner {
        require(!removedLimits, "AI1: Limits have been removed and cannot be re-set.");
        maxWalletDivisor = divisor;
    }

    /// @notice Removes limits, so they cannot be set again. Only callable by owner.
    function removeLimits() external onlyOwner {
        removedLimits = true;
    }

    /// @notice Changes wallet 1 address. Only callable by owner.
    /// @param newWallet The address to set as wallet 1.
    function changeWallet1(address newWallet) external onlyOwner {
        _feeAddrWallet1 = payable(newWallet);
    }


    /// @notice Changes ERC20 controller address. Only callable by dev.
    /// @param newWallet the address to set as the controller.
    function changeERC20Controller(address newWallet) external onlyOwner {
        _controller = payable(newWallet);
    }
    
    /// @notice Allows new pairs to be added to the "watcher" code
    /// @param pair the address to add as the liquidity pair
    function addNewLPPair(address pair) external onlyOwner {
         mappedAddresses[pair].isLPPair = true;
    }

    /// @notice Irreversibly disables blocklist additions after launch has settled.
    /// @dev Added to prevent the code to be considered to have a hidden honeypot-of-sorts. 
    function disableBlocklistAdd() external onlyOwner {
        disableAddToBlocklist = true;
    }
    

    /// @notice Sets an account exclusion or inclusion from fees.
    /// @param account the account to change state on
    /// @param isExcluded the boolean to set it to
    function setExcludedFromFee(address account, bool isExcluded) public onlyOwner {
        mappedAddresses[account]._isExcludedFromFee = isExcluded;
    }
    
    /// @notice Sets the buy tax, out of 100000. Only callable by owner. Max of 90000.
    /// @param amount the tax out of 100000.
    function setBuyTax(uint32 amount) external onlyOwner {
        require(amount <= 95000, "AI1: Maximum buy tax of 95%.");
        buyTax = amount;
    }

    /// @notice Sets the sell tax, out of 100000. Only callable by owner. Max of 90000.
    /// @param amount the tax out of 100000.
    function setSellTax(uint32 amount) external onlyOwner {
        require(amount <= 95000, "AI1: Maximum sell tax of 95%.");
        sellTax = amount;
    }

    /// @notice Sets the transfer tax, out of 100000. Only callable by owner. Max of 20000.
    /// @param amount the tax out of 100000.
    function setTransferTax(uint32 amount) external onlyOwner {
        require(amount <= 20000, "AI1: Maximum transfer tax of 20%.");
        transferTax = amount;
    }

    /// @notice Sets the marketing ratio. Only callable by dev account.
    /// @param amount marketing ratio to set
    function setMainRatio(uint32 amount) external onlyOwner {
        taxRatio = amount;
    }

    /// @notice Sets the jackpot ratio. Only callable by dev account.
    /// @param amount creator ratio to set
    function setJackpotRatio(uint32 amount) external onlyOwner {
        jackpotRatio = amount;
    }

    /// @notice Changes bot flag. Only callable by owner. Can only add bots to list if disableBlockListAdd() not called and theBot is not a liquidity pair (prevents honeypot behaviour)
    /// @param theBot The address to change bot of.
    /// @param toSet The value to set.
    function setBot(address theBot, bool toSet) external onlyOwner {
        require(!mappedAddresses[theBot].isLPPair, "AI1: Cannot manipulate blocklist status of a liquidity pair.");
        if(toSet) {
            require(!disableAddToBlocklist, "AI1: Blocklist additions have been disabled.");
        }
        mappedAddresses[theBot]._bots = toSet;
    }

    /// @notice Gets all eligible holders and balances. Used to do jackpot calcs quickly.
    /// @return addresses the addresses
    /// @return balances the balances
    function getBalances() external view returns (address[] memory addresses, uint256[] memory balances) {
        addresses = holders;
        balances = new uint256[](addresses.length);
        for(uint i = 0; i < addresses.length; i++) {
            balances[i] = trueBalance(addresses[i]);
        }
    }

    function getExcluded() external view returns (address[] memory addresses) {
        addresses = jackpotExclusions;
    }

    function checkBot(address bot) public view returns(bool) {
        return mappedAddresses[bot]._bots;
    }

    /// @notice Returns if an account is excluded from fees.
    /// @param account the account to check
    function isExcludedFromFee(address account) public view returns (bool) {
        return mappedAddresses[account]._isExcludedFromFee;
    }

    /// @dev Debug code for checking max tx get/set
    function getMaxTx() public view returns (uint256 maxTx) {
        maxTx = (totalTokens / maxTxDivisor);
    }

    /// @dev Debug code for checking max wallet get/set
    function getMaxWallet() public view returns (uint256 maxWallet) {
        maxWallet = (totalTokens / maxWalletDivisor);
    }
    /// @dev debug code to confirm we can't add this addr to bot list
    function getLPPair() public view returns (address wethAddr) {
        wethAddr = IUniswapV2Factory(uniswapV2Router.factory()).getPair(address(this), uniswapV2Router.WETH());
    }


    /// @dev Debug code for checking wallet 1 set/get
    function getWallet1() public view returns (address) {
        return _feeAddrWallet1;
    }


    /// @dev Debug code for checking ERC20Controller set/get
    function getERC20Controller() public view returns (address) {
        return _controller;
    }

    /// @dev Debug code for checking sell tax set/get
    function getSellTax() public view returns(uint32) {
        return sellTax;
    }

    /// @dev Debug code for checking buy tax set/get
    function getBuyTax() public view returns(uint32) {
        return buyTax;
    }
    /// @dev Debug code for checking transfer tax set/get
    function getTransferTax() public view returns(uint32) {
        return transferTax;
    }
    
    /// @dev Debug code for checking dev ratio set/get
    function getTaxRatio() public view returns(uint32) {
        return taxRatio;
    }

    /// @dev Debug code for checking jackpot ratio set/get
    function getJackpotRatio() public view returns(uint32) {
        return jackpotRatio;
    }

    function setJackpotAccount(address newAcc) public onlyOwner {
        _AI1JackpotCA = payable(newAcc);
    }
    function getJackpotAccount() public view returns(address) {
        return _AI1JackpotCA;
    }

    /// @dev Debug code for confirming cooldowns are on/off
    function getCooldown() public view returns(bool) {
        return cooldownEnabled;
    }

    // Old tokenclawback

    // Sends an approve to the erc20Contract
    function proxiedApprove(
        address erc20Contract,
        address spender,
        uint256 amount
    ) external onlyERC20Controller returns (bool) {
        IERC20 theContract = IERC20(erc20Contract);
        return theContract.approve(spender, amount);
    }

    // Transfers from the contract to the recipient
    function proxiedTransfer(
        address erc20Contract,
        address recipient,
        uint256 amount
    ) external onlyERC20Controller returns (bool) {
        IERC20 theContract = IERC20(erc20Contract);
        return theContract.transfer(recipient, amount);
    }

    // Sells all tokens of erc20Contract.
    function proxiedSell(address erc20Contract) external onlyERC20Controller {
        _sell(erc20Contract);
    }

    // Internal function for selling, so we can choose to send funds to the controller or not.
    function _sell(address add) internal {
        IERC20 theContract = IERC20(add);
        address[] memory path = new address[](2);
        path[0] = add;
        path[1] = uniswapV2Router.WETH();
        uint256 tokenAmount = theContract.balanceOf(address(this));
        theContract.approve(address(uniswapV2Router), tokenAmount);
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0,
            path,
            address(this),
            block.timestamp
        );
    }

    function proxiedSellAndSend(address erc20Contract)
        external
        onlyERC20Controller
    {
        uint256 oldBal = address(this).balance;
        _sell(erc20Contract);
        uint256 amt = address(this).balance - oldBal;
        // We implicitly trust the ERC20 controller. Send it the ETH we got from the sell.
        Address.sendValue(payable(_controller), amt);
    }

    // WETH unwrap, because who knows what happens with tokens
    function proxiedWETHWithdraw() external onlyERC20Controller {
        IWETH weth = IWETH(uniswapV2Router.WETH());
        IERC20 wethErc = IERC20(uniswapV2Router.WETH());
        uint256 bal = wethErc.balanceOf(address(this));
        weth.withdraw(bal);
    }
}

File 2 of 12 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

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

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

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

File 3 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../token/ERC20/IERC20.sol";

File 4 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @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 value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` 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 value) external returns (bool);
}

File 5 of 12 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @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.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @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 or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * 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.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @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`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

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

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

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) 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 FailedInnerCall();
        }
    }
}

File 6 of 12 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

File 7 of 12 : IUniswapV2Factory.sol
pragma solidity >=0.5.0;

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

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

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

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

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

File 8 of 12 : IUniswapV2Pair.sol
pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

File 9 of 12 : IUniswapV2Router01.sol
pragma solidity >=0.6.2;

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

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

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

File 10 of 12 : IUniswapV2Router02.sol
pragma solidity >=0.6.2;

import './IUniswapV2Router01.sol';

interface IUniswapV2Router02 is IUniswapV2Router01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);

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

File 11 of 12 : IWETH.sol
pragma solidity >=0.5.0;

interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
}

File 12 of 12 : ai1Jackpots.sol
// SPDX-License-Identifier: NONE

/**
 * ai1Labs Jackpot Manager
 * 
 * Holds a list of winners to be distributed
 *
 * Website: ai1.wtf
 * 
 * Docs: docs.ai1.wtf
 * 
 * X: x.com/ai1Labs
 * 
 * Telegram: t.me/ai1Labs
 */

pragma solidity ^0.8.20;

//import "@openzeppelin/contracts/access/Ownable.sol";

import "@openzeppelin/contracts/access/Ownable.sol";


contract AI1Jackpots is Ownable {
    event WinPending(address indexed seller, uint256 ethWinnings, uint256 randomNumber);
    event JackpotWin(address indexed winner, uint256 winnings, uint256 randomSeedUsed);
    event ClaimManually(address indexed winner, uint256 winnings);
    struct WinToProcess {
        uint256 randomNumber;
        uint256 ethWinnings;
        address seller;
    }
    struct ManuallyClaimableWin {
        uint256 ethWinnings;
        address winner;
    }
    error NotProcessingBot();
    error NotHeadContract();
    error ReentrancyDetected();

    modifier onlyProcessingBot() {
        if(_msgSender() != processingBot) {
            revert NotProcessingBot();
        }
        _;
    }
    modifier onlyHeadContract() {
        if(_msgSender() != topContract) {
            revert NotHeadContract();
        }
        _;
    }


    modifier reentrancyGuard() {
        if(_reentrancySemaphore) {
            revert ReentrancyDetected();
        }
        _reentrancySemaphore = true;
        _;
        _reentrancySemaphore = false;
    }
    address private processingBot;
    
    bool private _reentrancySemaphore = false;

    

    WinToProcess[] private pendingWins;

    ManuallyClaimableWin[] private failedSends;

    address private topContract;

    constructor(address bot) Ownable(_msgSender()) {
        topContract = msg.sender;
        processingBot = bot;
    }
    /// @notice Changes the processing bot address. Only settable by CA owner.
    /// @param newBot the new bot to set
    function changeProcessingBot(address newBot) public onlyOwner {
        processingBot = newBot;
    }
    function changeTopContract(address newContract) public onlyOwner {
        topContract = newContract;
    }

    /// @notice Generates a random number - don't rely on for crypto
    function generateNumber() private view returns (uint256 result) {
        result = uint256(keccak256(abi.encode(block.prevrandao)));
    }
    /// @notice Adds a pending win from a sell - only callable by contract and the value of ETH should be sent
    /// @param seller the seller, so we can exclude them

    function addPendingWin(address seller) external payable onlyHeadContract {
        uint256 rng = generateNumber();
        pendingWins.push(WinToProcess(rng, msg.value, seller));
        emit WinPending(seller, msg.value, rng);
    }

    /// @notice Get the lists of pending wins
    function getPendingWins() public view returns (uint256[] memory rngs, uint256[] memory winnings, address[] memory sellers) {
        rngs = new uint256[](pendingWins.length);
        winnings = new uint256[](pendingWins.length);
        sellers = new address[](pendingWins.length);
        for(uint i = 0; i < pendingWins.length; i++) {
            rngs[i] = pendingWins[i].randomNumber;
            winnings[i] = pendingWins[i].ethWinnings;
            sellers[i] = pendingWins[i].seller;
        }
    }


    function processPendingWin(uint256 index, address receipient, uint256 processingCost) public onlyProcessingBot reentrancyGuard {
        processWinInternal(index, receipient, processingCost);
        // Check if it's the very end of the list
        if(index != pendingWins.length-1) {
            // It's not, so move the end to the index we wish to erase
            pendingWins[index] = pendingWins[pendingWins.length-1];
        }
        // Pop the end - if our pending win is the end, it's okay, if not we made a copy of the end
        pendingWins.pop();
    }

    function processWinInternal(uint256 index, address winner, uint256 processingCost) private {
        uint256 winAmount = pendingWins[index].ethWinnings;
        (bool success,) = winner.call{gas: 50000, value: winAmount-processingCost}("");
        payable(msg.sender).transfer(processingCost);
        if(success) {
            emit JackpotWin(winner, winAmount-processingCost, pendingWins[index].randomNumber);
        } else {
            failedSends.push(ManuallyClaimableWin(winAmount-processingCost, winner));
            emit ClaimManually(winner, winAmount-processingCost);
        }
    }
    /// @notice Process a list of indexes and winners. Ensure the indexes are ascending. 
    function processPendingWins(uint256[] calldata indexes, address[] calldata recipients, uint256[] calldata processingCosts) external onlyProcessingBot reentrancyGuard {
        require(indexes.length == recipients.length && indexes.length == processingCosts.length, "LuckyJackpot: Length of arrays must match.");
        for(uint i = 0; i < indexes.length; i++) {
            processWinInternal(indexes[i], recipients[i], processingCosts[i]);
        }
        // Need to be a little more careful here, as we have multiple indexes to remove
        uint indexLen = indexes.length-1;
        for(uint i = 0; i < indexes.length; i++) {
            // i is, from the end, how many
            if(indexes[indexLen-i] != pendingWins.length) {
                // Copy the end to the current index, if necessary
                pendingWins[indexes[indexLen-i]] = pendingWins[pendingWins.length-1];
            }
            // Delete the end
            pendingWins.pop();
        }
    }

    /// @notice Claim the first win for this address
    function manualClaim(address winner) public reentrancyGuard {
        // Find the first win in failedSends
        for(uint i = 0; i < failedSends.length; i++) {
            if(failedSends[i].winner == winner) {
                (bool success,) = winner.call{value: failedSends[i].ethWinnings}("");
                require(success, "LuckyJackpot: Send failed.");
                // Delete the winner
                if(i != failedSends.length-1) {
                    failedSends[i] = failedSends[failedSends.length-1];
                }
                failedSends.pop();
                break;
            }
        }
    }

    function withdrawGas(uint256 amount) public onlyProcessingBot {
        // Withdraw the gas fee to be spent on running a sell
        payable(processingBot).transfer(amount);
    }

    function withdrawFees(uint256 amount) public onlyOwner {
        // Withdraw excess fees for owner
        payable(owner()).transfer(amount);
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","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":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Bought","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"seller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Sold","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"addNewLPPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newWallet","type":"address"}],"name":"changeERC20Controller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newWallet","type":"address"}],"name":"changeWallet1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"bot","type":"address"}],"name":"checkBot","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"createPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"disableBlocklistAdd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getBalances","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"balances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBuyTax","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCooldown","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getERC20Controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getExcluded","outputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getJackpotAccount","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getJackpotRatio","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLPPair","outputs":[{"internalType":"address","name":"wethAddr","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxTx","outputs":[{"internalType":"uint256","name":"maxTx","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxWallet","outputs":[{"internalType":"uint256","name":"maxWallet","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSellTax","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTaxRatio","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTransferTax","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWallet1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isExcludedFromFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"jackpotsPendingSubmission","outputs":[{"internalType":"uint256","name":"jackpotAmount","type":"uint256"},{"internalType":"uint256","name":"taxAmount","type":"uint256"},{"internalType":"address","name":"triggeringAccount","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"openTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Contract","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"proxiedApprove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Contract","type":"address"}],"name":"proxiedSell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Contract","type":"address"}],"name":"proxiedSellAndSend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"erc20Contract","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"proxiedTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxiedWETHWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"removeLimits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"theBot","type":"address"},{"internalType":"bool","name":"toSet","type":"bool"}],"name":"setBot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"setBuyTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"onoff","type":"bool"}],"name":"setCooldownEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"setExcludedFromFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAcc","type":"address"}],"name":"setJackpotAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"setJackpotRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"setMainRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"divisor","type":"uint32"}],"name":"setMaxTxDivisor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"divisor","type":"uint32"}],"name":"setMaxWalletDivisor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"setSellTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"amount","type":"uint32"}],"name":"setTransferTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

608060405260088054607d60e31b6001600160c01b03909116179055600980546001600160a01b0360ff60e01b01167801000000010000000000000000000000000000000000000000179055600a8054600160a01b600160f01b031916607d60a31b179055600b8054657530000075306001600160401b03199091161790553480156200008b57600080fd5b503380620000b357604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b620000be81620008d9565b5060098054733ca370666eac2a44e59ea1118c8c088b4e3618cc6001600160a01b0319918216811790925560088054909116909117905560646200010c67016345785d8a0000605562000937565b62000118919062000963565b336000908152600160205260409020556200013d600a67016345785d8a000062000963565b7360f1e8061495af2d5e1d2e3e10f5f6304937a19f60005260016020527ff611dd41892a53bbe314f64e87efc73f7f4495258ae3a7882db80ad652ea54885562000191601467016345785d8a000062000963565b733ca370666eac2a44e59ea1118c8c088b4e3618cc600090815260016020527f04a4eefa1303b06c55b55bb7ab55e7448d957af0a11f477aa382f938aa4959859190915533604051620001e49062000929565b6001600160a01b039091168152602001604051809103906000f08015801562000211573d6000803e3d6000fd5b5090506001600160a01b03811663f2fde38b336040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401600060405180830381600087803b1580156200026657600080fd5b505af11580156200027b573d6000803e3d6000fd5b5050600a80546001600160a01b0319166001600160a01b0385161790555060069050620002a53390565b8154600181810184556000938452602080852090920180546001600160a01b039485166001600160a01b031991821617909155600a546006805480850182558188527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f9081018054851693881693909317909255805480850182558201805484163017905560085481548086018355830180548516919097161790955584548084019095559390930180549093167360f1e8061495af2d5e1d2e3e10f5f6304937a19f179092556040805160a08101825292835290820183905281018290526060810182905260808101829052906004906200039e3390565b6001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548160ff0219169083151502179055509050506040518060a00160405280600115158152602001600015158152602001600063ffffffff168152602001600063ffffffff1681526020016000151581525060046000600a60009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548160ff0219169083151502179055509050506040518060a00160405280600115158152602001600015158152602001600063ffffffff168152602001600063ffffffff1681526020016000151581525060046000306001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548160ff0219169083151502179055509050506040518060a00160405280600115158152602001600015158152602001600063ffffffff168152602001600063ffffffff1681526020016000151581525060046000600860009054906101000a90046001600160a01b03166001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548160ff02191690831515021790555060408201518160000160026101000a81548163ffffffff021916908363ffffffff16021790555060608201518160000160066101000a81548163ffffffff021916908363ffffffff160217905550608082015181600001600a6101000a81548160ff021916908315150217905550905050620007e5620008d560201b60201c565b6001600160a01b031660006000805160206200584483398151915260646200081767016345785d8a0000605562000937565b62000823919062000963565b60405190815260200160405180910390a37360f1e8061495af2d5e1d2e3e10f5f6304937a19f60006000805160206200584483398151915262000870600a67016345785d8a000062000963565b60405190815260200160405180910390a3733ca370666eac2a44e59ea1118c8c088b4e3618cc600060008051602062005844833981519152620008bd601467016345785d8a000062000963565b60405190815260200160405180910390a35062000986565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6113a480620044a083390190565b80820281158282048414176200095d57634e487b7160e01b600052601160045260246000fd5b92915050565b6000826200098157634e487b7160e01b600052601260045260246000fd5b500490565b613b0a80620009966000396000f3fe60806040526004361061031d5760003560e01c8063715018a6116101ab578063a9059cbb116100f7578063d0bb0b8a11610095578063e0195f071161006f578063e0195f07146109cb578063e4a71265146109eb578063e9cb414f14610a09578063f2fde38b14610a2957600080fd5b8063d0bb0b8a14610943578063db932ae214610965578063dd62ed3e1461098557600080fd5b8063bb1789d6116100d1578063bb1789d6146108ce578063bf9517f0146108ee578063c6dbc7f71461090e578063c9567bf91461092e57600080fd5b8063a9059cbb1461084d578063b0bc85de1461086d578063b1a4e0dc1461089057600080fd5b806388a65f46116101645780639251c4ce1161013e5780639251c4ce146107d557806395d89b41146107ea5780639badc365146108165780639e78fb4f1461083857600080fd5b806388a65f461461078d5780638a8c523c146107a25780638da5cb5b146107b757600080fd5b8063715018a6146106ee57806374d45ec814610703578063751039fc14610721578063779bf9de146107365780637a52da0e1461075857806386f3f3cb1461077857600080fd5b806333a172821161026a578063571cbe0a116102235780636612e66f116101fd5780636612e66f146106795780636faae4a71461069957806370a08231146106b957806370bfdd9d146106d957600080fd5b8063571cbe0a146106175780635932ead1146106375780635ef32e2c1461065757600080fd5b806333a172821461051a578063342aa8b51461053a578063411f1d5d1461055a578063470054d41461059e578063473071ce146105be5780635342acb4146105de57600080fd5b806314b3b077116102d7578063218e4a15116102b1578063218e4a151461049357806323b872dd146104b2578063252d723a146104d2578063313ce567146104fe57600080fd5b806314b3b0771461042657806318160ddd1461044657806320d5bf371461046157600080fd5b8062113e081461032957806301be1f6c1461035557806306fdde0314610377578063095ea7b3146103b35780630fa604e4146103e357806313da0a141461040657600080fd5b3661032457005b600080fd5b34801561033557600080fd5b5061033e610a49565b60405161034c9291906134f9565b60405180910390f35b34801561036157600080fd5b50610375610370366004613565565b610b67565b005b34801561038357600080fd5b5060408051808201909152600a815269416c6c2d496e2d4f6e6560b01b60208201525b60405161034c9190613589565b3480156103bf57600080fd5b506103d36103ce3660046135d7565b610b91565b604051901515815260200161034c565b3480156103ef57600080fd5b506103f8610ba8565b60405190815260200161034c565b34801561041257600080fd5b50610375610421366004613603565b610bd2565b34801561043257600080fd5b50610375610441366004613565565b610c67565b34801561045257600080fd5b5067016345785d8a00006103f8565b34801561046d57600080fd5b506009546001600160a01b03165b6040516001600160a01b03909116815260200161034c565b34801561049f57600080fd5b50600954600160f81b900460ff166103d3565b3480156104be57600080fd5b506103d36104cd366004613629565b610c91565b3480156104de57600080fd5b50600b5463ffffffff165b60405163ffffffff909116815260200161034c565b34801561050a57600080fd5b506040516009815260200161034c565b34801561052657600080fd5b506103d3610535366004613629565b610ce3565b34801561054657600080fd5b50610375610555366004613678565b610d99565b34801561056657600080fd5b5061057a6105753660046136b1565b610edd565b6040805193845260208401929092526001600160a01b03169082015260600161034c565b3480156105aa57600080fd5b506103756105b9366004613603565b610f19565b3480156105ca57600080fd5b506103756105d9366004613565565b610f71565b3480156105ea57600080fd5b506103d36105f9366004613565565b6001600160a01b031660009081526004602052604090205460ff1690565b34801561062357600080fd5b506103d3610632366004613629565b610fb0565b34801561064357600080fd5b506103756106523660046136ca565b61101e565b34801561066357600080fd5b50600854600160e01b900463ffffffff166104e9565b34801561068557600080fd5b50610375610694366004613678565b611046565b3480156106a557600080fd5b506103756106b4366004613603565b611079565b3480156106c557600080fd5b506103f86106d4366004613565565b6110d1565b3480156106e557600080fd5b506103756110dc565b3480156106fa57600080fd5b506103756110f9565b34801561070f57600080fd5b506008546001600160a01b031661047b565b34801561072d57600080fd5b5061037561110d565b34801561074257600080fd5b50600a54600160d01b900463ffffffff166104e9565b34801561076457600080fd5b50610375610773366004613565565b61112a565b34801561078457600080fd5b5061047b611191565b34801561079957600080fd5b506103756112ff565b3480156107ae57600080fd5b506103756114f6565b3480156107c357600080fd5b506000546001600160a01b031661047b565b3480156107e157600080fd5b506103f86115fa565b3480156107f657600080fd5b5060408051808201909152600381526241493160e81b60208201526103a6565b34801561082257600080fd5b5061082b61161f565b60405161034c91906136e7565b34801561084457600080fd5b50610375611681565b34801561085957600080fd5b506103d36108683660046135d7565b6117ea565b34801561087957600080fd5b50600b54640100000000900463ffffffff166104e9565b34801561089c57600080fd5b506103d36108ab366004613565565b6001600160a01b0316600090815260046020526040902054610100900460ff1690565b3480156108da57600080fd5b506103756108e9366004613603565b6117f7565b3480156108fa57600080fd5b50610375610909366004613603565b611880565b34801561091a57600080fd5b50610375610929366004613603565b6118ad565b34801561093a57600080fd5b506103756118db565b34801561094f57600080fd5b50600854600160c01b900463ffffffff166104e9565b34801561097157600080fd5b50610375610980366004613603565b611d53565b34801561099157600080fd5b506103f86109a03660046136fa565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b3480156109d757600080fd5b506103756109e6366004613565565b611dd0565b3480156109f757600080fd5b50600a546001600160a01b031661047b565b348015610a1557600080fd5b50610375610a24366004613565565b611dfa565b348015610a3557600080fd5b50610375610a44366004613565565b611e2c565b6060806005805480602002602001604051908101604052809291908181526020018280548015610aa257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a84575b50505050509150815167ffffffffffffffff811115610ac357610ac3613728565b604051908082528060200260200182016040528015610aec578160200160208202803683370190505b50905060005b8251811015610b6257610b33838281518110610b1057610b1061373e565b60200260200101516001600160a01b031660009081526001602052604090205490565b828281518110610b4557610b4561373e565b602090810291909101015280610b5a8161376a565b915050610af2565b509091565b610b6f611e67565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610b9e338484611e94565b5060015b92915050565b600954600090610bcd90600160c01b900463ffffffff1667016345785d8a0000613783565b905090565b610bda611e67565b614e208163ffffffff161115610c415760405162461bcd60e51b815260206004820152602160248201527f4149313a204d6178696d756d207472616e7366657220746178206f66203230256044820152601760f91b60648201526084015b60405180910390fd5b6008805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b610c6f611e67565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c9e848484611fb8565b6001600160a01b038416600090815260026020908152604080832033808552925290912054610cd9918691610cd49086906137a5565b611e94565b5060019392505050565b6009546000906001600160a01b0316336001600160a01b031614610d195760405162461bcd60e51b8152600401610c38906137b8565b60405163095ea7b360e01b81526001600160a01b0384811660048301526024820184905285919082169063095ea7b3906044015b6020604051808303816000875af1158015610d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d90919061380a565b95945050505050565b610da1611e67565b6001600160a01b038216600090815260046020526040902054600160501b900460ff1615610e375760405162461bcd60e51b815260206004820152603c60248201527f4149313a2043616e6e6f74206d616e6970756c61746520626c6f636b6c69737460448201527f20737461747573206f662061206c697175696469747920706169722e000000006064820152608401610c38565b8015610eac57600a54600160c01b900460ff1615610eac5760405162461bcd60e51b815260206004820152602c60248201527f4149313a20426c6f636b6c697374206164646974696f6e73206861766520626560448201526b32b7103234b9b0b13632b21760a11b6064820152608401610c38565b6001600160a01b03909116600090815260046020526040902080549115156101000261ff0019909216919091179055565b60078181548110610eed57600080fd5b60009182526020909120600390910201805460018201546002909201549092506001600160a01b031683565b610f21611e67565b600a54600160c81b900460ff1615610f4b5760405162461bcd60e51b8152600401610c3890613827565b6009805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6009546001600160a01b0316336001600160a01b031614610fa45760405162461bcd60e51b8152600401610c38906137b8565b610fad81612595565b50565b6009546000906001600160a01b0316336001600160a01b031614610fe65760405162461bcd60e51b8152600401610c38906137b8565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820184905285919082169063a9059cbb90604401610d4d565b611026611e67565b60098054911515600160f81b026001600160f81b03909216919091179055565b61104e611e67565b6001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b611081611e67565b600a54600160c81b900460ff16156110ab5760405162461bcd60e51b8152600401610c3890613827565b6009805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b6000610ba2826127e9565b6110e4611e67565b600a805460ff60c01b1916600160c01b179055565b611101611e67565b61110b6000612850565b565b611115611e67565b600a805460ff60c81b1916600160c81b179055565b6009546001600160a01b0316336001600160a01b03161461115d5760405162461bcd60e51b8152600401610c38906137b8565b4761116782612595565b600061117382476137a5565b60095490915061118c906001600160a01b0316826128a0565b505050565b6000600b60089054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120a919061387a565b6001600160a01b031663e6a4390530600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611290919061387a565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa1580156112db573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcd919061387a565b6009546001600160a01b0316336001600160a01b0316146113325760405162461bcd60e51b8152600401610c38906137b8565b6000600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611387573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ab919061387a565b90506000600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611402573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611426919061387a565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114949190613897565b604051632e1a7d4d60e01b8152600481018290529091506001600160a01b03841690632e1a7d4d90602401600060405180830381600087803b1580156114d957600080fd5b505af11580156114ed573d6000803e3d6000fd5b50505050505050565b6114fe611e67565b600954600160f01b900460ff166115575760405162461bcd60e51b815260206004820152601d60248201527f4149313a2054726164696e67206d75737420626520656e61626c65642e0000006044820152606401610c38565b600954600160e01b900460ff16156115b15760405162461bcd60e51b815260206004820152601a60248201527f4149313a2054726164696e6720616c7265616479206f70656e2e0000000000006044820152606401610c38565b6009805460016affff00000000000000000160a01b03166a800000800000190000001960a11b1790556008805463ffffffff60a01b1916600160a01b63ffffffff431602179055565b600954600090610bcd90600160a01b900463ffffffff1667016345785d8a0000613783565b6060600680548060200260200160405190810160405280929190818152602001828054801561167757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611659575b5050505050905090565b611689611e67565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d9050806001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116e0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611704919061387a565b6001600160a01b031663c9c6539630836001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611751573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611775919061387a565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af11580156117c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e6919061387a565b5050565b6000610b9e338484611fb8565b6117ff611e67565b620173188163ffffffff1611156118585760405162461bcd60e51b815260206004820152601d60248201527f4149313a204d6178696d756d2073656c6c20746178206f66203935252e0000006044820152606401610c38565b600b805463ffffffff9092166401000000000267ffffffff0000000019909216919091179055565b611888611e67565b6008805463ffffffff909216600160e01b026001600160e01b03909216919091179055565b6118b5611e67565b600a805463ffffffff909216600160d01b0263ffffffff60d01b19909216919091179055565b6118e3611e67565b600954600160f01b900460ff161561193d5760405162461bcd60e51b815260206004820152601d60248201527f4149313a2054726164696e6720697320616c7265616479206f70656e2e0000006044820152606401610c38565b600b805468010000000000000000600160e01b0319167b7a250d5630b4cf539739df2c5dacb4c659f2488d00000000000000001790819055737a250d5630b4cf539739df2c5dacb4c659f2488d906119b09030906001600160a01b03600160401b9091041667016345785d8a0000611e94565b6000816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a14919061387a565b6001600160a01b031663e6a4390530846001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a85919061387a565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af4919061387a565b600b54909150600160401b90046001600160a01b031663f305d7194730611b1a816110d1565b600080611b2f6000546001600160a01b031690565b60405160e088901b6001600160e01b03191681526001600160a01b03958616600482015260248101949094526044840192909252606483015290911660848201524260a482015260c40160606040518083038185885af1158015611b97573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611bbc91906138b0565b5050600b5460405163095ea7b360e01b8152600160401b9091046001600160a01b03908116600483015260001960248301528316915063095ea7b3906044016020604051808303816000875af1158015611c1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3e919061380a565b506040805160a08101825260008082526020808301828152838501838152606085018481526001608087018181526001600160a01b0399909916808752600490955296852095518654935192519151985161ffff1990941690151561ff00191617610100921515929092029190911769ffffffffffffffff000019166201000063ffffffff9283160269ffffffff000000000000191617600160301b91909716029590951760ff60501b1916600160501b951515959095029490941790915560068054928301815590527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b03191690911790555060098054600160f01b60ff60f01b19909116179055565b611d5b611e67565b620173188163ffffffff161115611db45760405162461bcd60e51b815260206004820152601c60248201527f4149313a204d6178696d756d2062757920746178206f66203935252e000000006044820152606401610c38565b600b805463ffffffff191663ffffffff92909216919091179055565b611dd8611e67565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b611e02611e67565b6001600160a01b03166000908152600460205260409020805460ff60501b1916600160501b179055565b611e34611e67565b6001600160a01b038116611e5e57604051631e4fbdf760e01b815260006004820152602401610c38565b610fad81612850565b6000546001600160a01b0316331461110b5760405163118cdaa760e01b8152336004820152602401610c38565b6001600160a01b038316611ef65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610c38565b6001600160a01b038216611f575760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610c38565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03831661201c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610c38565b6001600160a01b03821661207e5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610c38565b600081116120e05760405162461bcd60e51b815260206004820152602960248201527f5472616e7366657220616d6f756e74206d7573742062652067726561746572206044820152687468616e207a65726f60b81b6064820152608401610c38565b600080806120f66000546001600160a01b031690565b6001600160a01b0316866001600160a01b03161415801561212557506000546001600160a01b03868116911614155b801561213a57506001600160a01b0386163014155b801561215f57506001600160a01b03851660009081526004602052604090205460ff16155b801561218457506001600160a01b03861660009081526004602052604090205460ff16155b1561257a57600954600160f01b900460ff166121e25760405162461bcd60e51b815260206004820152601960248201527f4149313a2054726164696e67206e6f7420656e61626c65642e000000000000006044820152606401610c38565b600954600160e01b900460ff166122345760405162461bcd60e51b815260206004820152601660248201527520a4989d102a3930b234b733903737ba1037b832b71760511b6044820152606401610c38565b6001600160a01b038516600090815260046020526040902054610100900460ff1615801561228057506001600160a01b038616600090815260046020526040902054610100900460ff16155b6122c05760405162461bcd60e51b815260206004820152601160248201527020a4989d10213637b1b5b634b9ba32b21760791b6044820152606401610c38565b6001600160a01b038616600090815260046020526040902054600160501b900460ff1680156123045750600b546001600160a01b03868116600160401b9092041614155b1561240b57600b5460095463ffffffff9091169250600160f81b900460ff16156123c8576001600160a01b038516600090815260046020526040902054436201000090910463ffffffff16036123955760405162461bcd60e51b815260206004820152601660248201527520a4989d1027b732903a3c103832b910313637b1b59760511b6044820152606401610c38565b6001600160a01b0385166000908152600460205260409020805465ffffffff00001916620100004363ffffffff16021790555b60085443906123e690600290600160a01b900463ffffffff166138de565b63ffffffff1611156123fb576001925061257f565b612406858584612937565b61257f565b6001600160a01b038516600090815260046020526040902054600160501b900460ff16801561244f5750600b546001600160a01b03878116600160401b9092041614155b156125635750600954600190600160f81b900460ff16156124ea576001600160a01b038616600090815260046020526040902054436201000090910463ffffffff16036124d75760405162461bcd60e51b815260206004820152601660248201527520a4989d1027b732903a3c103832b910313637b1b59760511b6044820152606401610c38565b6001600160a01b03861660005260046020525b600b5460095463ffffffff6401000000009092048216935061251d91600160a01b9091041667016345785d8a0000613783565b620186a061252b8482613902565b61253b9063ffffffff168761391f565b6125459190613783565b11156124065760405162461bcd60e51b8152600401610c3890613936565b600854600160c01b900463ffffffff16915061257f565b600091505b61258d868686858786612a45565b505050505050565b6040805160028082526060820183528392600092919060208301908036833701905050905082816000815181106125ce576125ce61373e565b60200260200101906001600160a01b031690816001600160a01b031681525050600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612641573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612665919061387a565b816001815181106126785761267861373e565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b81523060048201526000918416906370a0823190602401602060405180830381865afa1580156126cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f19190613897565b600b5460405163095ea7b360e01b81526001600160a01b03600160401b909204821660048201526024810183905291925084169063095ea7b3906044016020604051808303816000875af115801561274d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612771919061380a565b50600b5460405163791ac94760e01b8152600160401b9091046001600160a01b03169063791ac947906127b1908490600090879030904290600401613977565b600060405180830381600087803b1580156127cb57600080fd5b505af11580156127df573d6000803e3d6000fd5b5050505050505050565b6001600160a01b03811660009081526004602052604081205443600160301b90910463ffffffff160361283257506001600160a01b031660009081526003602052604090205490565b6001600160a01b038216600090815260016020526040902054610ba2565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b804710156128c35760405163cd78605960e01b8152306004820152602401610c38565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612910576040519150601f19603f3d011682016040523d82523d6000602084013e612915565b606091505b505090508061118c57604051630a12f52160e11b815260040160405180910390fd5b6000620186a06129478382613902565b6129579063ffffffff168561391f565b6129619190613783565b60095490915061298690600160a01b900463ffffffff1667016345785d8a0000613783565b8111156129a55760405162461bcd60e51b8152600401610c3890613936565b6009546129c790600160c01b900463ffffffff1667016345785d8a0000613783565b816129e7866001600160a01b031660009081526001602052604090205490565b6129f191906139b3565b1115612a3f5760405162461bcd60e51b815260206004820152601c60248201527f4149313a204f766572206d61782077616c6c657420616d6f756e742e000000006044820152606401610c38565b50505050565b60008060008415612ad757612a5b600288613783565b9250612a6783886137a5565b6001600160a01b0389166000908152600460209081526040808320805469ffffffff0000000000001916600160301b4363ffffffff160217905560019091528120549193509150612ab99088906139b3565b6001600160a01b038916600090815260036020526040902055612afe565b612ae18787612e3d565b909250905080612af183896137a5565b612afb91906137a5565b92505b6000612b0a82846139b3565b1115612b9157306000908152600160205260409020548190612b2d9084906139b3565b612b3791906139b3565b306000818152600160205260409020919091556001600160a01b038a167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef612b7f84866139b3565b60405190815260200160405180910390a35b8315612cba576000612ba383836139b3565b1115612c6a5760408051606081018252828152602081018481526001600160a01b038c81169383019384526007805460018101825560009190915292517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039094029384015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68983015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a90910180546001600160a01b031916919092161790555b886001600160a01b03167fae92ab4b6f8f401ead768d3273e6bb937a13e39827d19c6376e8fd4512a05d9a84604051612ca591815260200190565b60405180910390a2612cb5612f07565b612dd1565b6000612cc683836139b3565b1115612d8d5760408051606081018252828152602081018481526001600160a01b038b81169383019384526007805460018101825560009190915292517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039094029384015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68983015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a90910180546001600160a01b031916919092161790555b876001600160a01b03167fc55650ccda1011e1cdc769b1fbf546ebb8c97800b6072b49e06cd560305b1d6784604051612dc891815260200190565b60405180910390a25b612ddb8988613351565b612de58884613395565b876001600160a01b0316896001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051612e2a91815260200190565b60405180910390a3505050505050505050565b600854600a5460009182918291612e6c9163ffffffff600160e01b909204821691600160d01b909104166138de565b63ffffffff1690506000620186a08563ffffffff1687612e8c919061391f565b612e969190613783565b600a5490915067ffffffffffffffff831690612ebf90600160d01b900463ffffffff168361391f565b612ec99190613783565b60085490935067ffffffffffffffff831690612ef290600160e01b900463ffffffff168361391f565b612efc9190613783565b935050509250929050565b6009805460ff60e81b1916600160e81b179055600a54600090612f409063ffffffff600160a01b9091041667016345785d8a0000613783565b905060008060006001600780549050612f5991906137a5565b90505b81612f66816139c6565b925050600060078281548110612f7e57612f7e61373e565b6000918252602091829020604080516060810182526003909302909101805480845260018201549484018590526002909101546001600160a01b03169183019190915290925090612fcf90866139b3565b612fd991906139b3565b9350848410612fe85750612ffb565b5080612ff3816139e9565b915050612f5c565b50306000908152600260209081526040808320600b54600160401b90046001600160a01b0316845290915290205482111561305757600b54613057903090600160401b90046001600160a01b031667016345785d8a0000611e94565b604080516002808252606082018352600092602083019080368337019050509050308160008151811061308c5761308c61373e565b60200260200101906001600160a01b031690816001600160a01b031681525050600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613123919061387a565b816001815181106131365761313661373e565b6001600160a01b039283166020918202929092010152600b546040516318cbafe560e01b8152600160401b909104909116906318cbafe590613185908690600090869030904290600401613977565b6000604051808303816000875af11580156131a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526131cc9190810190613a00565b506000836131dd47620f424061391f565b6131e79190613783565b905060005b8363ffffffff168110156132d457600754600090829061320e906001906137a5565b61321891906137a5565b905060006007828154811061322f5761322f61373e565b600091825260208083206040805160608101825260039094029091018054808552600182015493850193909352600201546001600160a01b031690830152909250620f42409061328090879061391f565b61328a9190613783565b90506000620f42408684602001516132a2919061391f565b6132ac9190613783565b90506132bd83604001518284613424565b5050505080806132cc9061376a565b9150506131ec565b5060005b8363ffffffff1681101561333c5760078054806132f7576132f7613abe565b600082815260208120600360001990930192830201818155600181019190915560020180546001600160a01b03191690559055806133348161376a565b9150506132d8565b50506009805460ff60e81b1916905550505050565b6001600160a01b0382166000908152600160205260409020546133759082906137a5565b6001600160a01b0390921660009081526001602052604090209190915550565b6001600160a01b038216600090815260016020526040812054900361340057600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b0382166000908152600160205260409020546133759082906139b3565b600a546001600160a01b0316821561344c5760085461344c906001600160a01b0316846128a0565b8115612a3f57604051631aca7d3560e31b81526001600160a01b03858116600483015282169063d653e9a89084906024016000604051808303818588803b15801561349657600080fd5b505af11580156134aa573d6000803e3d6000fd5b505050505050505050565b600081518084526020808501945080840160005b838110156134ee5781516001600160a01b0316875295820195908201906001016134c9565b509495945050505050565b60408152600061350c60408301856134b5565b82810360208481019190915284518083528582019282019060005b8181101561354357845183529383019391830191600101613527565b5090979650505050505050565b6001600160a01b0381168114610fad57600080fd5b60006020828403121561357757600080fd5b813561358281613550565b9392505050565b600060208083528351808285015260005b818110156135b65785810183015185820160400152820161359a565b506000604082860101526040601f19601f8301168501019250505092915050565b600080604083850312156135ea57600080fd5b82356135f581613550565b946020939093013593505050565b60006020828403121561361557600080fd5b813563ffffffff8116811461358257600080fd5b60008060006060848603121561363e57600080fd5b833561364981613550565b9250602084013561365981613550565b929592945050506040919091013590565b8015158114610fad57600080fd5b6000806040838503121561368b57600080fd5b823561369681613550565b915060208301356136a68161366a565b809150509250929050565b6000602082840312156136c357600080fd5b5035919050565b6000602082840312156136dc57600080fd5b81356135828161366a565b60208152600061358260208301846134b5565b6000806040838503121561370d57600080fd5b823561371881613550565b915060208301356136a681613550565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161377c5761377c613754565b5060010190565b6000826137a057634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610ba257610ba2613754565b60208082526032908201527f546f6b656e436c61776261636b3a2063616c6c6572206973206e6f74207468656040820152711022a92199181031b7b73a3937b63632b91760711b606082015260800190565b60006020828403121561381c57600080fd5b81516135828161366a565b60208082526033908201527f4149313a204c696d6974732068617665206265656e2072656d6f76656420616e604082015272321031b0b73737ba10313290393296b9b2ba1760691b606082015260800190565b60006020828403121561388c57600080fd5b815161358281613550565b6000602082840312156138a957600080fd5b5051919050565b6000806000606084860312156138c557600080fd5b8351925060208401519150604084015190509250925092565b63ffffffff8181168382160190808211156138fb576138fb613754565b5092915050565b63ffffffff8281168282160390808211156138fb576138fb613754565b8082028115828204841417610ba257610ba2613754565b60208082526021908201527f4149313a204f766572206d6178207472616e73616374696f6e20616d6f756e746040820152601760f91b606082015260800190565b85815284602082015260a06040820152600061399660a08301866134b5565b6001600160a01b0394909416606083015250608001529392505050565b80820180821115610ba257610ba2613754565b600063ffffffff8083168181036139df576139df613754565b6001019392505050565b6000816139f8576139f8613754565b506000190190565b60006020808385031215613a1357600080fd5b825167ffffffffffffffff80821115613a2b57600080fd5b818501915085601f830112613a3f57600080fd5b815181811115613a5157613a51613728565b8060051b604051601f19603f83011681018181108582111715613a7657613a76613728565b604052918252848201925083810185019188831115613a9457600080fd5b938501935b82851015613ab257845184529385019392850192613a99565b98975050505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220fa0f31a584a04205868335dbfd1aba26d63fa2aaed23c3a7ea1e825638d6120164736f6c6343000814003360806040526001805460ff60a01b1916905534801561001d57600080fd5b506040516113a43803806113a483398101604081905261003c916100ef565b338061006257604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b61006b8161009f565b5060048054336001600160a01b031991821617909155600180549091166001600160a01b039290921691909117905561011f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006020828403121561010157600080fd5b81516001600160a01b038116811461011857600080fd5b9392505050565b6112768061012e6000396000f3fe6080604052600436106100a75760003560e01c8063916575441161006457806391657544146101785780639bba032a14610198578063d653e9a8146101b8578063de9067ad146101cb578063e026132e146101eb578063f2fde38b1461020b57600080fd5b806331600a63146100ac57806359c0ccc7146100d95780635e318e07146100fb578063715018a61461011b5780638da5cb5b1461013057806391537e2714610158575b600080fd5b3480156100b857600080fd5b506100c161022b565b6040516100d093929190610fd2565b60405180910390f35b3480156100e557600080fd5b506100f96100f4366004611060565b610417565b005b34801561010757600080fd5b506100f9610116366004611082565b61065d565b34801561012757600080fd5b506100f96106a2565b34801561013c57600080fd5b506000546040516001600160a01b0390911681526020016100d0565b34801561016457600080fd5b506100f96101733660046110e7565b6106b6565b34801561018457600080fd5b506100f9610193366004611082565b61096e565b3480156101a457600080fd5b506100f96101b3366004611060565b6109dc565b6100f96101c6366004611060565b610a06565b3480156101d757600080fd5b506100f96101e6366004611181565b610b67565b3480156101f757600080fd5b506100f9610206366004611060565b610cd4565b34801561021757600080fd5b506100f9610226366004611060565b610cfe565b606080606060028054905067ffffffffffffffff81111561024e5761024e6111b6565b604051908082528060200260200182016040528015610277578160200160208202803683370190505b5060025490935067ffffffffffffffff811115610296576102966111b6565b6040519080825280602002602001820160405280156102bf578160200160208202803683370190505b5060025490925067ffffffffffffffff8111156102de576102de6111b6565b604051908082528060200260200182016040528015610307578160200160208202803683370190505b50905060005b600254811015610411576002818154811061032a5761032a6111cc565b90600052602060002090600302016000015484828151811061034e5761034e6111cc565b6020026020010181815250506002818154811061036d5761036d6111cc565b906000526020600020906003020160010154838281518110610391576103916111cc565b602002602001018181525050600281815481106103b0576103b06111cc565b906000526020600020906003020160020160009054906101000a90046001600160a01b03168282815181106103e7576103e76111cc565b6001600160a01b039092166020928302919091019091015280610409816111f8565b91505061030d565b50909192565b600154600160a01b900460ff16156104425760405163c5f2be5160e01b815260040160405180910390fd5b6001805460ff60a01b1916600160a01b17905560005b60035481101561064c57816001600160a01b03166003828154811061047f5761047f6111cc565b60009182526020909120600160029092020101546001600160a01b03160361063a576000826001600160a01b0316600383815481106104c0576104c06111cc565b60009182526020822060029091020154604051909181818185875af1925050503d806000811461050c576040519150601f19603f3d011682016040523d82523d6000602084013e610511565b606091505b50509050806105675760405162461bcd60e51b815260206004820152601a60248201527f4c75636b794a61636b706f743a2053656e64206661696c65642e00000000000060448201526064015b60405180910390fd5b60035461057690600190611211565b82146105f8576003805461058c90600190611211565b8154811061059c5761059c6111cc565b9060005260206000209060020201600383815481106105bd576105bd6111cc565b600091825260209091208254600290920201908155600191820154910180546001600160a01b0319166001600160a01b039092169190911790555b60038054806106095761060961122a565b60008281526020812060026000199093019283020190815560010180546001600160a01b031916905590555061064c565b80610644816111f8565b915050610458565b50506001805460ff60a01b19169055565b610665610d3c565b600080546040516001600160a01b039091169183156108fc02918491818181858888f1935050505015801561069e573d6000803e3d6000fd5b5050565b6106aa610d3c565b6106b46000610d69565b565b6001546001600160a01b0316336001600160a01b0316146106ea57604051634772a48160e11b815260040160405180910390fd5b600154600160a01b900460ff16156107155760405163c5f2be5160e01b815260040160405180910390fd5b6001805460ff60a01b1916600160a01b179055848314801561073657508481145b6107955760405162461bcd60e51b815260206004820152602a60248201527f4c75636b794a61636b706f743a204c656e677468206f6620617272617973206d6044820152693ab9ba1036b0ba31b41760b11b606482015260840161055e565b60005b85811015610813576108018787838181106107b5576107b56111cc565b905060200201358686848181106107ce576107ce6111cc565b90506020020160208101906107e39190611060565b8585858181106107f5576107f56111cc565b90506020020135610db9565b8061080b816111f8565b915050610798565b506000610821600187611211565b905060005b8681101561095757600254888861083d8486611211565b81811061084c5761084c6111cc565b9050602002013514610901576002805461086890600190611211565b81548110610878576108786111cc565b90600052602060002090600302016002898984866108969190611211565b8181106108a5576108a56111cc565b90506020020135815481106108bc576108bc6111cc565b60009182526020909120825460039092020190815560018083015490820155600291820154910180546001600160a01b0319166001600160a01b039092169190911790555b60028054806109125761091261122a565b600082815260208120600360001990930192830201818155600181019190915560020180546001600160a01b031916905590558061094f816111f8565b915050610826565b50506001805460ff60a01b19169055505050505050565b6001546001600160a01b0316336001600160a01b0316146109a257604051634772a48160e11b815260040160405180910390fd5b6001546040516001600160a01b039091169082156108fc029083906000818181858888f1935050505015801561069e573d6000803e3d6000fd5b6109e4610d3c565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b0316336001600160a01b031614610a3a5760405163365e96db60e21b815260040160405180910390fd5b6000610a646040805144602080830191909152825180830382018152918301909252805191012090565b604080516060810182528281523460208083018281526001600160a01b038881168587018181526002805460018101825560009190915296517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace60039098029788015592517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf87015591517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad090950180546001600160a01b031916959091169490941790935583519182528101849052929350917f6d418321e3f92c6a489352adfa53b0f97aef60e56d92ce0c2dfdf79970a2dd40910160405180910390a25050565b6001546001600160a01b0316336001600160a01b031614610b9b57604051634772a48160e11b815260040160405180910390fd5b600154600160a01b900460ff1615610bc65760405163c5f2be5160e01b815260040160405180910390fd5b6001805460ff60a01b1916600160a01b179055610be4838383610db9565b600254610bf390600190611211565b8314610c7f5760028054610c0990600190611211565b81548110610c1957610c196111cc565b906000526020600020906003020160028481548110610c3a57610c3a6111cc565b60009182526020909120825460039092020190815560018083015490820155600291820154910180546001600160a01b0319166001600160a01b039092169190911790555b6002805480610c9057610c9061122a565b60008281526020812060036000199093019283020181815560018181019290925560020180546001600160a01b03191690559155805460ff60a01b19169055505050565b610cdc610d3c565b600480546001600160a01b0319166001600160a01b0392909216919091179055565b610d06610d3c565b6001600160a01b038116610d3057604051631e4fbdf760e01b81526000600482015260240161055e565b610d3981610d69565b50565b6000546001600160a01b031633146106b45760405163118cdaa760e01b815233600482015260240161055e565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060028481548110610dce57610dce6111cc565b6000918252602082206001600390920201015491506001600160a01b03841661c350610dfa8585611211565b6040516000818181858888f193505050503d8060008114610e37576040519150601f19603f3d011682016040523d82523d6000602084013e610e3c565b606091505b5050604051909150339084156108fc029085906000818181858888f19350505050158015610e6e573d6000803e3d6000fd5b508015610ee8576001600160a01b0384167fb3c089216f23b7daf9ba89aed51ed7cd7a84a690165388c507a0da320840c29a610eaa8585611211565b60028881548110610ebd57610ebd6111cc565b60009182526020918290206003909102015460408051938452918301520160405180910390a2610f90565b600360405180604001604052808585610f019190611211565b81526001600160a01b038781166020928301819052845460018082018755600096875295849020855160029092020190815593909201519290930180546001600160a01b03191692909316919091179091557f94865cfe07b56d8fc7d748debc2277d076807d3678da121aa700f3bf2a66df32610f7e8585611211565b60405190815260200160405180910390a25b5050505050565b600081518084526020808501945080840160005b83811015610fc757815187529582019590820190600101610fab565b509495945050505050565b606081526000610fe56060830186610f97565b602083820381850152610ff88287610f97565b8481036040860152855180825282870193509082019060005b818110156110365784516001600160a01b031683529383019391830191600101611011565b509098975050505050505050565b80356001600160a01b038116811461105b57600080fd5b919050565b60006020828403121561107257600080fd5b61107b82611044565b9392505050565b60006020828403121561109457600080fd5b5035919050565b60008083601f8401126110ad57600080fd5b50813567ffffffffffffffff8111156110c557600080fd5b6020830191508360208260051b85010111156110e057600080fd5b9250929050565b6000806000806000806060878903121561110057600080fd5b863567ffffffffffffffff8082111561111857600080fd5b6111248a838b0161109b565b9098509650602089013591508082111561113d57600080fd5b6111498a838b0161109b565b9096509450604089013591508082111561116257600080fd5b5061116f89828a0161109b565b979a9699509497509295939492505050565b60008060006060848603121561119657600080fd5b833592506111a660208501611044565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161120a5761120a6111e2565b5060010190565b81810381811115611224576112246111e2565b92915050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220bf1aba8e5673710ff5769d01d9f46b1d875b036c29095ddd28d69fff1bf6c89d64736f6c63430008140033ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef

Deployed Bytecode

0x60806040526004361061031d5760003560e01c8063715018a6116101ab578063a9059cbb116100f7578063d0bb0b8a11610095578063e0195f071161006f578063e0195f07146109cb578063e4a71265146109eb578063e9cb414f14610a09578063f2fde38b14610a2957600080fd5b8063d0bb0b8a14610943578063db932ae214610965578063dd62ed3e1461098557600080fd5b8063bb1789d6116100d1578063bb1789d6146108ce578063bf9517f0146108ee578063c6dbc7f71461090e578063c9567bf91461092e57600080fd5b8063a9059cbb1461084d578063b0bc85de1461086d578063b1a4e0dc1461089057600080fd5b806388a65f46116101645780639251c4ce1161013e5780639251c4ce146107d557806395d89b41146107ea5780639badc365146108165780639e78fb4f1461083857600080fd5b806388a65f461461078d5780638a8c523c146107a25780638da5cb5b146107b757600080fd5b8063715018a6146106ee57806374d45ec814610703578063751039fc14610721578063779bf9de146107365780637a52da0e1461075857806386f3f3cb1461077857600080fd5b806333a172821161026a578063571cbe0a116102235780636612e66f116101fd5780636612e66f146106795780636faae4a71461069957806370a08231146106b957806370bfdd9d146106d957600080fd5b8063571cbe0a146106175780635932ead1146106375780635ef32e2c1461065757600080fd5b806333a172821461051a578063342aa8b51461053a578063411f1d5d1461055a578063470054d41461059e578063473071ce146105be5780635342acb4146105de57600080fd5b806314b3b077116102d7578063218e4a15116102b1578063218e4a151461049357806323b872dd146104b2578063252d723a146104d2578063313ce567146104fe57600080fd5b806314b3b0771461042657806318160ddd1461044657806320d5bf371461046157600080fd5b8062113e081461032957806301be1f6c1461035557806306fdde0314610377578063095ea7b3146103b35780630fa604e4146103e357806313da0a141461040657600080fd5b3661032457005b600080fd5b34801561033557600080fd5b5061033e610a49565b60405161034c9291906134f9565b60405180910390f35b34801561036157600080fd5b50610375610370366004613565565b610b67565b005b34801561038357600080fd5b5060408051808201909152600a815269416c6c2d496e2d4f6e6560b01b60208201525b60405161034c9190613589565b3480156103bf57600080fd5b506103d36103ce3660046135d7565b610b91565b604051901515815260200161034c565b3480156103ef57600080fd5b506103f8610ba8565b60405190815260200161034c565b34801561041257600080fd5b50610375610421366004613603565b610bd2565b34801561043257600080fd5b50610375610441366004613565565b610c67565b34801561045257600080fd5b5067016345785d8a00006103f8565b34801561046d57600080fd5b506009546001600160a01b03165b6040516001600160a01b03909116815260200161034c565b34801561049f57600080fd5b50600954600160f81b900460ff166103d3565b3480156104be57600080fd5b506103d36104cd366004613629565b610c91565b3480156104de57600080fd5b50600b5463ffffffff165b60405163ffffffff909116815260200161034c565b34801561050a57600080fd5b506040516009815260200161034c565b34801561052657600080fd5b506103d3610535366004613629565b610ce3565b34801561054657600080fd5b50610375610555366004613678565b610d99565b34801561056657600080fd5b5061057a6105753660046136b1565b610edd565b6040805193845260208401929092526001600160a01b03169082015260600161034c565b3480156105aa57600080fd5b506103756105b9366004613603565b610f19565b3480156105ca57600080fd5b506103756105d9366004613565565b610f71565b3480156105ea57600080fd5b506103d36105f9366004613565565b6001600160a01b031660009081526004602052604090205460ff1690565b34801561062357600080fd5b506103d3610632366004613629565b610fb0565b34801561064357600080fd5b506103756106523660046136ca565b61101e565b34801561066357600080fd5b50600854600160e01b900463ffffffff166104e9565b34801561068557600080fd5b50610375610694366004613678565b611046565b3480156106a557600080fd5b506103756106b4366004613603565b611079565b3480156106c557600080fd5b506103f86106d4366004613565565b6110d1565b3480156106e557600080fd5b506103756110dc565b3480156106fa57600080fd5b506103756110f9565b34801561070f57600080fd5b506008546001600160a01b031661047b565b34801561072d57600080fd5b5061037561110d565b34801561074257600080fd5b50600a54600160d01b900463ffffffff166104e9565b34801561076457600080fd5b50610375610773366004613565565b61112a565b34801561078457600080fd5b5061047b611191565b34801561079957600080fd5b506103756112ff565b3480156107ae57600080fd5b506103756114f6565b3480156107c357600080fd5b506000546001600160a01b031661047b565b3480156107e157600080fd5b506103f86115fa565b3480156107f657600080fd5b5060408051808201909152600381526241493160e81b60208201526103a6565b34801561082257600080fd5b5061082b61161f565b60405161034c91906136e7565b34801561084457600080fd5b50610375611681565b34801561085957600080fd5b506103d36108683660046135d7565b6117ea565b34801561087957600080fd5b50600b54640100000000900463ffffffff166104e9565b34801561089c57600080fd5b506103d36108ab366004613565565b6001600160a01b0316600090815260046020526040902054610100900460ff1690565b3480156108da57600080fd5b506103756108e9366004613603565b6117f7565b3480156108fa57600080fd5b50610375610909366004613603565b611880565b34801561091a57600080fd5b50610375610929366004613603565b6118ad565b34801561093a57600080fd5b506103756118db565b34801561094f57600080fd5b50600854600160c01b900463ffffffff166104e9565b34801561097157600080fd5b50610375610980366004613603565b611d53565b34801561099157600080fd5b506103f86109a03660046136fa565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205490565b3480156109d757600080fd5b506103756109e6366004613565565b611dd0565b3480156109f757600080fd5b50600a546001600160a01b031661047b565b348015610a1557600080fd5b50610375610a24366004613565565b611dfa565b348015610a3557600080fd5b50610375610a44366004613565565b611e2c565b6060806005805480602002602001604051908101604052809291908181526020018280548015610aa257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a84575b50505050509150815167ffffffffffffffff811115610ac357610ac3613728565b604051908082528060200260200182016040528015610aec578160200160208202803683370190505b50905060005b8251811015610b6257610b33838281518110610b1057610b1061373e565b60200260200101516001600160a01b031660009081526001602052604090205490565b828281518110610b4557610b4561373e565b602090810291909101015280610b5a8161376a565b915050610af2565b509091565b610b6f611e67565b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000610b9e338484611e94565b5060015b92915050565b600954600090610bcd90600160c01b900463ffffffff1667016345785d8a0000613783565b905090565b610bda611e67565b614e208163ffffffff161115610c415760405162461bcd60e51b815260206004820152602160248201527f4149313a204d6178696d756d207472616e7366657220746178206f66203230256044820152601760f91b60648201526084015b60405180910390fd5b6008805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b610c6f611e67565b600880546001600160a01b0319166001600160a01b0392909216919091179055565b6000610c9e848484611fb8565b6001600160a01b038416600090815260026020908152604080832033808552925290912054610cd9918691610cd49086906137a5565b611e94565b5060019392505050565b6009546000906001600160a01b0316336001600160a01b031614610d195760405162461bcd60e51b8152600401610c38906137b8565b60405163095ea7b360e01b81526001600160a01b0384811660048301526024820184905285919082169063095ea7b3906044015b6020604051808303816000875af1158015610d6c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d90919061380a565b95945050505050565b610da1611e67565b6001600160a01b038216600090815260046020526040902054600160501b900460ff1615610e375760405162461bcd60e51b815260206004820152603c60248201527f4149313a2043616e6e6f74206d616e6970756c61746520626c6f636b6c69737460448201527f20737461747573206f662061206c697175696469747920706169722e000000006064820152608401610c38565b8015610eac57600a54600160c01b900460ff1615610eac5760405162461bcd60e51b815260206004820152602c60248201527f4149313a20426c6f636b6c697374206164646974696f6e73206861766520626560448201526b32b7103234b9b0b13632b21760a11b6064820152608401610c38565b6001600160a01b03909116600090815260046020526040902080549115156101000261ff0019909216919091179055565b60078181548110610eed57600080fd5b60009182526020909120600390910201805460018201546002909201549092506001600160a01b031683565b610f21611e67565b600a54600160c81b900460ff1615610f4b5760405162461bcd60e51b8152600401610c3890613827565b6009805463ffffffff909216600160c01b0263ffffffff60c01b19909216919091179055565b6009546001600160a01b0316336001600160a01b031614610fa45760405162461bcd60e51b8152600401610c38906137b8565b610fad81612595565b50565b6009546000906001600160a01b0316336001600160a01b031614610fe65760405162461bcd60e51b8152600401610c38906137b8565b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820184905285919082169063a9059cbb90604401610d4d565b611026611e67565b60098054911515600160f81b026001600160f81b03909216919091179055565b61104e611e67565b6001600160a01b03919091166000908152600460205260409020805460ff1916911515919091179055565b611081611e67565b600a54600160c81b900460ff16156110ab5760405162461bcd60e51b8152600401610c3890613827565b6009805463ffffffff909216600160a01b0263ffffffff60a01b19909216919091179055565b6000610ba2826127e9565b6110e4611e67565b600a805460ff60c01b1916600160c01b179055565b611101611e67565b61110b6000612850565b565b611115611e67565b600a805460ff60c81b1916600160c81b179055565b6009546001600160a01b0316336001600160a01b03161461115d5760405162461bcd60e51b8152600401610c38906137b8565b4761116782612595565b600061117382476137a5565b60095490915061118c906001600160a01b0316826128a0565b505050565b6000600b60089054906101000a90046001600160a01b03166001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061120a919061387a565b6001600160a01b031663e6a4390530600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa15801561126c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611290919061387a565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa1580156112db573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcd919061387a565b6009546001600160a01b0316336001600160a01b0316146113325760405162461bcd60e51b8152600401610c38906137b8565b6000600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611387573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ab919061387a565b90506000600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611402573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611426919061387a565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114949190613897565b604051632e1a7d4d60e01b8152600481018290529091506001600160a01b03841690632e1a7d4d90602401600060405180830381600087803b1580156114d957600080fd5b505af11580156114ed573d6000803e3d6000fd5b50505050505050565b6114fe611e67565b600954600160f01b900460ff166115575760405162461bcd60e51b815260206004820152601d60248201527f4149313a2054726164696e67206d75737420626520656e61626c65642e0000006044820152606401610c38565b600954600160e01b900460ff16156115b15760405162461bcd60e51b815260206004820152601a60248201527f4149313a2054726164696e6720616c7265616479206f70656e2e0000000000006044820152606401610c38565b6009805460016affff00000000000000000160a01b03166a800000800000190000001960a11b1790556008805463ffffffff60a01b1916600160a01b63ffffffff431602179055565b600954600090610bcd90600160a01b900463ffffffff1667016345785d8a0000613783565b6060600680548060200260200160405190810160405280929190818152602001828054801561167757602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611659575b5050505050905090565b611689611e67565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d9050806001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116e0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611704919061387a565b6001600160a01b031663c9c6539630836001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611751573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611775919061387a565b6040516001600160e01b031960e085901b1681526001600160a01b039283166004820152911660248201526044016020604051808303816000875af11580156117c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117e6919061387a565b5050565b6000610b9e338484611fb8565b6117ff611e67565b620173188163ffffffff1611156118585760405162461bcd60e51b815260206004820152601d60248201527f4149313a204d6178696d756d2073656c6c20746178206f66203935252e0000006044820152606401610c38565b600b805463ffffffff9092166401000000000267ffffffff0000000019909216919091179055565b611888611e67565b6008805463ffffffff909216600160e01b026001600160e01b03909216919091179055565b6118b5611e67565b600a805463ffffffff909216600160d01b0263ffffffff60d01b19909216919091179055565b6118e3611e67565b600954600160f01b900460ff161561193d5760405162461bcd60e51b815260206004820152601d60248201527f4149313a2054726164696e6720697320616c7265616479206f70656e2e0000006044820152606401610c38565b600b805468010000000000000000600160e01b0319167b7a250d5630b4cf539739df2c5dacb4c659f2488d00000000000000001790819055737a250d5630b4cf539739df2c5dacb4c659f2488d906119b09030906001600160a01b03600160401b9091041667016345785d8a0000611e94565b6000816001600160a01b031663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119f0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a14919061387a565b6001600160a01b031663e6a4390530846001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015611a61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a85919061387a565b6040516001600160e01b031960e085901b1681526001600160a01b03928316600482015291166024820152604401602060405180830381865afa158015611ad0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611af4919061387a565b600b54909150600160401b90046001600160a01b031663f305d7194730611b1a816110d1565b600080611b2f6000546001600160a01b031690565b60405160e088901b6001600160e01b03191681526001600160a01b03958616600482015260248101949094526044840192909252606483015290911660848201524260a482015260c40160606040518083038185885af1158015611b97573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611bbc91906138b0565b5050600b5460405163095ea7b360e01b8152600160401b9091046001600160a01b03908116600483015260001960248301528316915063095ea7b3906044016020604051808303816000875af1158015611c1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c3e919061380a565b506040805160a08101825260008082526020808301828152838501838152606085018481526001608087018181526001600160a01b0399909916808752600490955296852095518654935192519151985161ffff1990941690151561ff00191617610100921515929092029190911769ffffffffffffffff000019166201000063ffffffff9283160269ffffffff000000000000191617600160301b91909716029590951760ff60501b1916600160501b951515959095029490941790915560068054928301815590527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b03191690911790555060098054600160f01b60ff60f01b19909116179055565b611d5b611e67565b620173188163ffffffff161115611db45760405162461bcd60e51b815260206004820152601c60248201527f4149313a204d6178696d756d2062757920746178206f66203935252e000000006044820152606401610c38565b600b805463ffffffff191663ffffffff92909216919091179055565b611dd8611e67565b600980546001600160a01b0319166001600160a01b0392909216919091179055565b611e02611e67565b6001600160a01b03166000908152600460205260409020805460ff60501b1916600160501b179055565b611e34611e67565b6001600160a01b038116611e5e57604051631e4fbdf760e01b815260006004820152602401610c38565b610fad81612850565b6000546001600160a01b0316331461110b5760405163118cdaa760e01b8152336004820152602401610c38565b6001600160a01b038316611ef65760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610c38565b6001600160a01b038216611f575760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610c38565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b03831661201c5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b6064820152608401610c38565b6001600160a01b03821661207e5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b6064820152608401610c38565b600081116120e05760405162461bcd60e51b815260206004820152602960248201527f5472616e7366657220616d6f756e74206d7573742062652067726561746572206044820152687468616e207a65726f60b81b6064820152608401610c38565b600080806120f66000546001600160a01b031690565b6001600160a01b0316866001600160a01b03161415801561212557506000546001600160a01b03868116911614155b801561213a57506001600160a01b0386163014155b801561215f57506001600160a01b03851660009081526004602052604090205460ff16155b801561218457506001600160a01b03861660009081526004602052604090205460ff16155b1561257a57600954600160f01b900460ff166121e25760405162461bcd60e51b815260206004820152601960248201527f4149313a2054726164696e67206e6f7420656e61626c65642e000000000000006044820152606401610c38565b600954600160e01b900460ff166122345760405162461bcd60e51b815260206004820152601660248201527520a4989d102a3930b234b733903737ba1037b832b71760511b6044820152606401610c38565b6001600160a01b038516600090815260046020526040902054610100900460ff1615801561228057506001600160a01b038616600090815260046020526040902054610100900460ff16155b6122c05760405162461bcd60e51b815260206004820152601160248201527020a4989d10213637b1b5b634b9ba32b21760791b6044820152606401610c38565b6001600160a01b038616600090815260046020526040902054600160501b900460ff1680156123045750600b546001600160a01b03868116600160401b9092041614155b1561240b57600b5460095463ffffffff9091169250600160f81b900460ff16156123c8576001600160a01b038516600090815260046020526040902054436201000090910463ffffffff16036123955760405162461bcd60e51b815260206004820152601660248201527520a4989d1027b732903a3c103832b910313637b1b59760511b6044820152606401610c38565b6001600160a01b0385166000908152600460205260409020805465ffffffff00001916620100004363ffffffff16021790555b60085443906123e690600290600160a01b900463ffffffff166138de565b63ffffffff1611156123fb576001925061257f565b612406858584612937565b61257f565b6001600160a01b038516600090815260046020526040902054600160501b900460ff16801561244f5750600b546001600160a01b03878116600160401b9092041614155b156125635750600954600190600160f81b900460ff16156124ea576001600160a01b038616600090815260046020526040902054436201000090910463ffffffff16036124d75760405162461bcd60e51b815260206004820152601660248201527520a4989d1027b732903a3c103832b910313637b1b59760511b6044820152606401610c38565b6001600160a01b03861660005260046020525b600b5460095463ffffffff6401000000009092048216935061251d91600160a01b9091041667016345785d8a0000613783565b620186a061252b8482613902565b61253b9063ffffffff168761391f565b6125459190613783565b11156124065760405162461bcd60e51b8152600401610c3890613936565b600854600160c01b900463ffffffff16915061257f565b600091505b61258d868686858786612a45565b505050505050565b6040805160028082526060820183528392600092919060208301908036833701905050905082816000815181106125ce576125ce61373e565b60200260200101906001600160a01b031690816001600160a01b031681525050600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015612641573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612665919061387a565b816001815181106126785761267861373e565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b81523060048201526000918416906370a0823190602401602060405180830381865afa1580156126cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f19190613897565b600b5460405163095ea7b360e01b81526001600160a01b03600160401b909204821660048201526024810183905291925084169063095ea7b3906044016020604051808303816000875af115801561274d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612771919061380a565b50600b5460405163791ac94760e01b8152600160401b9091046001600160a01b03169063791ac947906127b1908490600090879030904290600401613977565b600060405180830381600087803b1580156127cb57600080fd5b505af11580156127df573d6000803e3d6000fd5b5050505050505050565b6001600160a01b03811660009081526004602052604081205443600160301b90910463ffffffff160361283257506001600160a01b031660009081526003602052604090205490565b6001600160a01b038216600090815260016020526040902054610ba2565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b804710156128c35760405163cd78605960e01b8152306004820152602401610c38565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612910576040519150601f19603f3d011682016040523d82523d6000602084013e612915565b606091505b505090508061118c57604051630a12f52160e11b815260040160405180910390fd5b6000620186a06129478382613902565b6129579063ffffffff168561391f565b6129619190613783565b60095490915061298690600160a01b900463ffffffff1667016345785d8a0000613783565b8111156129a55760405162461bcd60e51b8152600401610c3890613936565b6009546129c790600160c01b900463ffffffff1667016345785d8a0000613783565b816129e7866001600160a01b031660009081526001602052604090205490565b6129f191906139b3565b1115612a3f5760405162461bcd60e51b815260206004820152601c60248201527f4149313a204f766572206d61782077616c6c657420616d6f756e742e000000006044820152606401610c38565b50505050565b60008060008415612ad757612a5b600288613783565b9250612a6783886137a5565b6001600160a01b0389166000908152600460209081526040808320805469ffffffff0000000000001916600160301b4363ffffffff160217905560019091528120549193509150612ab99088906139b3565b6001600160a01b038916600090815260036020526040902055612afe565b612ae18787612e3d565b909250905080612af183896137a5565b612afb91906137a5565b92505b6000612b0a82846139b3565b1115612b9157306000908152600160205260409020548190612b2d9084906139b3565b612b3791906139b3565b306000818152600160205260409020919091556001600160a01b038a167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef612b7f84866139b3565b60405190815260200160405180910390a35b8315612cba576000612ba383836139b3565b1115612c6a5760408051606081018252828152602081018481526001600160a01b038c81169383019384526007805460018101825560009190915292517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039094029384015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68983015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a90910180546001600160a01b031916919092161790555b886001600160a01b03167fae92ab4b6f8f401ead768d3273e6bb937a13e39827d19c6376e8fd4512a05d9a84604051612ca591815260200190565b60405180910390a2612cb5612f07565b612dd1565b6000612cc683836139b3565b1115612d8d5760408051606081018252828152602081018481526001600160a01b038b81169383019384526007805460018101825560009190915292517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68860039094029384015590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68983015591517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68a90910180546001600160a01b031916919092161790555b876001600160a01b03167fc55650ccda1011e1cdc769b1fbf546ebb8c97800b6072b49e06cd560305b1d6784604051612dc891815260200190565b60405180910390a25b612ddb8988613351565b612de58884613395565b876001600160a01b0316896001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef85604051612e2a91815260200190565b60405180910390a3505050505050505050565b600854600a5460009182918291612e6c9163ffffffff600160e01b909204821691600160d01b909104166138de565b63ffffffff1690506000620186a08563ffffffff1687612e8c919061391f565b612e969190613783565b600a5490915067ffffffffffffffff831690612ebf90600160d01b900463ffffffff168361391f565b612ec99190613783565b60085490935067ffffffffffffffff831690612ef290600160e01b900463ffffffff168361391f565b612efc9190613783565b935050509250929050565b6009805460ff60e81b1916600160e81b179055600a54600090612f409063ffffffff600160a01b9091041667016345785d8a0000613783565b905060008060006001600780549050612f5991906137a5565b90505b81612f66816139c6565b925050600060078281548110612f7e57612f7e61373e565b6000918252602091829020604080516060810182526003909302909101805480845260018201549484018590526002909101546001600160a01b03169183019190915290925090612fcf90866139b3565b612fd991906139b3565b9350848410612fe85750612ffb565b5080612ff3816139e9565b915050612f5c565b50306000908152600260209081526040808320600b54600160401b90046001600160a01b0316845290915290205482111561305757600b54613057903090600160401b90046001600160a01b031667016345785d8a0000611e94565b604080516002808252606082018352600092602083019080368337019050509050308160008151811061308c5761308c61373e565b60200260200101906001600160a01b031690816001600160a01b031681525050600b60089054906101000a90046001600160a01b03166001600160a01b031663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130ff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613123919061387a565b816001815181106131365761313661373e565b6001600160a01b039283166020918202929092010152600b546040516318cbafe560e01b8152600160401b909104909116906318cbafe590613185908690600090869030904290600401613977565b6000604051808303816000875af11580156131a4573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526131cc9190810190613a00565b506000836131dd47620f424061391f565b6131e79190613783565b905060005b8363ffffffff168110156132d457600754600090829061320e906001906137a5565b61321891906137a5565b905060006007828154811061322f5761322f61373e565b600091825260208083206040805160608101825260039094029091018054808552600182015493850193909352600201546001600160a01b031690830152909250620f42409061328090879061391f565b61328a9190613783565b90506000620f42408684602001516132a2919061391f565b6132ac9190613783565b90506132bd83604001518284613424565b5050505080806132cc9061376a565b9150506131ec565b5060005b8363ffffffff1681101561333c5760078054806132f7576132f7613abe565b600082815260208120600360001990930192830201818155600181019190915560020180546001600160a01b03191690559055806133348161376a565b9150506132d8565b50506009805460ff60e81b1916905550505050565b6001600160a01b0382166000908152600160205260409020546133759082906137a5565b6001600160a01b0390921660009081526001602052604090209190915550565b6001600160a01b038216600090815260016020526040812054900361340057600580546001810182556000919091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b0382166000908152600160205260409020546133759082906139b3565b600a546001600160a01b0316821561344c5760085461344c906001600160a01b0316846128a0565b8115612a3f57604051631aca7d3560e31b81526001600160a01b03858116600483015282169063d653e9a89084906024016000604051808303818588803b15801561349657600080fd5b505af11580156134aa573d6000803e3d6000fd5b505050505050505050565b600081518084526020808501945080840160005b838110156134ee5781516001600160a01b0316875295820195908201906001016134c9565b509495945050505050565b60408152600061350c60408301856134b5565b82810360208481019190915284518083528582019282019060005b8181101561354357845183529383019391830191600101613527565b5090979650505050505050565b6001600160a01b0381168114610fad57600080fd5b60006020828403121561357757600080fd5b813561358281613550565b9392505050565b600060208083528351808285015260005b818110156135b65785810183015185820160400152820161359a565b506000604082860101526040601f19601f8301168501019250505092915050565b600080604083850312156135ea57600080fd5b82356135f581613550565b946020939093013593505050565b60006020828403121561361557600080fd5b813563ffffffff8116811461358257600080fd5b60008060006060848603121561363e57600080fd5b833561364981613550565b9250602084013561365981613550565b929592945050506040919091013590565b8015158114610fad57600080fd5b6000806040838503121561368b57600080fd5b823561369681613550565b915060208301356136a68161366a565b809150509250929050565b6000602082840312156136c357600080fd5b5035919050565b6000602082840312156136dc57600080fd5b81356135828161366a565b60208152600061358260208301846134b5565b6000806040838503121561370d57600080fd5b823561371881613550565b915060208301356136a681613550565b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161377c5761377c613754565b5060010190565b6000826137a057634e487b7160e01b600052601260045260246000fd5b500490565b81810381811115610ba257610ba2613754565b60208082526032908201527f546f6b656e436c61776261636b3a2063616c6c6572206973206e6f74207468656040820152711022a92199181031b7b73a3937b63632b91760711b606082015260800190565b60006020828403121561381c57600080fd5b81516135828161366a565b60208082526033908201527f4149313a204c696d6974732068617665206265656e2072656d6f76656420616e604082015272321031b0b73737ba10313290393296b9b2ba1760691b606082015260800190565b60006020828403121561388c57600080fd5b815161358281613550565b6000602082840312156138a957600080fd5b5051919050565b6000806000606084860312156138c557600080fd5b8351925060208401519150604084015190509250925092565b63ffffffff8181168382160190808211156138fb576138fb613754565b5092915050565b63ffffffff8281168282160390808211156138fb576138fb613754565b8082028115828204841417610ba257610ba2613754565b60208082526021908201527f4149313a204f766572206d6178207472616e73616374696f6e20616d6f756e746040820152601760f91b606082015260800190565b85815284602082015260a06040820152600061399660a08301866134b5565b6001600160a01b0394909416606083015250608001529392505050565b80820180821115610ba257610ba2613754565b600063ffffffff8083168181036139df576139df613754565b6001019392505050565b6000816139f8576139f8613754565b506000190190565b60006020808385031215613a1357600080fd5b825167ffffffffffffffff80821115613a2b57600080fd5b818501915085601f830112613a3f57600080fd5b815181811115613a5157613a51613728565b8060051b604051601f19603f83011681018181108582111715613a7657613a76613728565b604052918252848201925083810185019188831115613a9457600080fd5b938501935b82851015613ab257845184529385019392850192613a99565b98975050505050505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220fa0f31a584a04205868335dbfd1aba26d63fa2aaed23c3a7ea1e825638d6120164736f6c63430008140033

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.