ETH Price: $3,519.38 (+2.52%)
Gas: 5 Gwei

Contract

0x0a508e87F09a04d7EE4968694230A222C5500BE2
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040199210432024-05-21 21:43:3559 days ago1716327815IN
 Create: SDLGECreator
0 ETH0.037074826.8804535

Latest 3 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
200460762024-06-08 9:00:1141 days ago1717837211
0x0a508e87...2C5500BE2
 Contract Creation0 ETH
200441352024-06-08 2:30:1141 days ago1717813811
0x0a508e87...2C5500BE2
 Contract Creation0 ETH
200433352024-06-07 23:49:2341 days ago1717804163
0x0a508e87...2C5500BE2
 Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SDLGECreator

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 100 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-06-03
*/

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
// optimize 100
/// Standard IERC20 interface
interface IERC20 {
    function totalSupply() external view returns (uint256);
    function decimals() external view returns (uint8);
    function balanceOf(address user) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

interface Reader {
    function isAdmin(address addy) external view returns (bool);
    function superAdmin(address addy) external view returns (bool);
    function isSetter(address addy) external view returns (bool);
    function fegAddress() external view returns(address);
    function uniswapV2Pair() external view returns(address);
    function sdDepAddy() external view returns (address);
    function breaker() external view returns (bool); //circuit breaked in case of an exploit to handle
    function setWhitelistContract(address addy, bool _bool) external;
    function currentRouter() external view returns(address);
    function wETH() external view returns(address);
    function LEAPDepAddy() external view returns(address);
    function isProtocol(address addy) external view returns(bool);
}

interface sdep{
    function sdOwner() external view returns(address);
    function backingLogicAddress() external view returns(address);
    function backingAsset() external view returns(address);
    function setLGE(address addy) external;
    function endLGE() external;
    function endLGE(address addy) external;
    function setWLOff(address token, bool _bool) external;
    function liquifyForBacking(uint256 amt) external returns(uint tokenAmountOut);
    function liquifyForAllBacking(address user, uint256 amt) external returns(uint tokenAmountOut);
    function oneTokentoBacking(uint amt) external view returns(uint256);
    function frontRun(address who, uint256 range, uint256 slip) external view returns(bool yes);
    function tokenBackingPair(address token) external view returns(address);
    function setTick(address who) external;
    function range() external view returns(uint256,uint256);
}

interface spre {
    function setInitial(address _sd, uint256 _supplyForLP, uint256 _devShare, uint256 _rate, uint256 _maxBuy, uint256 _startTime, uint256 _durationDays, uint256 _backingShare) external;
    function setVesting(uint256 _vestingDelay, uint256 _vestingRate) external;
    function dev() external view returns(address);
    function fee(address user) external view returns(uint256);
}

interface Dataport {
    function DATA_READ() external view returns(address);
}

contract SDLGECreator {    
    address public dataport = 0xcCeD1a96321B2B2a06E8F3F4B0B883dDD059968c;
    function createLGE(address owner, address backing, address token) external returns(address SDP) {
        require(sdep(token).sdOwner() == owner && Reader(Dataport(dataport).DATA_READ()).LEAPDepAddy() == msg.sender, "not owner");
        SDP = address(new SDLGE(msg.sender, owner, backing, block.timestamp, token));
        return SDP;
    }
}

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

        return account.code.length > 0;
    }

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

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


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

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

/// Transfer Helper to ensure the correct transfer of the tokens or ETH
library SafeTransfer {
    using Address for address;
    /** Safe Transfer asset from one wallet with approval of the wallet
    * @param erc20: the contract address of the erc20 token
    * @param from: the wallet to take from
    * @param amount: the amount to take from the wallet
    **/
    function _pullUnderlying(IERC20 erc20, address from, uint amount) internal
    {
        safeTransferFrom(erc20,from,address(this),amount);
    }

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /** Safe Transfer asset to one wallet from within the contract
    * @param erc20: the contract address of the erc20 token
    * @param to: the wallet to send to
    * @param amount: the amount to send from the contract
    **/
    function _pushUnderlying(IERC20 erc20, address to, uint amount) internal
    {
        safeTransfer(erc20,to,amount);
    }

    /** Safe Transfer ETH to one wallet from within the contract
    * @param to: the wallet to send to
    * @param value: the amount to send from the contract
    **/
    function safeTransferETH(address to, uint256 value) internal {
        (bool success,) = to.call{value : value}(new bytes(0));
        require(success, 'TransferHelper::safeTransferETH: ETH transfer failed');
    }

    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SafeERC20: low");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 op");
        }
    }
    
    function safeApprove(IERC20 token, address spender, uint256 value) 
    internal {
    // safeApprove should only be called when setting an initial allowance,
    // or when resetting it to zero. To increase and decrease it, use
    // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
    require(
        (value == 0) || (token.allowance(address(this), spender) == 0)
    );
    _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
}

interface SD2 {
    function sdOwner() external view returns(address);
    function balanceOf(address account) external view returns(uint256);
    function BackingLogicAddress() external view returns(address);
    function uniswapV2Pair() external view returns(address);
    function setLGE() external;
    function LGE() external view returns(bool);
}

interface Swap {    
    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external;
    function deposit() external payable;
    function withdraw(uint wad) external;
    function getPair(address token0, address token1) external view returns(address);
    function factory() external view returns(address);
    function createPair(address tokenA, address tokenB) external returns (address pair);
}

contract SDLGE {
    mapping(address => LGErs) public buyer; // user entry data
    mapping(address => LGErsLP) public buyerLP; // user LP data
    address public SD; // Token which is staked
    address public uniswapV2Pair;
    address public uniswapV2PairFEG;
    address private constant dead = 0x000000000000000000000000000000000000dEaD;
    address public deployer; // LGE deployer
    address public owner; // LGE creator
    address public backingAsset; // Backing asset of the SmartDeFi
    address[] public entered; // All LGE Entrants
    address[] public whitelist; // All whitelisted addresses
    uint256 public startTime; // LGE Starttime
    uint256 public endTime; // LGE Endtime
    uint256 public duration; // duration of LGE in days
    uint256 public raised; // Total raised
    uint256 public sold; // Tokens allocated for Liquidity
    uint256 public rateCurrent; // LP price rate
    uint256 public totalLP0; // Total Main LP
    uint256 public totalLP1; // Total FEG LP
    uint256 public totalClaimedLP0; // Total claimed Main LP
    uint256 public totalClaimedLP1; // Total claimed FEG LP
    uint256 public whiteListEntered; // Total whitelist spots that have entered LGE
    uint256 public devShare; // Share of vested LP for dev
    uint256 public backingShare; // Percentage of LGE raised towards backing. 100 raised with 20 backingShare = 20 to backing 80 to LP
    uint256 public totalTokensVested; // Total vested tokens by dev
    uint256 private _status = 1;
    uint256 public soldOutTime;
    bool private setup; // LGE base setup
    bool public vestSetup; // LP Vesting setup
    bool public completeSetup; // All set up complete
    bool public started; // LGE Started
    bool public ended; // LGE ended
    bool public aborted; // LGE aborted, if endtime and softcap not met can abort.
    bool public soldOut; // LGE is soldout
    bool public SAFU; // LGE has lowest risk of loss, 100% total supply given to LP and 10% devShare or under.
    bool eu;
    LGE public pre; // Main LGE base info
    tokenVesting[] public vest; // Vested tokens of dev
    event EnterLGE(address buyer, uint256 amount);
    event ExitLGE(address buyer, uint256 amount);
    event EndLGE();
    event Claim0(address addy, uint256 LP0);
    event Claim1(address addy, uint256 LP1);
    event vestedToken(uint256 amount, uint256 unlockTime, uint256 vestID);
    event WithdrawVestedToken(uint256 amount, uint256 vestID);
    event LockLP(address user, uint256 unlocktime);
    event EditLGE(uint256 choice, uint256 input);

    constructor(address dep, address own, address _backing, uint256 time, address sd) {
        deployer = dep;
        owner = own;
        backingAsset = _backing;
        SD = sd; time;
    }

    receive() external payable {
        if(started && !soldOut && !ended) {
            if(!eu) {
            enterLGE(msg.sender);
            }
        }
    }

    struct LGE {
        uint256  supplyForLP;
        uint256  softCap;
        uint256  hardCap;
        uint256  maxBuy;
        uint256  vestingDelay;
        uint256  vestingRounds;
        uint256  vestingStartTime;
        bool  whiteListEnabled;
        uint256 whiteListCount;
    }

    struct tokenVesting {   
        uint256  vestingAmount;     
        uint256  vestingEnd;
        uint256  vestingClaimed;
    }

    struct LGErs {
        uint256 totAmtIn;
        uint256 tok;
        bool returned;
        bool aborted;
        bool whiteListed;
    }

    struct LGErsLP {
        uint256 lpInitial0;
        uint256 lpInitial1;
        uint256 lpClaimed0;
        uint256 lpClaimed1;
        uint256 lp0Rate;
        uint256 lp1Rate;
        uint256 lastClaimedLP;
    }

    modifier nonReentrant() {
        require(_status == 1, "reentrant");
        _status = 0;
        _;
        _status = 1;
    }

    function DATA_READ() public view returns(address) {
       return Dataport(0xcCeD1a96321B2B2a06E8F3F4B0B883dDD059968c).DATA_READ();
    }

    function FEG() public view returns(address) {
        return Reader(DATA_READ()).fegAddress();
    }

    function fegPair() internal view returns(address) {
        return Reader(FEG()).uniswapV2Pair();
    }

    function UNISWAP_V2_ROUTER() public view returns(address) {
        return Reader(DATA_READ()).currentRouter();
    }
    
    function wETH() public view returns(address) {
        return Reader(DATA_READ()).wETH();
    }

// ********************** Start LGE Base Section

    // function to end LGE on hardcap
    function close(uint256 minFEGOut, uint256 minBackOut) internal {
        address feg = FEG();
        (uint256 range, uint256 slip) = sdep(deployer).range();
        if(range > 0) {
        require(!sdep(Reader(DATA_READ()).sdDepAddy()).frontRun(feg, range, slip), "Front run");
        }
        if(backingShare > 0) {
        settleBacking(minBackOut);
        }
        address weth = wETH();
        uint256 FEGfee = IERC20(weth).balanceOf(address(this)) * spre(deployer).fee(address(this)) / 1000;
        uint256 tokensForFEGPair = pre.supplyForLP * spre(deployer).fee(address(this)) / 1000;
        uint256 tokensForPair = pre.supplyForLP - tokensForFEGPair;
        SafeTransfer.safeApprove(IERC20(weth), UNISWAP_V2_ROUTER(), FEGfee);
        address[] memory path = new address[](2);
        path[0] = weth;
        path[1] = feg;
        Swap(UNISWAP_V2_ROUTER()).swapExactTokensForTokensSupportingFeeOnTransferTokens(
            FEGfee,
            minFEGOut,
            path,
            address(this),
            block.timestamp
        );
        SafeTransfer._pushUnderlying(IERC20(SD), uniswapV2Pair, tokensForPair);
        SafeTransfer._pushUnderlying(IERC20(weth), uniswapV2Pair, IERC20(weth).balanceOf(address(this)));   
        totalLP0 = Swap(uniswapV2Pair).mint(address(this));   
        totalLP0 = totalLP0 * 98 / 100;
        buyerLP[owner].lpInitial0 = devShare > 0 ? totalLP0 * devShare / 100 : 0;
        buyerLP[owner].lp0Rate = buyerLP[owner].lpInitial0 / pre.vestingRounds;
        SafeTransfer._pushUnderlying(IERC20(feg), uniswapV2PairFEG, IERC20(feg).balanceOf(address(this)));
        SafeTransfer._pushUnderlying(IERC20(SD), uniswapV2PairFEG, tokensForFEGPair);
        totalLP1 = Swap(uniswapV2PairFEG).mint(address(this));
        totalLP1 = totalLP1 * 98 / 100;
        buyerLP[owner].lpInitial1 = devShare > 0 ? totalLP1 * devShare / 100 : 0;
        buyerLP[owner].lp1Rate = buyerLP[owner].lpInitial1 / pre.vestingRounds;
        pre.vestingStartTime = block.timestamp;
        emit EndLGE();
    }

    // function called when LGE reached hardCap or endTime passed and above softCap
    function endLGE(uint256 minFEGOut, uint256 minBackOut) external { 
        require(!aborted && !ended && started, "already");
        require(msg.sender == owner || Reader(DATA_READ()).isAdmin(msg.sender));
        if(block.timestamp > endTime && raised < pre.softCap) {
        endTime = block.timestamp + duration;
        }
        else{
        require(soldOut || (block.timestamp > endTime && raised >= pre.softCap));     
        close(minFEGOut, minBackOut);
        sdep(deployer).endLGE(SD);
        ended = true;
        endTime = block.timestamp;
        }
    }

    // function to abortLGE must not be already aborted, not ended and raised is below softCap.
    function abortLGE() external {     
        require(!aborted && !ended, "already");
        require(raised < pre.softCap, "scap");
        aborted = true;
        saveTokens(SD);
        sdep(deployer).setWLOff(SD, false);
        sdep(deployer).endLGE(SD);
        SAFU = false;
        emit EndLGE();
    }
    
    // editLGE enter choice of option below with input data to change, only LGE creator can call. Must not be started or aborted
    function editLGE(uint256 choice, uint256 input) external {
        require(msg.sender == owner);
        require((!started && !aborted), "started");
        if(choice == 0) {
            require(input >= block.timestamp + 15 minutes, "past");
            startTime = input;
            endTime = startTime + duration;
        }
        if(choice == 1) {
            require(input <= 90 && input >= 1, " 90/1");
            duration = input * 1 days;
            endTime = startTime + duration;
        }
        if(choice == 2) {
            require(input <= 50, "50");
            devShare = input;
        }
        if(choice == 3) {
            require(input <= 50, "50/1");
            backingShare = input;
        }
        if(choice == 4) {
            pre.hardCap = input;
            rateCurrent = pre.supplyForLP / input;
            pre.softCap = input / 3;
            pre.maxBuy = pre.maxBuy > input ? input : pre.maxBuy;
        }
        if(choice == 5) {
            require(input <= IERC20(SD).totalSupply() && input <= (type(uint128).max - 1), "total supply");
            uint256 a = pre.supplyForLP;
            if(input > a) {
            SafeTransfer._pullUnderlying(IERC20(SD), msg.sender, input - pre.supplyForLP);
            }
            if(input <= a) {
            SafeTransfer._pushUnderlying(IERC20(SD), msg.sender, pre.supplyForLP - input);
            }
            pre.supplyForLP = input;
            require(pre.supplyForLP > 0, "zero");
            pre.hardCap = pre.supplyForLP / rateCurrent;
            pre.softCap = pre.hardCap / 3;
            SAFU = (input >= (IERC20(SD).totalSupply() * 98 / 100) && devShare < 11) ? true : false;
        }
        if(choice == 6) {
        require(input <= 90 && input >= 7, "90/7");
            pre.vestingDelay = input * 1 days;
        }
        if(choice == 7) {
        require(input <= 20 && input >= 5, "20/5");
            pre.vestingRounds = input;
        }    
        if(choice == 8) {
        require(input >= 1e16, "1e16");
            pre.maxBuy = input > pre.hardCap ? pre.hardCap : input;
        }    
        emit EditLGE(choice, input);
    }

    // initial set up function 
    function setInitial(uint256 _supplyForLP, uint256 _devShare, uint256 _hardcap, uint256 _maxbuy, uint256 _startTime, uint256 _backingShare) external {
        require(!setup && msg.sender == deployer);
        owner = SD2(SD).sdOwner();
        uniswapV2Pair = SD2(SD).uniswapV2Pair();
        setup = true;
        pre.supplyForLP = _supplyForLP;
        pre.hardCap = _hardcap; 
        rateCurrent = _supplyForLP / _hardcap;       
        pre.softCap = _hardcap / 3;
        pre.maxBuy = _maxbuy;
        startTime = _startTime;
        duration = 90 * 1 days;
        endTime = _startTime + duration;
        devShare = _devShare;
        backingShare = _backingShare;
    }    

    // function to auto start LGE after starttime
    function Started() public {
        if(!started) {
        if(block.timestamp > startTime){
        started = true;
        }
        }
    }

// ********************** End LGE Base Section
// ********************** Token Vesting Section

    // LGE owner can vest the SD token here.
    function vestToken(uint256[] memory amount, uint256[] memory _vestingEnd) external nonReentrant{        
        require(msg.sender == owner);
        require(amount.length == _vestingEnd.length, "length");
        uint256 a;
        for(uint256 i = 0; i < amount.length; i++) {
        a += amount[i];
        vest.push(tokenVesting(amount[i],_vestingEnd[i],0));
        emit vestedToken(amount[i], _vestingEnd[i], i);
        }
        totalTokensVested += a;
        SafeTransfer._pullUnderlying(IERC20(SD), msg.sender, a);
    }

    // LGE owner can withdraw expired vested tokens
    function withdrawVestedToken(uint256[] memory vestID) external nonReentrant{       
        require(msg.sender == owner);
        uint256 totalOut;
        uint256 a;
        for(uint256 i = 0; i < vestID.length; i++) {
        require((block.timestamp > vest[vestID[i]].vestingEnd || aborted) && vest[vestID[i]].vestingClaimed == 0, "already");
        a = vest[vestID[i]].vestingAmount;
        totalOut += a;
        vest[vestID[i]].vestingClaimed = a;
        emit WithdrawVestedToken(a, vestID[i]);
        }
        totalTokensVested -= totalOut;
        SafeTransfer._pushUnderlying(IERC20(SD), owner, totalOut);
    }

    // Initial setup function
    function setVesting(uint256 _vestingDelay, uint256 _vestingRate, address fp) external {
        require(!vestSetup && msg.sender == deployer);
        require(_vestingDelay <= 90 && _vestingDelay >= 7, "90/7");
        vestSetup = true;
        pre.vestingDelay = _vestingDelay * 1 days; // enter in days
        pre.vestingRounds = _vestingRate;
        completeSetup = true;
        uniswapV2PairFEG = fp;
        if(pre.supplyForLP >= (IERC20(SD).totalSupply() * 98 / 100) && devShare < 11){
        SAFU = true;
        }
    }

    // function to check vesting round
    function vestingRound() public view returns(uint256) {
        uint256 a = pre.vestingDelay;
        uint256 round = 1; 
        for(uint256 i = 0; i < pre.vestingRounds; i++) {
        if(block.timestamp > pre.vestingStartTime + (round * a)){
        round += 1;
        }       
        if(block.timestamp <= pre.vestingStartTime + (round * a) || round == pre.vestingRounds){
        break;
        } 
        }
        return round;
    }

// ********************** End Token Vesting Section
// ********************** Start LGE Whitelist Section

    function whitelistLength() public view returns(uint256) {
        return whitelist.length;
    }

    // function to enable whitelist LGE must be done before LGE has started
    function setWhitelist(bool _bool) external {
        require(msg.sender == owner);
        require(!started || (started && pre.whiteListEnabled && !_bool));
        pre.whiteListEnabled = _bool;
    }

    // function for adding bulk initial whitelist data
    function addBulkWhitelist(address[] memory _list) external {
        require(msg.sender == owner);
        require(!started);
        pre.whiteListEnabled = true;
        uint256 length = _list.length;
        for(uint256 i = 0; i < length; i++) {
            require(!buyer[_list[i]].whiteListed && _list[i] != owner, "already");
            buyer[_list[i]].whiteListed = true;
            pre.whiteListCount += 1;
            whitelist.push(_list[i]);
        }
    }

    // function to edit whitelist spot
    function editWhitelist(address user, bool _live) external {
        require(msg.sender == owner && user != owner);
        if(!buyer[user].whiteListed) { // if not already whitelisted require _live = true and LGE not started
            require(_live);
            require(!started);
            pre.whiteListEnabled = true;
            whitelist.push(user);
        }
        require(pre.whiteListEnabled);
        if(buyer[user].whiteListed) { // if already whitelisted require _live = false and LGE started with user not have entered yet.
            require(!_live);
            require(buyer[user].totAmtIn == 0);
        }
        buyer[user].whiteListed = _live;
        pre.whiteListCount = buyer[user].whiteListed ? pre.whiteListCount + 1 : pre.whiteListCount - 1;
        pre.whiteListEnabled = whiteListEntered == pre.whiteListCount ? false : true;
    }

// ********************** End LGE Whitelist Section
// ********************** Enter LGE Section

    // check if LGE has whitelist enabled, if true then require user is whitelisted. After whiteListCount has reached whiteListEntered allow public to enter LGE
    function preCheck(address user) internal {
        if(pre.whiteListEnabled){
            require(buyer[user].whiteListed, "not wl");    
            whiteListEntered = buyer[user].totAmtIn == 0 ? whiteListEntered + 1 : whiteListEntered;
            if(whiteListEntered == pre.whiteListCount){pre.whiteListEnabled = false;}  
        }
    }

    // LGE entry quote
    function quoteBuy(uint256 amount) external view returns(uint256 quote) {
        quote = amount * rateCurrent;
    }
    
    // enter LGE with ETH
    function enterLGE(address user) public payable nonReentrant {
        Started();
        if(!Reader(DATA_READ()).isProtocol(msg.sender)) {
        user = msg.sender;
        }
        require(!soldOut && !aborted && started, "sout");
        require(!buyer[user].returned, "exited");
        require(msg.value > 0, "no amount");
        if(block.timestamp < endTime && endTime < block.timestamp + 5 minutes) {
            endTime += 5 minutes;
        }
        require(block.timestamp < endTime && user != owner, "time up");
        preCheck(user);
        Swap(wETH()).deposit{value:msg.value}();
        raised += msg.value;
        if(buyer[user].totAmtIn == 0) {
            entered.push(user);
        }
        buyer[user].totAmtIn += msg.value;
        require(buyer[user].totAmtIn <= pre.maxBuy, "MB");
        uint256 amtBought = msg.value * rateCurrent;
        buyer[user].tok += amtBought;
        sold += amtBought;
        require(raised <= pre.hardCap, "oversold");
        if(raised == pre.hardCap){
            soldOut = true;
            soldOutTime = block.timestamp;
        }
        emit EnterLGE(user, msg.value);
    }

    // enter LGE with token, input token to sell, amount to sell and minAmountOut of ETH for selling token for entering LGE with ETH.
    function enterLGEWithToken(address user, address token, uint256 amount, uint256 minAmountOut) external nonReentrant returns(uint256) {
        Started();
        if(!Reader(DATA_READ()).isProtocol(msg.sender)) {
        user = msg.sender;
        }
        require(token != SD, "invalid token");
        require(amount > 0, "no amount");
        require(!buyer[user].returned, "exited");
        address weth = wETH();
        require(!soldOut && !aborted && started, "sout");
        if(block.timestamp < endTime && endTime < block.timestamp + 5 minutes) {
            endTime += 5 minutes;
        }
        require(block.timestamp < endTime && user != owner, "time up");
        preCheck(user);
        if(buyer[user].totAmtIn == 0) {
            entered.push(user);
        }
        uint256 beforeToken = IERC20(token).balanceOf(address(this));        
        SafeTransfer.safeTransferFrom(IERC20(token), msg.sender, address(this), amount);
        uint256 amtToken = IERC20(token).balanceOf(address(this)) - beforeToken;
        uint256 amtE = IERC20(weth).balanceOf(address(this));
        convert(token, amtToken, minAmountOut);
        uint256 amtIn = IERC20(weth).balanceOf(address(this)) - amtE;
        require(amtIn > 0, "amtIn 0");
        raised += amtIn;
        buyer[user].totAmtIn += amtIn;
        require(buyer[user].totAmtIn <= pre.maxBuy, "MB");
        uint256 amtBought = amtIn * rateCurrent;
        buyer[user].tok += amtBought;
        sold += amtBought;
        require(raised <= pre.hardCap, "oversold");
        if(raised == pre.hardCap){
            soldOut = true;
            soldOutTime = block.timestamp;
        }
        emit EnterLGE(user, amtIn);
        return amtIn;
    }

    // convert token from enterLGEWithToken
    function convert(address token, uint256 amtToken, uint256 minAmountOut) internal {
        SafeTransfer.safeApprove(IERC20(token), UNISWAP_V2_ROUTER(), amtToken);
        address[] memory path = new address[](2);
        path[0] = token;
        path[1] = wETH();
        Swap(UNISWAP_V2_ROUTER()).swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amtToken,
            minAmountOut,
            path,
            address(this),
            block.timestamp
        );
    }
    
    // function for LGE participant to exit LGE with requirements listed below
    function emergencyExit() external nonReentrant {
        require(buyer[msg.sender].totAmtIn > 0, "no balance");
        require(totalLP0 == 0, "sout");
        if(soldOut) {
        require(block.timestamp > soldOutTime + 72 hours);
        }
        require(!buyer[msg.sender].returned && !buyer[msg.sender].aborted, "ret/abt");
        if(aborted) {
        buyer[msg.sender].aborted = true;
        }
        buyer[msg.sender].returned = true;
        uint256 ta = buyer[msg.sender].totAmtIn;
        raised -= ta;
        uint256 s = buyer[msg.sender].tok;
        sold -= s;
        buyer[msg.sender].totAmtIn = 0;
        buyer[msg.sender].tok = 0;
        if(buyer[msg.sender].whiteListed) {
        whiteListEntered -= 1;
        }
        eu = true;
        Swap(wETH()).withdraw(ta);
        eu = false;
        SafeTransfer.safeTransferETH(msg.sender, ta);
        emit ExitLGE(msg.sender, ta);
    }

// ********************** End Enter LGE Section
// ********************** Shares Section

    // after LGE completes user enableShares to activate vesting
    function enableShares() external nonReentrant {
        require(totalLP0 > 0 && msg.sender != owner, "no lp");
        require(buyerLP[msg.sender].lpInitial0 == 0, "claimed");
        buyerLP[msg.sender].lpInitial0 = (totalLP0 * (100 - devShare) / 100) * buyer[msg.sender].totAmtIn / raised;
        buyerLP[msg.sender].lpInitial1 = (totalLP1 * (100 - devShare) / 100) * buyer[msg.sender].totAmtIn / raised;
        buyerLP[msg.sender].lp0Rate = buyerLP[msg.sender].lpInitial0 / pre.vestingRounds;
        buyerLP[msg.sender].lp1Rate = buyerLP[msg.sender].lpInitial1 / pre.vestingRounds;
    }

    // check total vested LP for withdraw
    function checkShare(address user) public view returns(uint256 val0, uint256 val1) {
        val0 = 0; val1 = 0;
        uint256 vr = vestingRound();
        if(buyerLP[user].lpInitial0 > 0) {            
        if(block.timestamp > buyerLP[msg.sender].lastClaimedLP + 1 days) {
        if((buyerLP[user].lp0Rate * vr > buyerLP[user].lpClaimed0)) {            
        uint256 val00 = (buyerLP[user].lp0Rate * vr) - buyerLP[user].lpClaimed0 > buyerLP[user].lp0Rate ? buyerLP[user].lp0Rate : (buyerLP[user].lp0Rate * vr) - buyerLP[user].lpClaimed0;
        val0 = val00 + buyerLP[user].lpClaimed0 > buyerLP[user].lpInitial0 ? buyerLP[user].lpInitial0 - buyerLP[user].lpClaimed0 : val00;
        uint256 val11 = (buyerLP[user].lp1Rate * vr) - buyerLP[user].lpClaimed1 > buyerLP[user].lp1Rate ? buyerLP[user].lp1Rate : (buyerLP[user].lp1Rate * vr) - buyerLP[user].lpClaimed1;
        val1 = val11 + buyerLP[user].lpClaimed1 > buyerLP[user].lpInitial1 ? buyerLP[user].lpInitial1 - buyerLP[user].lpClaimed1 : val11;
        }
        }
        }
    }

    /*
    * @param val0: ETH value of main LP
    * @param val1: FEG of fegPair LP
    * @param back0: backing value of SD side of LP from main pair
    * @param back1: backing value of FEG side of LP from fegPair
    */
    function claimableShareValue(address user) public view returns(uint256 val0, uint256 val1, uint256 back0, uint256 back1) {
        uint256 max0 = buyerLP[user].lp0Rate * vestingRound();
        uint256 max1 = buyerLP[user].lp1Rate * vestingRound();
        if(max0 > buyerLP[user].lpClaimed0) {
        address weth = wETH();
        uint256 totLP0 = IERC20(uniswapV2Pair).totalSupply();
        uint256 totLP1 = IERC20(uniswapV2PairFEG).totalSupply();
        (max0, max1) = checkShare(user);
        back0 = sdep(sdep(SD).backingLogicAddress()).oneTokentoBacking(IERC20(SD).balanceOf(uniswapV2Pair) * max0 / totLP0);
        back1 = sdep(sdep(SD).backingLogicAddress()).oneTokentoBacking(IERC20(SD).balanceOf(uniswapV2PairFEG) * max1 / totLP1);
        val0 = IERC20(weth).balanceOf(uniswapV2Pair) * max0 / totLP0;
        val1 = IERC20(FEG()).balanceOf(uniswapV2PairFEG) * max1 / totLP1;
        }
    }
    
    // total of all unclaimed LP
    function totalUnclaimedLP() external view returns(uint256 max0, uint256 max1) {
        max0 = totalLP0  > totalClaimedLP0 ? totalLP0 - totalClaimedLP0 : 0;
        max1 = totalLP1 > totalClaimedLP1 ? totalLP1 - totalClaimedLP1 : 0;
    }

    // claim share with amount input as % of claimable share, 100 = 100% of claimable share, if share is over vestingRate then max claim sets to _vestingRate
    function claimShare(uint256 amount) public nonReentrant {
        require(ended && !aborted, "not ended");
        require(amount <= 100, "100% max");
        uint256 amt0;
        uint256 amt01;
        address weth = wETH();
        bool h;
        require(block.timestamp > buyerLP[msg.sender].lastClaimedLP + 1 days); // 1 day cool down, also used for ensuring of locking LP
        (amt0,amt01) = checkShare(msg.sender);
        if(msg.sender == owner) {
        if(buyerLP[msg.sender].lpClaimed0 == 0) {
        amt0 = amt0 * (51 - devShare) / 10;
        h = true;
        }
        }
        uint256 amt0a = amt0 * amount / 100;
        buyerLP[msg.sender].lpClaimed0 += amt0a;
        require((buyerLP[msg.sender].lpClaimed0 <= buyerLP[msg.sender].lpInitial0), "LPO");        
        SafeTransfer._pushUnderlying(IERC20(uniswapV2Pair), uniswapV2Pair, amt0a);
        Swap(uniswapV2Pair).burn(address(this));        
        totalClaimedLP0 += amt0a;
        emit Claim0(msg.sender, amt0a);

        if(msg.sender == owner) {
        if(buyerLP[msg.sender].lpClaimed1 == 0) {
        amt01 = amt01 * (51 - devShare) / 10;
        h = true;
        }
        }
        uint256 amt01a = amt01 * amount / 100;
        require((amt0a <= buyerLP[msg.sender].lp0Rate && amt01a <= buyerLP[msg.sender].lp1Rate) || (msg.sender == owner && h), "AM");
        buyerLP[msg.sender].lpClaimed1 += amt01a;
        require(buyerLP[msg.sender].lpClaimed1 <= buyerLP[msg.sender].lpInitial1, "LP1");        
        SafeTransfer._pushUnderlying(IERC20(uniswapV2PairFEG), uniswapV2PairFEG, amt01a);
        Swap(uniswapV2PairFEG).burn(address(this));
        preback(msg.sender);
        Swap(weth).withdraw(IERC20(weth).balanceOf(address(this)));
        SafeTransfer.safeTransferETH(msg.sender, address(this).balance);
        address f = FEG();
        SafeTransfer._pushUnderlying(IERC20(f), msg.sender, IERC20(f).balanceOf(address(this)));
        totalClaimedLP1 += amt01a;
        emit Claim1(msg.sender, amt01a);
        buyerLP[msg.sender].lastClaimedLP = block.timestamp;      
    }

// ********************** End Shares Section
// ********************** LP section

    // allow any user or dev to lock their LP, lastClaimedLP will add days which will trigger the cooldown on claim function blocking claiming
    function lockLP(uint256 _days) external {
        require(buyerLP[msg.sender].lpInitial0 > 0 && _days > 0, "no hold or days");
        require(block.timestamp + (_days * 1 days) > buyerLP[msg.sender].lastClaimedLP, "must be in future");
        buyerLP[msg.sender].lastClaimedLP = block.timestamp + (_days * 1 days);
        emit LockLP(msg.sender, buyerLP[msg.sender].lastClaimedLP);
    }

    // check LP lock
    function getLPLock(address user) external view returns(bool, uint256) {
        bool a = buyerLP[user].lastClaimedLP > block.timestamp ? true : false;
        uint256 b = a ? buyerLP[user].lastClaimedLP : 0;
        return (a, b);
    }
    
// ********************** End LP Section
// ********************** Start Backing Section

    // after LGE has reached hardCap settle backing share
    function settleBacking(uint256 minBackOut) private {
        uint256 backing = raised * backingShare / 100;
        address backingPool = sdep(SD).backingLogicAddress();
        address weth = wETH();
        // since we cannot track backing pool balance history before SD ticks enable we cannot check for front run.
        if(backingAsset != weth) {
        SafeTransfer.safeApprove(IERC20(weth), UNISWAP_V2_ROUTER(), backing);
            address[] memory path;
            path = new address[](2);
            path[0] = weth;
            path[1] = backingAsset;
            // BUY and SELL fee may apply
            Swap(UNISWAP_V2_ROUTER()).swapExactTokensForTokensSupportingFeeOnTransferTokens(
                backing,
                minBackOut,
                path,
                address(this),
                block.timestamp
        );
        SafeTransfer._pushUnderlying(IERC20(backingAsset), backingPool, IERC20(backingAsset).balanceOf(address(this)));
        }        
        if(backingAsset == weth) {
        SafeTransfer._pushUnderlying(IERC20(weth), backingPool, backing);
        } 
    }

    // call to burn SD from LP on claim function
    function preback(address user) internal {        
        address backingPool = sdep(SD).backingLogicAddress();
        uint256 b = IERC20(SD).balanceOf(address(this)) - totalTokensVested;
        uint256 c = IERC20(backingAsset).balanceOf(backingPool);
        if(c < 1e15) {
        SafeTransfer._pushUnderlying(IERC20(SD), dead, b);  
        }
        if(c >= 1e15) {
        SafeTransfer.safeApprove(IERC20(SD), backingPool, b);
        sdep(backingPool).liquifyForAllBacking(user, b);
        }
    }
    
// ********************** End Backing Section

    // LGE owner can save lost tokens, cannot remove FEG, LP or backing asset. If LGE has started and token == sd require LGE aborted.
    function saveTokens(address token) public nonReentrant {
        require(msg.sender == owner);
        require(token != FEG() && token != uniswapV2Pair && token != uniswapV2PairFEG);
        if(token == backingAsset || token == wETH()) {
        require(raised == 0, "raised != 0");
        }
        uint256 a = IERC20(token).balanceOf(address(this));
        if(token == SD) {
        if(started) {
        require(aborted, "rax");
        }
        a = a - totalTokensVested;
        pre.supplyForLP = 0;
        pre.hardCap = 0;
        pre.softCap = 0;
        }
        if(a > 0) {
        SafeTransfer._pushUnderlying(IERC20(token), owner, a);
        }
        if(address(this).balance > 0) {
        SafeTransfer.safeTransferETH(owner, address(this).balance);
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"backing","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"createLGE","outputs":[{"internalType":"address","name":"SDP","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dataport","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60806040525f80546001600160a01b03191673cced1a96321b2b2a06e8f3f4b0b883ddd059968c179055348015610034575f80fd5b50615ff8806100425f395ff3fe608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063ab20213b14610038578063abddca0d14610067575b5f80fd5b61004b610046366004610289565b610079565b6040516001600160a01b03909116815260200160405180910390f35b5f5461004b906001600160a01b031681565b5f836001600160a01b0316826001600160a01b0316638c00e9b96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e491906102d1565b6001600160a01b03161480156101c957505f54604080516385523a1b60e01b8152905133926001600160a01b0316916385523a1b9160048083019260209291908290030181865afa15801561013b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061015f91906102d1565b6001600160a01b03166381b832376040518163ffffffff1660e01b8152600401602060405180830381865afa15801561019a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101be91906102d1565b6001600160a01b0316145b6102055760405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b604482015260640160405180910390fd5b338484428560405161021690610265565b6001600160a01b039586168152938516602085015291841660408401526060830152909116608082015260a001604051809103905ff08015801561025c573d5f803e3d5ffd5b50949350505050565b615ccf806102f483390190565b6001600160a01b0381168114610286575f80fd5b50565b5f805f6060848603121561029b575f80fd5b83356102a681610272565b925060208401356102b681610272565b915060408401356102c681610272565b809150509250925092565b5f602082840312156102e1575f80fd5b81516102ec81610272565b939250505056fe6080604052600160185534801562000015575f80fd5b5060405162005ccf38038062005ccf8339810160408190526200003891620000a9565b600580546001600160a01b039687166001600160a01b0319918216179091556006805495871695821695909517909455600780549386169385169390931790925550600280549190931691161790556200010c565b80516001600160a01b0381168114620000a4575f80fd5b919050565b5f805f805f60a08688031215620000be575f80fd5b620000c9866200008d565b9450620000d9602087016200008d565b9350620000e9604087016200008d565b92506060860151915062000100608087016200008d565b90509295509295909350565b615bb5806200011a5f395ff3fe608060405260043610610333575f3560e01c806380b62b70116101ad578063cc142b07116100ea578063e5ba08961161008e578063e5ba089614610afd578063ef0fc79014610b1c578063f0ea4bfc14610b52578063f242862114610b67578063f2db8b2614610b7b578063f958a65714610b90578063fca3c0aa14610baf578063fe46580714610bc4575f80fd5b8063cc142b07146109c5578063cc4e508d146109e4578063ce2c178a14610a03578063d5d0526e14610a18578063d5f3948814610aa2578063d8cea0ec14610ac1578063daf2de1314610ad5578063dfc0cdf614610aea575f80fd5b806398c99c9e1161015157806398c99c9e146108965780639de2b11b146108b5578063a82ed9ec146108ca578063aa6ce92a146108de578063aed04fae146108fc578063b774820814610911578063bc58a4aa14610991578063bebd0fd3146109b0575f80fd5b806380b62b701461078757806383d98967146107a757806385523a1b146107c657806385611bd8146107da57806388cb214e14610819578063893da6c9146108385780638aea8f71146108585780638da5cb5b14610877575f80fd5b806345ea69da1161027b57806359ea287d1161021f57806359ea287d1461063e5780636104113e146106bd5780636a760b80146106d15780636ac5e0fb1461070b57806370c88b791461072a57806378bb51641461073f57806378e97925146107535780637ebd1b3014610768575f80fd5b806345ea69da1461055c578063484d27fc1461057b57806349bd5a5e1461059a5780634adb3374146105b95780634beb394c146105d85780634ed48edc146105f757806354ae78ee1461060b5780635641ec031461062a575f80fd5b806310117e85116102e257806310117e851461046d57806312fa6feb1461048157806316269d95146104a15780631f2698ab146104ca5780633197cbb6146104ea57806333788622146104ff578063384002a21461051e57806340519a531461053d575f80fd5b806302c7e7af146103965780630363799a146103be5780630415af81146103d3578063093a9fbc146103e85780630cc03e7a146104095780630dbc6b3e146104285780630fb5a6b414610458575f80fd5b3661039257601a546301000000900460ff16801561035b5750601a54600160301b900460ff16155b80156103715750601a54600160201b900460ff16155b1561039057601a54600160401b900460ff166103905761039033610be3565b005b5f80fd5b3480156103a1575f80fd5b506103ab600e5481565b6040519081526020015b60405180910390f35b3480156103c9575f80fd5b506103ab60135481565b3480156103de575f80fd5b506103ab60175481565b3480156103f3575f80fd5b506103fc610fe7565b6040516103b591906154c9565b348015610414575f80fd5b506103906104233660046154dd565b611054565b348015610433575f80fd5b50601a5461044890600160381b900460ff1681565b60405190151581526020016103b5565b348015610463575f80fd5b506103ab600c5481565b348015610478575f80fd5b506103906116c3565b34801561048c575f80fd5b50601a5461044890600160201b900460ff1681565b3480156104ac575f80fd5b506104b5611891565b604080519283526020830191909152016103b5565b3480156104d5575f80fd5b50601a54610448906301000000900460ff1681565b3480156104f5575f80fd5b506103ab600b5481565b34801561050a575f80fd5b506103906105193660046155c8565b6118dd565b348015610529575f80fd5b506002546103fc906001600160a01b031681565b348015610548575f80fd5b506103906105573660046154dd565b611b05565b348015610567575f80fd5b506103906105763660046155fa565b611c2e565b348015610586575f80fd5b5061039061059536600461565a565b611e06565b3480156105a5575f80fd5b506003546103fc906001600160a01b031681565b3480156105c4575f80fd5b506103906105d336600461568e565b6123a3565b3480156105e3575f80fd5b506103ab6105f23660046154dd565b6124fb565b348015610602575f80fd5b50610390612510565b348015610616575f80fd5b506104b56106253660046156c4565b6126b1565b348015610635575f80fd5b50610390612934565b348015610649575f80fd5b50601b54601c54601d54601e54601f54602054602154602254602354610677989796959493929160ff169089565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c0840152151560e0830152610100820152610120016103b5565b3480156106c8575f80fd5b506103ab612bef565b3480156106dc575f80fd5b506106f06106eb3660046154dd565b612c67565b604080519384526020840192909252908201526060016103b5565b348015610716575f80fd5b506103906107253660046156e6565b612c98565b348015610735575f80fd5b506103ab60145481565b34801561074a575f80fd5b506009546103ab565b34801561075e575f80fd5b506103ab600a5481565b348015610773575f80fd5b506103fc6107823660046154dd565b612e32565b348015610792575f80fd5b50601a5461044890600160281b900460ff1681565b3480156107b2575f80fd5b506007546103fc906001600160a01b031681565b3480156107d1575f80fd5b506103fc612e5a565b3480156107e5575f80fd5b506107f96107f43660046156c4565b612eab565b6040805194855260208501939093529183015260608201526080016103b5565b348015610824575f80fd5b50610390610833366004615732565b613426565b348015610843575f80fd5b50601a5461044890600160301b900460ff1681565b348015610863575f80fd5b50601a546104489062010000900460ff1681565b348015610882575f80fd5b506006546103fc906001600160a01b031681565b3480156108a1575f80fd5b506103906108b03660046156c4565b6135e0565b3480156108c0575f80fd5b506103ab600f5481565b3480156108d5575f80fd5b506103fc613824565b3480156108e9575f80fd5b50601a5461044890610100900460ff1681565b348015610907575f80fd5b506103ab60155481565b34801561091c575f80fd5b5061096161092b3660046156c4565b5f6020819052908152604090208054600182015460029092015490919060ff808216916101008104821691620100009091041685565b6040805195865260208601949094529115159284019290925290151560608301521515608082015260a0016103b5565b34801561099c575f80fd5b506103906109ab36600461565a565b613868565b3480156109bb575f80fd5b506103ab60165481565b3480156109d0575f80fd5b506103906109df366004615769565b613a2f565b3480156109ef575f80fd5b506103ab6109fe3660046157f3565b613be6565b348015610a0e575f80fd5b506103ab60125481565b348015610a23575f80fd5b50610a6d610a323660046156c4565b600160208190525f91825260409091208054918101546002820154600383015460048401546005850154600690950154939492939192909187565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103b5565b348015610aad575f80fd5b506005546103fc906001600160a01b031681565b348015610acc575f80fd5b5061039061420f565b348015610ae0575f80fd5b506103ab60115481565b610390610af83660046156c4565b610be3565b348015610b08575f80fd5b506004546103fc906001600160a01b031681565b348015610b27575f80fd5b50610b3b610b363660046156c4565b614240565b6040805192151583526020830191909152016103b5565b348015610b5d575f80fd5b506103ab600d5481565b348015610b72575f80fd5b506103fc6142a4565b348015610b86575f80fd5b506103ab60105481565b348015610b9b575f80fd5b50610390610baa366004615836565b6142e8565b348015610bba575f80fd5b506103ab60195481565b348015610bcf575f80fd5b506103fc610bde3660046154dd565b614352565b601854600114610c0e5760405162461bcd60e51b8152600401610c0590615851565b60405180910390fd5b5f601855610c1a61420f565b610c22612e5a565b6001600160a01b0316632c86cba3336040518263ffffffff1660e01b8152600401610c4d91906154c9565b602060405180830381865afa158015610c68573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c8c9190615874565b610c935750335b601a54600160301b900460ff16158015610cb75750601a54600160281b900460ff16155b8015610ccc5750601a546301000000900460ff165b610ce85760405162461bcd60e51b8152600401610c059061588f565b6001600160a01b0381165f9081526020819052604090206002015460ff1615610d235760405162461bcd60e51b8152600401610c05906158ad565b5f3411610d425760405162461bcd60e51b8152600401610c05906158cd565b600b5442108015610d5f5750610d5a4261012c615904565b600b54105b15610d7d5761012c600b5f828254610d779190615904565b90915550505b600b5442108015610d9c57506006546001600160a01b03828116911614155b610db85760405162461bcd60e51b8152600401610c0590615917565b610dc181614361565b610dc96142a4565b6001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b158015610e01575f80fd5b505af1158015610e13573d5f803e3d5ffd5b505050505034600d5f828254610e299190615904565b90915550506001600160a01b0381165f908152602081905260408120549003610e9757600880546001810182555f919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0383161790555b6001600160a01b0381165f9081526020819052604081208054349290610ebe908490615904565b9091555050601e546001600160a01b0382165f908152602081905260409020541115610efc5760405162461bcd60e51b8152600401610c0590615938565b5f600f5434610f0b9190615954565b9050805f80846001600160a01b03166001600160a01b031681526020019081526020015f206001015f828254610f419190615904565b9250508190555080600e5f828254610f599190615904565b9091555050601d54600d541115610f825760405162461bcd60e51b8152600401610c059061596b565b601d54600d5403610fa557601a805460ff60301b1916600160301b179055426019555b7f46838cf48618a58fe85e0e5a216982cb39ea66766b6279365511ba996556c62e8234604051610fd692919061598d565b60405180910390a150506001601855565b5f610ff0612e5a565b6001600160a01b031663bf7c56e06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561102b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061104f91906159a6565b905090565b6018546001146110765760405162461bcd60e51b8152600401610c0590615851565b5f601855601a54600160201b900460ff16801561109d5750601a54600160281b900460ff16155b6110d55760405162461bcd60e51b81526020600482015260096024820152681b9bdd08195b99195960ba1b6044820152606401610c05565b60648111156111115760405162461bcd60e51b815260206004820152600860248201526706260604a40dac2f60c31b6044820152606401610c05565b5f805f61111c6142a4565b335f908152600160205260408120600601549192509061113f9062015180615904565b4211611149575f80fd5b611152336126b1565b60065491955093506001600160a01b031633036111ad57335f9081526001602052604081206002015490036111ad57600a601554603361119291906159c1565b61119c9086615954565b6111a691906159d4565b9350600190505b5f60646111ba8787615954565b6111c491906159d4565b335f908152600160205260408120600201805492935083929091906111ea908490615904565b9091555050335f908152600160205260409020805460029091015411156112395760405162461bcd60e51b81526020600482015260036024820152624c504f60e81b6044820152606401610c05565b600354611250906001600160a01b03168083614414565b60035460405163226bf2d160e21b81526001600160a01b03909116906389afcb44906112809030906004016154c9565b60408051808303815f875af115801561129b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112bf91906159f3565b50508060125f8282546112d29190615904565b90915550506040517f1a42d431af6fa10e6946404a861f6fb9ae0cb2ebb4efc3b0f61c84d61339aa1290611309903390849061598d565b60405180910390a16006546001600160a01b0316330361136757335f90815260016020526040812060030154900361136757600a601554603361134c91906159c1565b6113569086615954565b61136091906159d4565b9350600191505b5f60646113748887615954565b61137e91906159d4565b335f9081526001602052604090206004015490915082118015906113b35750335f908152600160205260409020600501548111155b806113d057506006546001600160a01b0316331480156113d05750825b6114015760405162461bcd60e51b8152602060048201526002602482015261414d60f01b6044820152606401610c05565b335f9081526001602052604081206003018054839290611422908490615904565b9091555050335f9081526001602081905260409091209081015460039091015411156114765760405162461bcd60e51b81526020600482015260036024820152624c503160e81b6044820152606401610c05565b60045461148d906001600160a01b03168083614414565b6004805460405163226bf2d160e21b81526001600160a01b03909116916389afcb44916114bc913091016154c9565b60408051808303815f875af11580156114d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114fb91906159f3565b50506115063361441f565b6040516370a0823160e01b81526001600160a01b03851690632e1a7d4d9082906370a082319061153a9030906004016154c9565b602060405180830381865afa158015611555573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115799190615a15565b6040518263ffffffff1660e01b815260040161159791815260200190565b5f604051808303815f87803b1580156115ae575f80fd5b505af11580156115c0573d5f803e3d5ffd5b505050506115ce3347614644565b5f6115d7610fe7565b905061164e8133836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161160a91906154c9565b602060405180830381865afa158015611625573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116499190615a15565b614414565b8160135f82825461165f9190615904565b90915550506040517fb96d785789a045e4950040309c1583cad395a8489e28446f5f93d3b2dbd9a50590611696903390859061598d565b60405180910390a15050335f90815260016020819052604090912042600690910155601855505050505050565b6018546001146116e55760405162461bcd60e51b8152600401610c0590615851565b5f6018556010541580159061170557506006546001600160a01b03163314155b6117395760405162461bcd60e51b815260206004820152600560248201526406e6f206c760dc1b6044820152606401610c05565b335f908152600160205260409020541561177f5760405162461bcd60e51b815260206004820152600760248201526618db185a5b595960ca1b6044820152606401610c05565b600d54335f908152602081905260409020546015546064906117a190826159c1565b6010546117ae9190615954565b6117b891906159d4565b6117c29190615954565b6117cc91906159d4565b335f90815260016020908152604080832093909355600d5490829052919020546015546064906117fc90826159c1565b6011546118099190615954565b61181391906159d4565b61181d9190615954565b61182791906159d4565b335f9081526001602081815260409092209081019290925554905461184c91906159d4565b335f9081526001602081815260409092206004810193909355905491015461187491906159d4565b335f90815260016020819052604090912060050191909155601855565b5f80601254601054116118a4575f6118b4565b6012546010546118b491906159c1565b9150601354601154116118c7575f6118d7565b6013546011546118d791906159c1565b90509091565b6018546001146118ff5760405162461bcd60e51b8152600401610c0590615851565b5f6018556006546001600160a01b03163314611919575f80fd5b5f805f5b8351811015611ac757602484828151811061193a5761193a615a2c565b60200260200101518154811061195257611952615a2c565b905f5260205f209060030201600101544211806119785750601a54600160281b900460ff165b80156119be5750602484828151811061199357611993615a2c565b6020026020010151815481106119ab576119ab615a2c565b905f5260205f209060030201600201545f145b6119da5760405162461bcd60e51b8152600401610c0590615a40565b60248482815181106119ee576119ee615a2c565b602002602001015181548110611a0657611a06615a2c565b5f9182526020909120600390910201549150611a228284615904565b9250816024858381518110611a3957611a39615a2c565b602002602001015181548110611a5157611a51615a2c565b905f5260205f209060030201600201819055507f58f6565f7ca9225084d6c61a164110cd062fec398701e465a82706950ef3e1a082858381518110611a9857611a98615a2c565b6020026020010151604051611ab7929190918252602082015260400190565b60405180910390a160010161191d565b508160175f828254611ad991906159c1565b9091555050600254600654611afb916001600160a01b03908116911684614414565b5050600160185550565b335f9081526001602052604090205415801590611b2157505f81115b611b5f5760405162461bcd60e51b815260206004820152600f60248201526e6e6f20686f6c64206f72206461797360881b6044820152606401610c05565b335f90815260016020526040902060060154611b7e8262015180615954565b611b889042615904565b11611bc95760405162461bcd60e51b81526020600482015260116024820152706d75737420626520696e2066757475726560781b6044820152606401610c05565b611bd68162015180615954565b611be09042615904565b335f8181526001602052604090819020600601839055517f79c93c0a2b06c8a59c5867f08c471f91760f438c5b9dac36e7d41d80585060a792611c23929161598d565b60405180910390a150565b601854600114611c505760405162461bcd60e51b8152600401610c0590615851565b5f6018556006546001600160a01b03163314611c6a575f80fd5b8051825114611ca45760405162461bcd60e51b81526020600482015260066024820152650d8cadccee8d60d31b6044820152606401610c05565b5f805b8351811015611dd857838181518110611cc257611cc2615a2c565b602002602001015182611cd59190615904565b915060246040518060600160405280868481518110611cf657611cf6615a2c565b60200260200101518152602001858481518110611d1557611d15615a2c565b60209081029190910181015182525f918101829052835460018181018655948352918190208351600390930201918255820151928101929092556040015160029091015583517fcbba5b8a19b4433a08340f967e8e5cb07b4c4e80305d04a78d5695f5ed8bd28190859083908110611d8f57611d8f615a2c565b6020026020010151848381518110611da957611da9615a2c565b6020908102919091018101516040805193845291830152810183905260600160405180910390a1600101611ca7565b508060175f828254611dea9190615904565b9091555050600254611afb906001600160a01b0316338361471a565b6006546001600160a01b03163314611e1c575f80fd5b601a546301000000900460ff16158015611e405750601a54600160281b900460ff16155b611e765760405162461bcd60e51b81526020600482015260076024820152661cdd185c9d195960ca1b6044820152606401610c05565b815f03611ed757611e8942610384615904565b811015611ec15760405162461bcd60e51b8152600401610c05906020808252600490820152631c185cdd60e21b604082015260600190565b600a819055600c54611ed39082615904565b600b555b81600103611f4857605a8111158015611ef1575060018110155b611f255760405162461bcd60e51b81526020600482015260056024820152642039302f3160d81b6044820152606401610c05565b611f328162015180615954565b600c819055600a54611f449190615904565b600b555b81600203611f8c576032811115611f865760405162461bcd60e51b8152602060048201526002602482015261035360f41b6044820152606401610c05565b60158190555b81600303611fd4576032811115611fce5760405162461bcd60e51b8152600401610c059060208082526004908201526335302f3160e01b604082015260600190565b60168190555b8160040361201757601d819055601b54611fef9082906159d4565b600f55611ffd6003826159d4565b601c55601e54811061201157601e54612013565b805b601e555b8160050361226b5760025f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561206f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120939190615a15565b81111580156120bc57506120af60016001600160801b03615a61565b6001600160801b03168111155b6120f75760405162461bcd60e51b815260206004820152600c60248201526b746f74616c20737570706c7960a01b6044820152606401610c05565b601b548082111561212757600254601b54612127916001600160a01b031690339061212290866159c1565b61471a565b80821161214f57600254601b5461214f916001600160a01b03169033906116499086906159c1565b601b8290558161218a5760405162461bcd60e51b8152600401610c05906020808252600490820152637a65726f60e01b604082015260600190565b600f54601b5461219a91906159d4565b601d8190556121ab906003906159d4565b601c55600254604080516318160ddd60e01b815290516064926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa1580156121f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221a9190615a15565b612225906062615954565b61222f91906159d4565b82101580156122405750600b601554105b61224a575f61224d565b60015b601a8054911515600160381b0260ff60381b19909216919091179055505b816006036122b257605a8111158015612285575060078110155b6122a15760405162461bcd60e51b8152600401610c0590615a81565b6122ae8162015180615954565b601f555b8160070361230757601481111580156122cc575060058110155b6123015760405162461bcd60e51b8152600401610c059060208082526004908201526332302f3560e01b604082015260600190565b60208190555b8160080361236657662386f26fc1000081101561234f5760405162461bcd60e51b8152600401610c059060208082526004908201526318b2989b60e11b604082015260600190565b601d54811161235e5780612362565b601d545b601e555b60408051838152602081018390527f57f8066c13130516c76eafcbbaeda0b5339c2ef724f4214c390f902531f5a123910160405180910390a15050565b601a54610100900460ff161580156123c557506005546001600160a01b031633145b6123cd575f80fd5b605a83111580156123df575060078310155b6123fb5760405162461bcd60e51b8152600401610c0590615a81565b601a805461ff0019166101001790556124178362015180615954565b601f556020828155601a805462ff0000191662010000179055600480546001600160a01b038085166001600160a01b0319909216919091178255600254604080516318160ddd60e01b8152905160649592909316936318160ddd9382820193929091908290030181865afa158015612491573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124b59190615a15565b6124c0906062615954565b6124ca91906159d4565b601b54108015906124dd5750600b601554105b156124f657601a805460ff60381b1916600160381b1790555b505050565b5f600f548261250a9190615954565b92915050565b601a54600160281b900460ff161580156125345750601a54600160201b900460ff16155b6125505760405162461bcd60e51b8152600401610c0590615a40565b601c54600d541061258c5760405162461bcd60e51b8152600401610c05906020808252600490820152630736361760e41b604082015260600190565b601a805465ff00000000001916600160281b1790556002546125b6906001600160a01b03166135e0565b60055460025460405163b5e55f2f60e01b81526001600160a01b0391821660048201525f602482015291169063b5e55f2f906044015f604051808303815f87803b158015612602575f80fd5b505af1158015612614573d5f803e3d5ffd5b505060055460025460405163e96be10760e01b81526001600160a01b03928316945063e96be107935061264d92909116906004016154c9565b5f604051808303815f87803b158015612664575f80fd5b505af1158015612676573d5f803e3d5ffd5b5050601a805460ff60381b1916905550506040517fd0710aa9f2dc3d816b38e246a7683ffc8be7b37ac4ac0363c0cde7841eb9afda905f90a1565b5f80806126bc612bef565b6001600160a01b0385165f908152600160205260409020549091501561292e57335f908152600160205260409020600601546126fb9062015180615904565b42111561292e576001600160a01b0384165f908152600160205260409020600281015460049091015461272f908390615954565b111561292e576001600160a01b0384165f90815260016020526040812060048101546002909101546127618483615954565b61276b91906159c1565b116127ac576001600160a01b0385165f908152600160205260409020600281015460049091015461279d908490615954565b6127a791906159c1565b6127c8565b6001600160a01b0385165f908152600160205260409020600401545b6001600160a01b0386165f9081526001602052604090208054600290910154919250906127f59083615904565b116128005780612828565b6001600160a01b0385165f9081526001602052604090206002810154905461282891906159c1565b6001600160a01b0386165f908152600160205260408120600581015460039091015492965090916128598583615954565b61286391906159c1565b116128a4576001600160a01b0386165f9081526001602052604090206003810154600590910154612895908590615954565b61289f91906159c1565b6128c0565b6001600160a01b0386165f908152600160205260409020600501545b6001600160a01b0387165f90815260016020819052604090912090810154600390910154919250906128f29083615904565b116128fd5780612929565b6001600160a01b0386165f908152600160208190526040909120600381015491015461292991906159c1565b935050505b50915091565b6018546001146129565760405162461bcd60e51b8152600401610c0590615851565b5f6018819055338152602081905260409020546129a25760405162461bcd60e51b815260206004820152600a6024820152696e6f2062616c616e636560b01b6044820152606401610c05565b601054156129c25760405162461bcd60e51b8152600401610c059061588f565b601a54600160301b900460ff16156129ee576019546129e4906203f480615904565b42116129ee575f80fd5b335f9081526020819052604090206002015460ff16158015612a275750335f90815260208190526040902060020154610100900460ff16155b612a5d5760405162461bcd60e51b81526020600482015260076024820152661c995d0bd8589d60ca1b6044820152606401610c05565b601a54600160281b900460ff1615612a8e57335f908152602081905260409020600201805461ff0019166101001790555b335f90815260208190526040812060028101805460ff1916600117905554600d805491928392612abf9084906159c1565b9091555050335f90815260208190526040812060010154600e805491928392612ae99084906159c1565b9091555050335f90815260208190526040812081815560018101919091556002015462010000900460ff1615612b3157600160145f828254612b2b91906159c1565b90915550505b601a805460ff60401b1916600160401b179055612b4c6142a4565b6001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b8152600401612b7991815260200190565b5f604051808303815f87803b158015612b90575f80fd5b505af1158015612ba2573d5f803e3d5ffd5b5050601a805460ff60401b1916905550612bbe90503383614644565b7f57a14dfcf9eafb37c308036c6fb972bd18bcc057d36594887421e4f4a60f93c63383604051610fd692919061598d565b601f545f906001825b602054811015612c6057612c0c8383615954565b602154612c199190615904565b421115612c2e57612c2b600183615904565b91505b612c388383615954565b602154612c459190615904565b42111580612c54575060205482145b612c6057600101612bf8565b5092915050565b60248181548110612c76575f80fd5b5f91825260209091206003909102018054600182015460029092015490925083565b601a5460ff16158015612cb557506005546001600160a01b031633145b612cbd575f80fd5b60025f9054906101000a90046001600160a01b03166001600160a01b0316638c00e9b96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d3191906159a6565b600680546001600160a01b0319166001600160a01b03928316179055600254604080516324dead2f60e11b8152905191909216916349bd5a5e9160048083019260209291908290030181865afa158015612d8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612db191906159a6565b600380546001600160a01b0319166001600160a01b0392909216919091179055601a805460ff19166001179055601b869055601d849055612df284876159d4565b600f55612e006003856159d4565b601c55601e839055600a8290556276a700600c819055612e209083615904565b600b5560159490945550505060165550565b60098181548110612e41575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f73cced1a96321b2b2a06e8f3f4b0b883ddd059968c6001600160a01b03166385523a1b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561102b573d5f803e3d5ffd5b5f805f805f612eb8612bef565b6001600160a01b0387165f90815260016020526040902060040154612edd9190615954565b90505f612ee8612bef565b6001600160a01b0388165f90815260016020526040902060050154612f0d9190615954565b6001600160a01b0388165f9081526001602052604090206002015490915082111561341d575f612f3b6142a4565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f8e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fb29190615a15565b90505f60045f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613005573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130299190615a15565b90506130348a6126b1565b6002546040805163373556cf60e01b815290519398509196506001600160a01b03169163373556cf916004808201926020929091908290030181865afa158015613080573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130a491906159a6565b6002546003546040516370a0823160e01b81526001600160a01b039384169363d24a1f029387938b93918316926370a08231926130e792909116906004016154c9565b602060405180830381865afa158015613102573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131269190615a15565b6131309190615954565b61313a91906159d4565b6040518263ffffffff1660e01b815260040161315891815260200190565b602060405180830381865afa158015613173573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131979190615a15565b965060025f9054906101000a90046001600160a01b03166001600160a01b031663373556cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061320d91906159a6565b600254600480546040516370a0823160e01b81526001600160a01b039485169463d24a1f029487948b94918316936370a082319361324d931691016154c9565b602060405180830381865afa158015613268573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061328c9190615a15565b6132969190615954565b6132a091906159d4565b6040518263ffffffff1660e01b81526004016132be91815260200190565b602060405180830381865afa1580156132d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132fd9190615a15565b6003546040516370a0823160e01b8152919750839187916001600160a01b03808816926370a08231926133349216906004016154c9565b602060405180830381865afa15801561334f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133739190615a15565b61337d9190615954565b61338791906159d4565b98508084613393610fe7565b600480546040516370a0823160e01b81526001600160a01b03938416936370a08231936133c49390911691016154c9565b602060405180830381865afa1580156133df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134039190615a15565b61340d9190615954565b61341791906159d4565b97505050505b50509193509193565b6006546001600160a01b03163314801561344e57506006546001600160a01b03838116911614155b613456575f80fd5b6001600160a01b0382165f9081526020819052604090206002015462010000900460ff166134f55780613487575f80fd5b601a546301000000900460ff161561349d575f80fd5b60228054600160ff1990911681179091556009805491820181555f527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b0384161790555b60225460ff16613503575f80fd5b6001600160a01b0382165f9081526020819052604090206002015462010000900460ff1615613557578015613536575f80fd5b6001600160a01b0382165f9081526020819052604090205415613557575f80fd5b6001600160a01b0382165f908152602081905260409020600201805462ff00001916620100008315158102919091179182905560ff9104166135a7576023546135a2906001906159c1565b6135b5565b6023546135b5906001615904565b6023819055601454146135c95760016135cb565b5f5b6022805460ff19169115159190911790555050565b6018546001146136025760405162461bcd60e51b8152600401610c0590615851565b5f6018556006546001600160a01b0316331461361c575f80fd5b613624610fe7565b6001600160a01b0316816001600160a01b03161415801561365357506003546001600160a01b03828116911614155b801561366d57506004546001600160a01b03828116911614155b613675575f80fd5b6007546001600160a01b03828116911614806136a957506136946142a4565b6001600160a01b0316816001600160a01b0316145b156136ec57600d54156136ec5760405162461bcd60e51b815260206004820152600b60248201526a072616973656420213d20360ac1b6044820152606401610c05565b6040516370a0823160e01b81525f906001600160a01b038316906370a082319061371a9030906004016154c9565b602060405180830381865afa158015613735573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137599190615a15565b6002549091506001600160a01b03908116908316036137e157601a546301000000900460ff16156137c357601a54600160281b900460ff166137c35760405162461bcd60e51b81526020600482015260036024820152620e4c2f60eb1b6044820152606401610c05565b6017546137d090826159c1565b5f601b819055601d819055601c5590505b80156137ff576006546137ff9083906001600160a01b031683614414565b471561381b5760065461381b906001600160a01b031647614644565b50506001601855565b5f61382d612e5a565b6001600160a01b031663122fea3b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561102b573d5f803e3d5ffd5b601a54600160281b900460ff1615801561388c5750601a54600160201b900460ff16155b80156138a15750601a546301000000900460ff165b6138bd5760405162461bcd60e51b8152600401610c0590615a40565b6006546001600160a01b031633148061394357506138d9612e5a565b6001600160a01b03166324d7806c336040518263ffffffff1660e01b815260040161390491906154c9565b602060405180830381865afa15801561391f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139439190615874565b61394b575f80fd5b600b544211801561395f5750601c54600d54105b1561397857600c546139719042615904565b600b555050565b601a54600160301b900460ff16806139a05750600b54421180156139a05750601c54600d5410155b6139a8575f80fd5b6139b28282614726565b60055460025460405163e96be10760e01b81526001600160a01b039283169263e96be107926139e6929116906004016154c9565b5f604051808303815f87803b1580156139fd575f80fd5b505af1158015613a0f573d5f803e3d5ffd5b5050601a805464ff000000001916600160201b179055505042600b555050565b6006546001600160a01b03163314613a45575f80fd5b601a546301000000900460ff1615613a5b575f80fd5b6022805460ff1916600117905580515f5b818110156124f6575f80848381518110613a8857613a88615a2c565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2060020160029054906101000a900460ff16158015613aff575060065483516001600160a01b0390911690849083908110613aeb57613aeb615a2c565b60200260200101516001600160a01b031614155b613b1b5760405162461bcd60e51b8152600401610c0590615a40565b60015f80858481518110613b3157613b31615a2c565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2060020160026101000a81548160ff0219169083151502179055506001601b6008015f828254613b879190615904565b925050819055506009838281518110613ba257613ba2615a2c565b6020908102919091018101518254600180820185555f9485529290932090920180546001600160a01b0319166001600160a01b039093169290921790915501613a6c565b5f601854600114613c095760405162461bcd60e51b8152600401610c0590615851565b5f601855613c1561420f565b613c1d612e5a565b6001600160a01b0316632c86cba3336040518263ffffffff1660e01b8152600401613c4891906154c9565b602060405180830381865afa158015613c63573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613c879190615874565b613c8f573394505b6002546001600160a01b0390811690851603613cdd5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610c05565b5f8311613cfc5760405162461bcd60e51b8152600401610c05906158cd565b6001600160a01b0385165f9081526020819052604090206002015460ff1615613d375760405162461bcd60e51b8152600401610c05906158ad565b5f613d406142a4565b601a54909150600160301b900460ff16158015613d675750601a54600160281b900460ff16155b8015613d7c5750601a546301000000900460ff165b613d985760405162461bcd60e51b8152600401610c059061588f565b600b5442108015613db55750613db04261012c615904565b600b54105b15613dd35761012c600b5f828254613dcd9190615904565b90915550505b600b5442108015613df257506006546001600160a01b03878116911614155b613e0e5760405162461bcd60e51b8152600401610c0590615917565b613e1786614361565b6001600160a01b0386165f908152602081905260408120549003613e8057600880546001810182555f919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6040516370a0823160e01b81525f906001600160a01b038716906370a0823190613eae9030906004016154c9565b602060405180830381865afa158015613ec9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613eed9190615a15565b9050613efb86333088614e77565b5f81876001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401613f2991906154c9565b602060405180830381865afa158015613f44573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f689190615a15565b613f7291906159c1565b90505f836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401613fa191906154c9565b602060405180830381865afa158015613fbc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fe09190615a15565b9050613fed888388614ee2565b5f81856001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161401b91906154c9565b602060405180830381865afa158015614036573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061405a9190615a15565b61406491906159c1565b90505f811161409f5760405162461bcd60e51b81526020600482015260076024820152660616d74496e20360cc1b6044820152606401610c05565b80600d5f8282546140b09190615904565b90915550506001600160a01b038a165f90815260208190526040812080548392906140dc908490615904565b9091555050601e546001600160a01b038b165f90815260208190526040902054111561411a5760405162461bcd60e51b8152600401610c0590615938565b5f600f54826141299190615954565b9050805f808d6001600160a01b03166001600160a01b031681526020019081526020015f206001015f82825461415f9190615904565b9250508190555080600e5f8282546141779190615904565b9091555050601d54600d5411156141a05760405162461bcd60e51b8152600401610c059061596b565b601d54600d54036141c357601a805460ff60301b1916600160301b179055426019555b7f46838cf48618a58fe85e0e5a216982cb39ea66766b6279365511ba996556c62e8b836040516141f492919061598d565b60405180910390a15060016018559998505050505050505050565b601a546301000000900460ff1661423e57600a5442111561423e57601a805463ff000000191663010000001790555b565b6001600160a01b0381165f9081526001602052604081206006015481908190421061426b575f61426e565b60015b90505f8161427c575f614298565b6001600160a01b0385165f908152600160205260409020600601545b91959194509092505050565b5f6142ad612e5a565b6001600160a01b031663f24286216040518163ffffffff1660e01b8152600401602060405180830381865afa15801561102b573d5f803e3d5ffd5b6006546001600160a01b031633146142fe575f80fd5b601a546301000000900460ff1615806143375750601a546301000000900460ff16801561432d575060225460ff165b8015614337575080155b61433f575f80fd5b6022805460ff1916911515919091179055565b60088181548110612e41575f80fd5b60225460ff1615614411576001600160a01b0381165f9081526020819052604090206002015462010000900460ff166143c55760405162461bcd60e51b81526020600482015260066024820152651b9bdd081ddb60d21b6044820152606401610c05565b6001600160a01b0381165f90815260208190526040902054156143ea576014546143f8565b6014546143f8906001615904565b60148190556023549003614411576022805460ff191690555b50565b6124f6838383614ff0565b6002546040805163373556cf60e01b815290515f926001600160a01b03169163373556cf9160048083019260209291908290030181865afa158015614466573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061448a91906159a6565b6017546002546040516370a0823160e01b81529293505f926001600160a01b03909116906370a08231906144c29030906004016154c9565b602060405180830381865afa1580156144dd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906145019190615a15565b61450b91906159c1565b6007546040516370a0823160e01b81529192505f916001600160a01b03909116906370a08231906145409086906004016154c9565b602060405180830381865afa15801561455b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061457f9190615a15565b905066038d7ea4c680008110156145a9576002546145a9906001600160a01b031661dead84614414565b66038d7ea4c68000811061463e576002546145ce906001600160a01b0316848461500f565b604051630e9ec60f60e01b81526001600160a01b03841690630e9ec60f906145fc908790869060040161598d565b6020604051808303815f875af1158015614618573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061463c9190615a15565b505b50505050565b604080515f808252602082019092526001600160a01b03841690839060405161466d9190615ac1565b5f6040518083038185875af1925050503d805f81146146a7576040519150601f19603f3d011682016040523d82523d5f602084013e6146ac565b606091505b50509050806124f65760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b6064820152608401610c05565b6124f683833084614e77565b5f61472f610fe7565b6005546040805163e97206a960e01b815281519394505f9384936001600160a01b03169263e97206a992600480820193918290030181865afa158015614777573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061479b91906159f3565b909250905081156148be576147ae612e5a565b6001600160a01b0316637f2a47686040518163ffffffff1660e01b8152600401602060405180830381865afa1580156147e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061480d91906159a6565b6040516383db77c360e01b81526001600160a01b038581166004830152602482018590526044820184905291909116906383db77c390606401602060405180830381865afa158015614861573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906148859190615874565b156148be5760405162461bcd60e51b8152602060048201526009602482015268233937b73a10393ab760b91b6044820152606401610c05565b601654156148cf576148cf846150ae565b5f6148d86142a4565b600554604051636fcca69b60e01b81529192505f916103e8916001600160a01b031690636fcca69b9061490f9030906004016154c9565b602060405180830381865afa15801561492a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061494e9190615a15565b6040516370a0823160e01b81526001600160a01b038516906370a082319061497a9030906004016154c9565b602060405180830381865afa158015614995573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906149b99190615a15565b6149c39190615954565b6149cd91906159d4565b600554604051636fcca69b60e01b81529192505f916103e8916001600160a01b031690636fcca69b90614a049030906004016154c9565b602060405180830381865afa158015614a1f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614a439190615a15565b601b54614a509190615954565b614a5a91906159d4565b90505f81601b5f0154614a6d91906159c1565b9050614a8184614a7b613824565b8561500f565b6040805160028082526060820183525f9260208301908036833701905050905084815f81518110614ab457614ab4615a2c565b60200260200101906001600160a01b031690816001600160a01b0316815250508781600181518110614ae857614ae8615a2c565b60200260200101906001600160a01b031690816001600160a01b031681525050614b10613824565b6001600160a01b0316635c11d795858c8430426040518663ffffffff1660e01b8152600401614b43959493929190615adc565b5f604051808303815f87803b158015614b5a575f80fd5b505af1158015614b6c573d5f803e3d5ffd5b5050600254600354614b8d93506001600160a01b0391821692501684614414565b6003546040516370a0823160e01b8152614bc69187916001600160a01b03918216918316906370a082319061160a9030906004016154c9565b6003546040516335313c2160e11b81526001600160a01b0390911690636a62784290614bf69030906004016154c9565b6020604051808303815f875af1158015614c12573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614c369190615a15565b6010819055606490614c49906062615954565b614c5391906159d4565b601055601554614c63575f614c7f565b6064601554601054614c759190615954565b614c7f91906159d4565b600680546001600160a01b039081165f9081526001602090815260408083209590955554925490911681529190912054614cb991906159d4565b6006546001600160a01b039081165f9081526001602052604090819020600490810193909355825490516370a0823160e01b8152614d0c938c93928316928416916370a082319161160a913091016154c9565b600254600454614d29916001600160a01b03908116911685614414565b600480546040516335313c2160e11b81526001600160a01b0390911691636a62784291614d58913091016154c9565b6020604051808303815f875af1158015614d74573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614d989190615a15565b6011819055606490614dab906062615954565b614db591906159d4565b601155601554614dc5575f614de1565b6064601554601154614dd79190615954565b614de191906159d4565b600680546001600160a01b039081165f90815260016020818152604080842083019690965554935490921681529290922090910154614e2091906159d4565b6006546001600160a01b03165f90815260016020526040808220600501929092554260215590517fd0710aa9f2dc3d816b38e246a7683ffc8be7b37ac4ac0363c0cde7841eb9afda9190a150505050505050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261463e9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526152b7565b614ef483614eee613824565b8461500f565b6040805160028082526060820183525f9260208301908036833701905050905083815f81518110614f2757614f27615a2c565b60200260200101906001600160a01b031690816001600160a01b031681525050614f4f6142a4565b81600181518110614f6257614f62615a2c565b60200260200101906001600160a01b031690816001600160a01b031681525050614f8a613824565b6001600160a01b0316635c11d79584848430426040518663ffffffff1660e01b8152600401614fbd959493929190615adc565b5f604051808303815f87803b158015614fd4575f80fd5b505af1158015614fe6573d5f803e3d5ffd5b5050505050505050565b6124f68363a9059cbb60e01b8484604051602401614eab92919061598d565b8015806150875750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015615061573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906150859190615a15565b155b61508f575f80fd5b6124f68363095ea7b360e01b8484604051602401614eab92919061598d565b5f6064601654600d546150c19190615954565b6150cb91906159d4565b90505f60025f9054906101000a90046001600160a01b03166001600160a01b031663373556cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561511e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061514291906159a6565b90505f61514d6142a4565b6007549091506001600160a01b038083169116146152975761517181614a7b613824565b604080516002808252606080830184529260208301908036833701905050905081815f815181106151a4576151a4615a2c565b6001600160a01b0392831660209182029290920101526007548251911690829060019081106151d5576151d5615a2c565b60200260200101906001600160a01b031690816001600160a01b0316815250506151fd613824565b6001600160a01b0316635c11d79585878430426040518663ffffffff1660e01b8152600401615230959493929190615adc565b5f604051808303815f87803b158015615247575f80fd5b505af1158015615259573d5f803e3d5ffd5b50506007546040516370a0823160e01b815261529593506001600160a01b039091169150859082906370a082319061160a9030906004016154c9565b505b6007546001600160a01b0380831691160361463e5761463e818385614414565b5f6152fc826040518060400160405280600e81526020016d5361666545524332303a206c6f7760901b815250856001600160a01b031661535c9092919063ffffffff16565b8051909150156124f6578080602001905181019061531a9190615874565b6124f65760405162461bcd60e51b815260206004820152601360248201527205361666545524332303a204552433230206f7606c1b6044820152606401610c05565b606061536a84845f85615372565b949350505050565b6060824710156153b65760405162461bcd60e51b815260206004820152600f60248201526e20b2323932b9b99d1034b739bab33360891b6044820152606401610c05565b5f80866001600160a01b031685876040516153d19190615ac1565b5f6040518083038185875af1925050503d805f811461540b576040519150601f19603f3d011682016040523d82523d5f602084013e615410565b606091505b50915091506154218783838761542c565b979650505050505050565b6060831561549a5782515f03615493576001600160a01b0385163b6154935760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c05565b508161536a565b61536a83838151156154af5781518083602001fd5b8060405162461bcd60e51b8152600401610c059190615b4d565b6001600160a01b0391909116815260200190565b5f602082840312156154ed575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715615531576155316154f4565b604052919050565b5f67ffffffffffffffff821115615552576155526154f4565b5060051b60200190565b5f82601f83011261556b575f80fd5b8135602061558061557b83615539565b615508565b8083825260208201915060208460051b8701019350868411156155a1575f80fd5b602086015b848110156155bd57803583529183019183016155a6565b509695505050505050565b5f602082840312156155d8575f80fd5b813567ffffffffffffffff8111156155ee575f80fd5b61536a8482850161555c565b5f806040838503121561560b575f80fd5b823567ffffffffffffffff80821115615622575f80fd5b61562e8683870161555c565b93506020850135915080821115615643575f80fd5b506156508582860161555c565b9150509250929050565b5f806040838503121561566b575f80fd5b50508035926020909101359150565b6001600160a01b0381168114614411575f80fd5b5f805f606084860312156156a0575f80fd5b833592506020840135915060408401356156b98161567a565b809150509250925092565b5f602082840312156156d4575f80fd5b81356156df8161567a565b9392505050565b5f805f805f8060c087890312156156fb575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b8015158114614411575f80fd5b5f8060408385031215615743575f80fd5b823561574e8161567a565b9150602083013561575e81615725565b809150509250929050565b5f602080838503121561577a575f80fd5b823567ffffffffffffffff811115615790575f80fd5b8301601f810185136157a0575f80fd5b80356157ae61557b82615539565b81815260059190911b820183019083810190878311156157cc575f80fd5b928401925b828410156154215783356157e48161567a565b825292840192908401906157d1565b5f805f8060808587031215615806575f80fd5b84356158118161567a565b935060208501356158218161567a565b93969395505050506040820135916060013590565b5f60208284031215615846575f80fd5b81356156df81615725565b6020808252600990820152681c99595b9d1c985b9d60ba1b604082015260600190565b5f60208284031215615884575f80fd5b81516156df81615725565b6020808252600490820152631cdbdd5d60e21b604082015260600190565b602080825260069082015265195e1a5d195960d21b604082015260600190565b6020808252600990820152681b9bc8185b5bdd5b9d60ba1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561250a5761250a6158f0565b602080825260079082015266074696d652075760cc1b604082015260600190565b60208082526002908201526126a160f11b604082015260600190565b808202811582820484141761250a5761250a6158f0565b6020808252600890820152671bdd995c9cdbdb1960c21b604082015260600190565b6001600160a01b03929092168252602082015260400190565b5f602082840312156159b6575f80fd5b81516156df8161567a565b8181038181111561250a5761250a6158f0565b5f826159ee57634e487b7160e01b5f52601260045260245ffd5b500490565b5f8060408385031215615a04575f80fd5b505080516020909101519092909150565b5f60208284031215615a25575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b602080825260079082015266616c726561647960c81b604082015260600190565b6001600160801b03828116828216039080821115612c6057612c606158f0565b60208082526004908201526339302f3760e01b604082015260600190565b5f5b83811015615ab9578181015183820152602001615aa1565b50505f910152565b5f8251615ad2818460208701615a9f565b9190910192915050565b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b81811015615b2c5784516001600160a01b031683529383019391830191600101615b07565b50506001600160a01b03969096166060850152505050608001529392505050565b602081525f8251806020840152615b6b816040850160208701615a9f565b601f01601f1916919091016040019291505056fea2646970667358221220d33e51511ed5052d591f93ae7fcc1bd4ff69c346bb1366903b0a5769fe5213f764736f6c63430008180033a2646970667358221220b4e037fbc04249ffa3e35c21c03620c0c3f5654a228c087bfed6d579dd0fe76964736f6c63430008180033

Deployed Bytecode

0x608060405234801561000f575f80fd5b5060043610610034575f3560e01c8063ab20213b14610038578063abddca0d14610067575b5f80fd5b61004b610046366004610289565b610079565b6040516001600160a01b03909116815260200160405180910390f35b5f5461004b906001600160a01b031681565b5f836001600160a01b0316826001600160a01b0316638c00e9b96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100e491906102d1565b6001600160a01b03161480156101c957505f54604080516385523a1b60e01b8152905133926001600160a01b0316916385523a1b9160048083019260209291908290030181865afa15801561013b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061015f91906102d1565b6001600160a01b03166381b832376040518163ffffffff1660e01b8152600401602060405180830381865afa15801561019a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101be91906102d1565b6001600160a01b0316145b6102055760405162461bcd60e51b81526020600482015260096024820152683737ba1037bbb732b960b91b604482015260640160405180910390fd5b338484428560405161021690610265565b6001600160a01b039586168152938516602085015291841660408401526060830152909116608082015260a001604051809103905ff08015801561025c573d5f803e3d5ffd5b50949350505050565b615ccf806102f483390190565b6001600160a01b0381168114610286575f80fd5b50565b5f805f6060848603121561029b575f80fd5b83356102a681610272565b925060208401356102b681610272565b915060408401356102c681610272565b809150509250925092565b5f602082840312156102e1575f80fd5b81516102ec81610272565b939250505056fe6080604052600160185534801562000015575f80fd5b5060405162005ccf38038062005ccf8339810160408190526200003891620000a9565b600580546001600160a01b039687166001600160a01b0319918216179091556006805495871695821695909517909455600780549386169385169390931790925550600280549190931691161790556200010c565b80516001600160a01b0381168114620000a4575f80fd5b919050565b5f805f805f60a08688031215620000be575f80fd5b620000c9866200008d565b9450620000d9602087016200008d565b9350620000e9604087016200008d565b92506060860151915062000100608087016200008d565b90509295509295909350565b615bb5806200011a5f395ff3fe608060405260043610610333575f3560e01c806380b62b70116101ad578063cc142b07116100ea578063e5ba08961161008e578063e5ba089614610afd578063ef0fc79014610b1c578063f0ea4bfc14610b52578063f242862114610b67578063f2db8b2614610b7b578063f958a65714610b90578063fca3c0aa14610baf578063fe46580714610bc4575f80fd5b8063cc142b07146109c5578063cc4e508d146109e4578063ce2c178a14610a03578063d5d0526e14610a18578063d5f3948814610aa2578063d8cea0ec14610ac1578063daf2de1314610ad5578063dfc0cdf614610aea575f80fd5b806398c99c9e1161015157806398c99c9e146108965780639de2b11b146108b5578063a82ed9ec146108ca578063aa6ce92a146108de578063aed04fae146108fc578063b774820814610911578063bc58a4aa14610991578063bebd0fd3146109b0575f80fd5b806380b62b701461078757806383d98967146107a757806385523a1b146107c657806385611bd8146107da57806388cb214e14610819578063893da6c9146108385780638aea8f71146108585780638da5cb5b14610877575f80fd5b806345ea69da1161027b57806359ea287d1161021f57806359ea287d1461063e5780636104113e146106bd5780636a760b80146106d15780636ac5e0fb1461070b57806370c88b791461072a57806378bb51641461073f57806378e97925146107535780637ebd1b3014610768575f80fd5b806345ea69da1461055c578063484d27fc1461057b57806349bd5a5e1461059a5780634adb3374146105b95780634beb394c146105d85780634ed48edc146105f757806354ae78ee1461060b5780635641ec031461062a575f80fd5b806310117e85116102e257806310117e851461046d57806312fa6feb1461048157806316269d95146104a15780631f2698ab146104ca5780633197cbb6146104ea57806333788622146104ff578063384002a21461051e57806340519a531461053d575f80fd5b806302c7e7af146103965780630363799a146103be5780630415af81146103d3578063093a9fbc146103e85780630cc03e7a146104095780630dbc6b3e146104285780630fb5a6b414610458575f80fd5b3661039257601a546301000000900460ff16801561035b5750601a54600160301b900460ff16155b80156103715750601a54600160201b900460ff16155b1561039057601a54600160401b900460ff166103905761039033610be3565b005b5f80fd5b3480156103a1575f80fd5b506103ab600e5481565b6040519081526020015b60405180910390f35b3480156103c9575f80fd5b506103ab60135481565b3480156103de575f80fd5b506103ab60175481565b3480156103f3575f80fd5b506103fc610fe7565b6040516103b591906154c9565b348015610414575f80fd5b506103906104233660046154dd565b611054565b348015610433575f80fd5b50601a5461044890600160381b900460ff1681565b60405190151581526020016103b5565b348015610463575f80fd5b506103ab600c5481565b348015610478575f80fd5b506103906116c3565b34801561048c575f80fd5b50601a5461044890600160201b900460ff1681565b3480156104ac575f80fd5b506104b5611891565b604080519283526020830191909152016103b5565b3480156104d5575f80fd5b50601a54610448906301000000900460ff1681565b3480156104f5575f80fd5b506103ab600b5481565b34801561050a575f80fd5b506103906105193660046155c8565b6118dd565b348015610529575f80fd5b506002546103fc906001600160a01b031681565b348015610548575f80fd5b506103906105573660046154dd565b611b05565b348015610567575f80fd5b506103906105763660046155fa565b611c2e565b348015610586575f80fd5b5061039061059536600461565a565b611e06565b3480156105a5575f80fd5b506003546103fc906001600160a01b031681565b3480156105c4575f80fd5b506103906105d336600461568e565b6123a3565b3480156105e3575f80fd5b506103ab6105f23660046154dd565b6124fb565b348015610602575f80fd5b50610390612510565b348015610616575f80fd5b506104b56106253660046156c4565b6126b1565b348015610635575f80fd5b50610390612934565b348015610649575f80fd5b50601b54601c54601d54601e54601f54602054602154602254602354610677989796959493929160ff169089565b60408051998a5260208a0198909852968801959095526060870193909352608086019190915260a085015260c0840152151560e0830152610100820152610120016103b5565b3480156106c8575f80fd5b506103ab612bef565b3480156106dc575f80fd5b506106f06106eb3660046154dd565b612c67565b604080519384526020840192909252908201526060016103b5565b348015610716575f80fd5b506103906107253660046156e6565b612c98565b348015610735575f80fd5b506103ab60145481565b34801561074a575f80fd5b506009546103ab565b34801561075e575f80fd5b506103ab600a5481565b348015610773575f80fd5b506103fc6107823660046154dd565b612e32565b348015610792575f80fd5b50601a5461044890600160281b900460ff1681565b3480156107b2575f80fd5b506007546103fc906001600160a01b031681565b3480156107d1575f80fd5b506103fc612e5a565b3480156107e5575f80fd5b506107f96107f43660046156c4565b612eab565b6040805194855260208501939093529183015260608201526080016103b5565b348015610824575f80fd5b50610390610833366004615732565b613426565b348015610843575f80fd5b50601a5461044890600160301b900460ff1681565b348015610863575f80fd5b50601a546104489062010000900460ff1681565b348015610882575f80fd5b506006546103fc906001600160a01b031681565b3480156108a1575f80fd5b506103906108b03660046156c4565b6135e0565b3480156108c0575f80fd5b506103ab600f5481565b3480156108d5575f80fd5b506103fc613824565b3480156108e9575f80fd5b50601a5461044890610100900460ff1681565b348015610907575f80fd5b506103ab60155481565b34801561091c575f80fd5b5061096161092b3660046156c4565b5f6020819052908152604090208054600182015460029092015490919060ff808216916101008104821691620100009091041685565b6040805195865260208601949094529115159284019290925290151560608301521515608082015260a0016103b5565b34801561099c575f80fd5b506103906109ab36600461565a565b613868565b3480156109bb575f80fd5b506103ab60165481565b3480156109d0575f80fd5b506103906109df366004615769565b613a2f565b3480156109ef575f80fd5b506103ab6109fe3660046157f3565b613be6565b348015610a0e575f80fd5b506103ab60125481565b348015610a23575f80fd5b50610a6d610a323660046156c4565b600160208190525f91825260409091208054918101546002820154600383015460048401546005850154600690950154939492939192909187565b604080519788526020880196909652948601939093526060850191909152608084015260a083015260c082015260e0016103b5565b348015610aad575f80fd5b506005546103fc906001600160a01b031681565b348015610acc575f80fd5b5061039061420f565b348015610ae0575f80fd5b506103ab60115481565b610390610af83660046156c4565b610be3565b348015610b08575f80fd5b506004546103fc906001600160a01b031681565b348015610b27575f80fd5b50610b3b610b363660046156c4565b614240565b6040805192151583526020830191909152016103b5565b348015610b5d575f80fd5b506103ab600d5481565b348015610b72575f80fd5b506103fc6142a4565b348015610b86575f80fd5b506103ab60105481565b348015610b9b575f80fd5b50610390610baa366004615836565b6142e8565b348015610bba575f80fd5b506103ab60195481565b348015610bcf575f80fd5b506103fc610bde3660046154dd565b614352565b601854600114610c0e5760405162461bcd60e51b8152600401610c0590615851565b60405180910390fd5b5f601855610c1a61420f565b610c22612e5a565b6001600160a01b0316632c86cba3336040518263ffffffff1660e01b8152600401610c4d91906154c9565b602060405180830381865afa158015610c68573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c8c9190615874565b610c935750335b601a54600160301b900460ff16158015610cb75750601a54600160281b900460ff16155b8015610ccc5750601a546301000000900460ff165b610ce85760405162461bcd60e51b8152600401610c059061588f565b6001600160a01b0381165f9081526020819052604090206002015460ff1615610d235760405162461bcd60e51b8152600401610c05906158ad565b5f3411610d425760405162461bcd60e51b8152600401610c05906158cd565b600b5442108015610d5f5750610d5a4261012c615904565b600b54105b15610d7d5761012c600b5f828254610d779190615904565b90915550505b600b5442108015610d9c57506006546001600160a01b03828116911614155b610db85760405162461bcd60e51b8152600401610c0590615917565b610dc181614361565b610dc96142a4565b6001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b158015610e01575f80fd5b505af1158015610e13573d5f803e3d5ffd5b505050505034600d5f828254610e299190615904565b90915550506001600160a01b0381165f908152602081905260408120549003610e9757600880546001810182555f919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0383161790555b6001600160a01b0381165f9081526020819052604081208054349290610ebe908490615904565b9091555050601e546001600160a01b0382165f908152602081905260409020541115610efc5760405162461bcd60e51b8152600401610c0590615938565b5f600f5434610f0b9190615954565b9050805f80846001600160a01b03166001600160a01b031681526020019081526020015f206001015f828254610f419190615904565b9250508190555080600e5f828254610f599190615904565b9091555050601d54600d541115610f825760405162461bcd60e51b8152600401610c059061596b565b601d54600d5403610fa557601a805460ff60301b1916600160301b179055426019555b7f46838cf48618a58fe85e0e5a216982cb39ea66766b6279365511ba996556c62e8234604051610fd692919061598d565b60405180910390a150506001601855565b5f610ff0612e5a565b6001600160a01b031663bf7c56e06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561102b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061104f91906159a6565b905090565b6018546001146110765760405162461bcd60e51b8152600401610c0590615851565b5f601855601a54600160201b900460ff16801561109d5750601a54600160281b900460ff16155b6110d55760405162461bcd60e51b81526020600482015260096024820152681b9bdd08195b99195960ba1b6044820152606401610c05565b60648111156111115760405162461bcd60e51b815260206004820152600860248201526706260604a40dac2f60c31b6044820152606401610c05565b5f805f61111c6142a4565b335f908152600160205260408120600601549192509061113f9062015180615904565b4211611149575f80fd5b611152336126b1565b60065491955093506001600160a01b031633036111ad57335f9081526001602052604081206002015490036111ad57600a601554603361119291906159c1565b61119c9086615954565b6111a691906159d4565b9350600190505b5f60646111ba8787615954565b6111c491906159d4565b335f908152600160205260408120600201805492935083929091906111ea908490615904565b9091555050335f908152600160205260409020805460029091015411156112395760405162461bcd60e51b81526020600482015260036024820152624c504f60e81b6044820152606401610c05565b600354611250906001600160a01b03168083614414565b60035460405163226bf2d160e21b81526001600160a01b03909116906389afcb44906112809030906004016154c9565b60408051808303815f875af115801561129b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112bf91906159f3565b50508060125f8282546112d29190615904565b90915550506040517f1a42d431af6fa10e6946404a861f6fb9ae0cb2ebb4efc3b0f61c84d61339aa1290611309903390849061598d565b60405180910390a16006546001600160a01b0316330361136757335f90815260016020526040812060030154900361136757600a601554603361134c91906159c1565b6113569086615954565b61136091906159d4565b9350600191505b5f60646113748887615954565b61137e91906159d4565b335f9081526001602052604090206004015490915082118015906113b35750335f908152600160205260409020600501548111155b806113d057506006546001600160a01b0316331480156113d05750825b6114015760405162461bcd60e51b8152602060048201526002602482015261414d60f01b6044820152606401610c05565b335f9081526001602052604081206003018054839290611422908490615904565b9091555050335f9081526001602081905260409091209081015460039091015411156114765760405162461bcd60e51b81526020600482015260036024820152624c503160e81b6044820152606401610c05565b60045461148d906001600160a01b03168083614414565b6004805460405163226bf2d160e21b81526001600160a01b03909116916389afcb44916114bc913091016154c9565b60408051808303815f875af11580156114d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114fb91906159f3565b50506115063361441f565b6040516370a0823160e01b81526001600160a01b03851690632e1a7d4d9082906370a082319061153a9030906004016154c9565b602060405180830381865afa158015611555573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115799190615a15565b6040518263ffffffff1660e01b815260040161159791815260200190565b5f604051808303815f87803b1580156115ae575f80fd5b505af11580156115c0573d5f803e3d5ffd5b505050506115ce3347614644565b5f6115d7610fe7565b905061164e8133836001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161160a91906154c9565b602060405180830381865afa158015611625573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116499190615a15565b614414565b8160135f82825461165f9190615904565b90915550506040517fb96d785789a045e4950040309c1583cad395a8489e28446f5f93d3b2dbd9a50590611696903390859061598d565b60405180910390a15050335f90815260016020819052604090912042600690910155601855505050505050565b6018546001146116e55760405162461bcd60e51b8152600401610c0590615851565b5f6018556010541580159061170557506006546001600160a01b03163314155b6117395760405162461bcd60e51b815260206004820152600560248201526406e6f206c760dc1b6044820152606401610c05565b335f908152600160205260409020541561177f5760405162461bcd60e51b815260206004820152600760248201526618db185a5b595960ca1b6044820152606401610c05565b600d54335f908152602081905260409020546015546064906117a190826159c1565b6010546117ae9190615954565b6117b891906159d4565b6117c29190615954565b6117cc91906159d4565b335f90815260016020908152604080832093909355600d5490829052919020546015546064906117fc90826159c1565b6011546118099190615954565b61181391906159d4565b61181d9190615954565b61182791906159d4565b335f9081526001602081815260409092209081019290925554905461184c91906159d4565b335f9081526001602081815260409092206004810193909355905491015461187491906159d4565b335f90815260016020819052604090912060050191909155601855565b5f80601254601054116118a4575f6118b4565b6012546010546118b491906159c1565b9150601354601154116118c7575f6118d7565b6013546011546118d791906159c1565b90509091565b6018546001146118ff5760405162461bcd60e51b8152600401610c0590615851565b5f6018556006546001600160a01b03163314611919575f80fd5b5f805f5b8351811015611ac757602484828151811061193a5761193a615a2c565b60200260200101518154811061195257611952615a2c565b905f5260205f209060030201600101544211806119785750601a54600160281b900460ff165b80156119be5750602484828151811061199357611993615a2c565b6020026020010151815481106119ab576119ab615a2c565b905f5260205f209060030201600201545f145b6119da5760405162461bcd60e51b8152600401610c0590615a40565b60248482815181106119ee576119ee615a2c565b602002602001015181548110611a0657611a06615a2c565b5f9182526020909120600390910201549150611a228284615904565b9250816024858381518110611a3957611a39615a2c565b602002602001015181548110611a5157611a51615a2c565b905f5260205f209060030201600201819055507f58f6565f7ca9225084d6c61a164110cd062fec398701e465a82706950ef3e1a082858381518110611a9857611a98615a2c565b6020026020010151604051611ab7929190918252602082015260400190565b60405180910390a160010161191d565b508160175f828254611ad991906159c1565b9091555050600254600654611afb916001600160a01b03908116911684614414565b5050600160185550565b335f9081526001602052604090205415801590611b2157505f81115b611b5f5760405162461bcd60e51b815260206004820152600f60248201526e6e6f20686f6c64206f72206461797360881b6044820152606401610c05565b335f90815260016020526040902060060154611b7e8262015180615954565b611b889042615904565b11611bc95760405162461bcd60e51b81526020600482015260116024820152706d75737420626520696e2066757475726560781b6044820152606401610c05565b611bd68162015180615954565b611be09042615904565b335f8181526001602052604090819020600601839055517f79c93c0a2b06c8a59c5867f08c471f91760f438c5b9dac36e7d41d80585060a792611c23929161598d565b60405180910390a150565b601854600114611c505760405162461bcd60e51b8152600401610c0590615851565b5f6018556006546001600160a01b03163314611c6a575f80fd5b8051825114611ca45760405162461bcd60e51b81526020600482015260066024820152650d8cadccee8d60d31b6044820152606401610c05565b5f805b8351811015611dd857838181518110611cc257611cc2615a2c565b602002602001015182611cd59190615904565b915060246040518060600160405280868481518110611cf657611cf6615a2c565b60200260200101518152602001858481518110611d1557611d15615a2c565b60209081029190910181015182525f918101829052835460018181018655948352918190208351600390930201918255820151928101929092556040015160029091015583517fcbba5b8a19b4433a08340f967e8e5cb07b4c4e80305d04a78d5695f5ed8bd28190859083908110611d8f57611d8f615a2c565b6020026020010151848381518110611da957611da9615a2c565b6020908102919091018101516040805193845291830152810183905260600160405180910390a1600101611ca7565b508060175f828254611dea9190615904565b9091555050600254611afb906001600160a01b0316338361471a565b6006546001600160a01b03163314611e1c575f80fd5b601a546301000000900460ff16158015611e405750601a54600160281b900460ff16155b611e765760405162461bcd60e51b81526020600482015260076024820152661cdd185c9d195960ca1b6044820152606401610c05565b815f03611ed757611e8942610384615904565b811015611ec15760405162461bcd60e51b8152600401610c05906020808252600490820152631c185cdd60e21b604082015260600190565b600a819055600c54611ed39082615904565b600b555b81600103611f4857605a8111158015611ef1575060018110155b611f255760405162461bcd60e51b81526020600482015260056024820152642039302f3160d81b6044820152606401610c05565b611f328162015180615954565b600c819055600a54611f449190615904565b600b555b81600203611f8c576032811115611f865760405162461bcd60e51b8152602060048201526002602482015261035360f41b6044820152606401610c05565b60158190555b81600303611fd4576032811115611fce5760405162461bcd60e51b8152600401610c059060208082526004908201526335302f3160e01b604082015260600190565b60168190555b8160040361201757601d819055601b54611fef9082906159d4565b600f55611ffd6003826159d4565b601c55601e54811061201157601e54612013565b805b601e555b8160050361226b5760025f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561206f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906120939190615a15565b81111580156120bc57506120af60016001600160801b03615a61565b6001600160801b03168111155b6120f75760405162461bcd60e51b815260206004820152600c60248201526b746f74616c20737570706c7960a01b6044820152606401610c05565b601b548082111561212757600254601b54612127916001600160a01b031690339061212290866159c1565b61471a565b80821161214f57600254601b5461214f916001600160a01b03169033906116499086906159c1565b601b8290558161218a5760405162461bcd60e51b8152600401610c05906020808252600490820152637a65726f60e01b604082015260600190565b600f54601b5461219a91906159d4565b601d8190556121ab906003906159d4565b601c55600254604080516318160ddd60e01b815290516064926001600160a01b0316916318160ddd9160048083019260209291908290030181865afa1580156121f6573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061221a9190615a15565b612225906062615954565b61222f91906159d4565b82101580156122405750600b601554105b61224a575f61224d565b60015b601a8054911515600160381b0260ff60381b19909216919091179055505b816006036122b257605a8111158015612285575060078110155b6122a15760405162461bcd60e51b8152600401610c0590615a81565b6122ae8162015180615954565b601f555b8160070361230757601481111580156122cc575060058110155b6123015760405162461bcd60e51b8152600401610c059060208082526004908201526332302f3560e01b604082015260600190565b60208190555b8160080361236657662386f26fc1000081101561234f5760405162461bcd60e51b8152600401610c059060208082526004908201526318b2989b60e11b604082015260600190565b601d54811161235e5780612362565b601d545b601e555b60408051838152602081018390527f57f8066c13130516c76eafcbbaeda0b5339c2ef724f4214c390f902531f5a123910160405180910390a15050565b601a54610100900460ff161580156123c557506005546001600160a01b031633145b6123cd575f80fd5b605a83111580156123df575060078310155b6123fb5760405162461bcd60e51b8152600401610c0590615a81565b601a805461ff0019166101001790556124178362015180615954565b601f556020828155601a805462ff0000191662010000179055600480546001600160a01b038085166001600160a01b0319909216919091178255600254604080516318160ddd60e01b8152905160649592909316936318160ddd9382820193929091908290030181865afa158015612491573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124b59190615a15565b6124c0906062615954565b6124ca91906159d4565b601b54108015906124dd5750600b601554105b156124f657601a805460ff60381b1916600160381b1790555b505050565b5f600f548261250a9190615954565b92915050565b601a54600160281b900460ff161580156125345750601a54600160201b900460ff16155b6125505760405162461bcd60e51b8152600401610c0590615a40565b601c54600d541061258c5760405162461bcd60e51b8152600401610c05906020808252600490820152630736361760e41b604082015260600190565b601a805465ff00000000001916600160281b1790556002546125b6906001600160a01b03166135e0565b60055460025460405163b5e55f2f60e01b81526001600160a01b0391821660048201525f602482015291169063b5e55f2f906044015f604051808303815f87803b158015612602575f80fd5b505af1158015612614573d5f803e3d5ffd5b505060055460025460405163e96be10760e01b81526001600160a01b03928316945063e96be107935061264d92909116906004016154c9565b5f604051808303815f87803b158015612664575f80fd5b505af1158015612676573d5f803e3d5ffd5b5050601a805460ff60381b1916905550506040517fd0710aa9f2dc3d816b38e246a7683ffc8be7b37ac4ac0363c0cde7841eb9afda905f90a1565b5f80806126bc612bef565b6001600160a01b0385165f908152600160205260409020549091501561292e57335f908152600160205260409020600601546126fb9062015180615904565b42111561292e576001600160a01b0384165f908152600160205260409020600281015460049091015461272f908390615954565b111561292e576001600160a01b0384165f90815260016020526040812060048101546002909101546127618483615954565b61276b91906159c1565b116127ac576001600160a01b0385165f908152600160205260409020600281015460049091015461279d908490615954565b6127a791906159c1565b6127c8565b6001600160a01b0385165f908152600160205260409020600401545b6001600160a01b0386165f9081526001602052604090208054600290910154919250906127f59083615904565b116128005780612828565b6001600160a01b0385165f9081526001602052604090206002810154905461282891906159c1565b6001600160a01b0386165f908152600160205260408120600581015460039091015492965090916128598583615954565b61286391906159c1565b116128a4576001600160a01b0386165f9081526001602052604090206003810154600590910154612895908590615954565b61289f91906159c1565b6128c0565b6001600160a01b0386165f908152600160205260409020600501545b6001600160a01b0387165f90815260016020819052604090912090810154600390910154919250906128f29083615904565b116128fd5780612929565b6001600160a01b0386165f908152600160208190526040909120600381015491015461292991906159c1565b935050505b50915091565b6018546001146129565760405162461bcd60e51b8152600401610c0590615851565b5f6018819055338152602081905260409020546129a25760405162461bcd60e51b815260206004820152600a6024820152696e6f2062616c616e636560b01b6044820152606401610c05565b601054156129c25760405162461bcd60e51b8152600401610c059061588f565b601a54600160301b900460ff16156129ee576019546129e4906203f480615904565b42116129ee575f80fd5b335f9081526020819052604090206002015460ff16158015612a275750335f90815260208190526040902060020154610100900460ff16155b612a5d5760405162461bcd60e51b81526020600482015260076024820152661c995d0bd8589d60ca1b6044820152606401610c05565b601a54600160281b900460ff1615612a8e57335f908152602081905260409020600201805461ff0019166101001790555b335f90815260208190526040812060028101805460ff1916600117905554600d805491928392612abf9084906159c1565b9091555050335f90815260208190526040812060010154600e805491928392612ae99084906159c1565b9091555050335f90815260208190526040812081815560018101919091556002015462010000900460ff1615612b3157600160145f828254612b2b91906159c1565b90915550505b601a805460ff60401b1916600160401b179055612b4c6142a4565b6001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b8152600401612b7991815260200190565b5f604051808303815f87803b158015612b90575f80fd5b505af1158015612ba2573d5f803e3d5ffd5b5050601a805460ff60401b1916905550612bbe90503383614644565b7f57a14dfcf9eafb37c308036c6fb972bd18bcc057d36594887421e4f4a60f93c63383604051610fd692919061598d565b601f545f906001825b602054811015612c6057612c0c8383615954565b602154612c199190615904565b421115612c2e57612c2b600183615904565b91505b612c388383615954565b602154612c459190615904565b42111580612c54575060205482145b612c6057600101612bf8565b5092915050565b60248181548110612c76575f80fd5b5f91825260209091206003909102018054600182015460029092015490925083565b601a5460ff16158015612cb557506005546001600160a01b031633145b612cbd575f80fd5b60025f9054906101000a90046001600160a01b03166001600160a01b0316638c00e9b96040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612d3191906159a6565b600680546001600160a01b0319166001600160a01b03928316179055600254604080516324dead2f60e11b8152905191909216916349bd5a5e9160048083019260209291908290030181865afa158015612d8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612db191906159a6565b600380546001600160a01b0319166001600160a01b0392909216919091179055601a805460ff19166001179055601b869055601d849055612df284876159d4565b600f55612e006003856159d4565b601c55601e839055600a8290556276a700600c819055612e209083615904565b600b5560159490945550505060165550565b60098181548110612e41575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f73cced1a96321b2b2a06e8f3f4b0b883ddd059968c6001600160a01b03166385523a1b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561102b573d5f803e3d5ffd5b5f805f805f612eb8612bef565b6001600160a01b0387165f90815260016020526040902060040154612edd9190615954565b90505f612ee8612bef565b6001600160a01b0388165f90815260016020526040902060050154612f0d9190615954565b6001600160a01b0388165f9081526001602052604090206002015490915082111561341d575f612f3b6142a4565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f8e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612fb29190615a15565b90505f60045f9054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613005573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130299190615a15565b90506130348a6126b1565b6002546040805163373556cf60e01b815290519398509196506001600160a01b03169163373556cf916004808201926020929091908290030181865afa158015613080573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130a491906159a6565b6002546003546040516370a0823160e01b81526001600160a01b039384169363d24a1f029387938b93918316926370a08231926130e792909116906004016154c9565b602060405180830381865afa158015613102573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131269190615a15565b6131309190615954565b61313a91906159d4565b6040518263ffffffff1660e01b815260040161315891815260200190565b602060405180830381865afa158015613173573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906131979190615a15565b965060025f9054906101000a90046001600160a01b03166001600160a01b031663373556cf6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061320d91906159a6565b600254600480546040516370a0823160e01b81526001600160a01b039485169463d24a1f029487948b94918316936370a082319361324d931691016154c9565b602060405180830381865afa158015613268573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061328c9190615a15565b6132969190615954565b6132a091906159d4565b6040518263ffffffff1660e01b81526004016132be91815260200190565b602060405180830381865afa1580156132d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132fd9190615a15565b6003546040516370a0823160e01b8152919750839187916001600160a01b03808816926370a08231926133349216906004016154c9565b602060405180830381865afa15801561334f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906133739190615a15565b61337d9190615954565b61338791906159d4565b98508084613393610fe7565b600480546040516370a0823160e01b81526001600160a01b03938416936370a08231936133c49390911691016154c9565b602060405180830381865afa1580156133df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906134039190615a15565b61340d9190615954565b61341791906159d4565b97505050505b50509193509193565b6006546001600160a01b03163314801561344e57506006546001600160a01b03838116911614155b613456575f80fd5b6001600160a01b0382165f9081526020819052604090206002015462010000900460ff166134f55780613487575f80fd5b601a546301000000900460ff161561349d575f80fd5b60228054600160ff1990911681179091556009805491820181555f527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0180546001600160a01b0319166001600160a01b0384161790555b60225460ff16613503575f80fd5b6001600160a01b0382165f9081526020819052604090206002015462010000900460ff1615613557578015613536575f80fd5b6001600160a01b0382165f9081526020819052604090205415613557575f80fd5b6001600160a01b0382165f908152602081905260409020600201805462ff00001916620100008315158102919091179182905560ff9104166135a7576023546135a2906001906159c1565b6135b5565b6023546135b5906001615904565b6023819055601454146135c95760016135cb565b5f5b6022805460ff19169115159190911790555050565b6018546001146136025760405162461bcd60e51b8152600401610c0590615851565b5f6018556006546001600160a01b0316331461361c575f80fd5b613624610fe7565b6001600160a01b0316816001600160a01b03161415801561365357506003546001600160a01b03828116911614155b801561366d57506004546001600160a01b03828116911614155b613675575f80fd5b6007546001600160a01b03828116911614806136a957506136946142a4565b6001600160a01b0316816001600160a01b0316145b156136ec57600d54156136ec5760405162461bcd60e51b815260206004820152600b60248201526a072616973656420213d20360ac1b6044820152606401610c05565b6040516370a0823160e01b81525f906001600160a01b038316906370a082319061371a9030906004016154c9565b602060405180830381865afa158015613735573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906137599190615a15565b6002549091506001600160a01b03908116908316036137e157601a546301000000900460ff16156137c357601a54600160281b900460ff166137c35760405162461bcd60e51b81526020600482015260036024820152620e4c2f60eb1b6044820152606401610c05565b6017546137d090826159c1565b5f601b819055601d819055601c5590505b80156137ff576006546137ff9083906001600160a01b031683614414565b471561381b5760065461381b906001600160a01b031647614644565b50506001601855565b5f61382d612e5a565b6001600160a01b031663122fea3b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561102b573d5f803e3d5ffd5b601a54600160281b900460ff1615801561388c5750601a54600160201b900460ff16155b80156138a15750601a546301000000900460ff165b6138bd5760405162461bcd60e51b8152600401610c0590615a40565b6006546001600160a01b031633148061394357506138d9612e5a565b6001600160a01b03166324d7806c336040518263ffffffff1660e01b815260040161390491906154c9565b602060405180830381865afa15801561391f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906139439190615874565b61394b575f80fd5b600b544211801561395f5750601c54600d54105b1561397857600c546139719042615904565b600b555050565b601a54600160301b900460ff16806139a05750600b54421180156139a05750601c54600d5410155b6139a8575f80fd5b6139b28282614726565b60055460025460405163e96be10760e01b81526001600160a01b039283169263e96be107926139e6929116906004016154c9565b5f604051808303815f87803b1580156139fd575f80fd5b505af1158015613a0f573d5f803e3d5ffd5b5050601a805464ff000000001916600160201b179055505042600b555050565b6006546001600160a01b03163314613a45575f80fd5b601a546301000000900460ff1615613a5b575f80fd5b6022805460ff1916600117905580515f5b818110156124f6575f80848381518110613a8857613a88615a2c565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2060020160029054906101000a900460ff16158015613aff575060065483516001600160a01b0390911690849083908110613aeb57613aeb615a2c565b60200260200101516001600160a01b031614155b613b1b5760405162461bcd60e51b8152600401610c0590615a40565b60015f80858481518110613b3157613b31615a2c565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020015f2060020160026101000a81548160ff0219169083151502179055506001601b6008015f828254613b879190615904565b925050819055506009838281518110613ba257613ba2615a2c565b6020908102919091018101518254600180820185555f9485529290932090920180546001600160a01b0319166001600160a01b039093169290921790915501613a6c565b5f601854600114613c095760405162461bcd60e51b8152600401610c0590615851565b5f601855613c1561420f565b613c1d612e5a565b6001600160a01b0316632c86cba3336040518263ffffffff1660e01b8152600401613c4891906154c9565b602060405180830381865afa158015613c63573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613c879190615874565b613c8f573394505b6002546001600160a01b0390811690851603613cdd5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b2103a37b5b2b760991b6044820152606401610c05565b5f8311613cfc5760405162461bcd60e51b8152600401610c05906158cd565b6001600160a01b0385165f9081526020819052604090206002015460ff1615613d375760405162461bcd60e51b8152600401610c05906158ad565b5f613d406142a4565b601a54909150600160301b900460ff16158015613d675750601a54600160281b900460ff16155b8015613d7c5750601a546301000000900460ff165b613d985760405162461bcd60e51b8152600401610c059061588f565b600b5442108015613db55750613db04261012c615904565b600b54105b15613dd35761012c600b5f828254613dcd9190615904565b90915550505b600b5442108015613df257506006546001600160a01b03878116911614155b613e0e5760405162461bcd60e51b8152600401610c0590615917565b613e1786614361565b6001600160a01b0386165f908152602081905260408120549003613e8057600880546001810182555f919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0388161790555b6040516370a0823160e01b81525f906001600160a01b038716906370a0823190613eae9030906004016154c9565b602060405180830381865afa158015613ec9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613eed9190615a15565b9050613efb86333088614e77565b5f81876001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401613f2991906154c9565b602060405180830381865afa158015613f44573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f689190615a15565b613f7291906159c1565b90505f836001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401613fa191906154c9565b602060405180830381865afa158015613fbc573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613fe09190615a15565b9050613fed888388614ee2565b5f81856001600160a01b03166370a08231306040518263ffffffff1660e01b815260040161401b91906154c9565b602060405180830381865afa158015614036573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061405a9190615a15565b61406491906159c1565b90505f811161409f5760405162461bcd60e51b81526020600482015260076024820152660616d74496e20360cc1b6044820152606401610c05565b80600d5f8282546140b09190615904565b90915550506001600160a01b038a165f90815260208190526040812080548392906140dc908490615904565b9091555050601e546001600160a01b038b165f90815260208190526040902054111561411a5760405162461bcd60e51b8152600401610c0590615938565b5f600f54826141299190615954565b9050805f808d6001600160a01b03166001600160a01b031681526020019081526020015f206001015f82825461415f9190615904565b9250508190555080600e5f8282546141779190615904565b9091555050601d54600d5411156141a05760405162461bcd60e51b8152600401610c059061596b565b601d54600d54036141c357601a805460ff60301b1916600160301b179055426019555b7f46838cf48618a58fe85e0e5a216982cb39ea66766b6279365511ba996556c62e8b836040516141f492919061598d565b60405180910390a15060016018559998505050505050505050565b601a546301000000900460ff1661423e57600a5442111561423e57601a805463ff000000191663010000001790555b565b6001600160a01b0381165f9081526001602052604081206006015481908190421061426b575f61426e565b60015b90505f8161427c575f614298565b6001600160a01b0385165f908152600160205260409020600601545b91959194509092505050565b5f6142ad612e5a565b6001600160a01b031663f24286216040518163ffffffff1660e01b8152600401602060405180830381865afa15801561102b573d5f803e3d5ffd5b6006546001600160a01b031633146142fe575f80fd5b601a546301000000900460ff1615806143375750601a546301000000900460ff16801561432d575060225460ff165b8015614337575080155b61433f575f80fd5b6022805460ff1916911515919091179055565b60088181548110612e41575f80fd5b60225460ff1615614411576001600160a01b0381165f9081526020819052604090206002015462010000900460ff166143c55760405162461bcd60e51b81526020600482015260066024820152651b9bdd081ddb60d21b6044820152606401610c05565b6001600160a01b0381165f90815260208190526040902054156143ea576014546143f8565b6014546143f8906001615904565b60148190556023549003614411576022805460ff191690555b50565b6124f6838383614ff0565b6002546040805163373556cf60e01b815290515f926001600160a01b03169163373556cf9160048083019260209291908290030181865afa158015614466573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061448a91906159a6565b6017546002546040516370a0823160e01b81529293505f926001600160a01b03909116906370a08231906144c29030906004016154c9565b602060405180830381865afa1580156144dd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906145019190615a15565b61450b91906159c1565b6007546040516370a0823160e01b81529192505f916001600160a01b03909116906370a08231906145409086906004016154c9565b602060405180830381865afa15801561455b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061457f9190615a15565b905066038d7ea4c680008110156145a9576002546145a9906001600160a01b031661dead84614414565b66038d7ea4c68000811061463e576002546145ce906001600160a01b0316848461500f565b604051630e9ec60f60e01b81526001600160a01b03841690630e9ec60f906145fc908790869060040161598d565b6020604051808303815f875af1158015614618573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061463c9190615a15565b505b50505050565b604080515f808252602082019092526001600160a01b03841690839060405161466d9190615ac1565b5f6040518083038185875af1925050503d805f81146146a7576040519150601f19603f3d011682016040523d82523d5f602084013e6146ac565b606091505b50509050806124f65760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b6064820152608401610c05565b6124f683833084614e77565b5f61472f610fe7565b6005546040805163e97206a960e01b815281519394505f9384936001600160a01b03169263e97206a992600480820193918290030181865afa158015614777573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061479b91906159f3565b909250905081156148be576147ae612e5a565b6001600160a01b0316637f2a47686040518163ffffffff1660e01b8152600401602060405180830381865afa1580156147e9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061480d91906159a6565b6040516383db77c360e01b81526001600160a01b038581166004830152602482018590526044820184905291909116906383db77c390606401602060405180830381865afa158015614861573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906148859190615874565b156148be5760405162461bcd60e51b8152602060048201526009602482015268233937b73a10393ab760b91b6044820152606401610c05565b601654156148cf576148cf846150ae565b5f6148d86142a4565b600554604051636fcca69b60e01b81529192505f916103e8916001600160a01b031690636fcca69b9061490f9030906004016154c9565b602060405180830381865afa15801561492a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061494e9190615a15565b6040516370a0823160e01b81526001600160a01b038516906370a082319061497a9030906004016154c9565b602060405180830381865afa158015614995573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906149b99190615a15565b6149c39190615954565b6149cd91906159d4565b600554604051636fcca69b60e01b81529192505f916103e8916001600160a01b031690636fcca69b90614a049030906004016154c9565b602060405180830381865afa158015614a1f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614a439190615a15565b601b54614a509190615954565b614a5a91906159d4565b90505f81601b5f0154614a6d91906159c1565b9050614a8184614a7b613824565b8561500f565b6040805160028082526060820183525f9260208301908036833701905050905084815f81518110614ab457614ab4615a2c565b60200260200101906001600160a01b031690816001600160a01b0316815250508781600181518110614ae857614ae8615a2c565b60200260200101906001600160a01b031690816001600160a01b031681525050614b10613824565b6001600160a01b0316635c11d795858c8430426040518663ffffffff1660e01b8152600401614b43959493929190615adc565b5f604051808303815f87803b158015614b5a575f80fd5b505af1158015614b6c573d5f803e3d5ffd5b5050600254600354614b8d93506001600160a01b0391821692501684614414565b6003546040516370a0823160e01b8152614bc69187916001600160a01b03918216918316906370a082319061160a9030906004016154c9565b6003546040516335313c2160e11b81526001600160a01b0390911690636a62784290614bf69030906004016154c9565b6020604051808303815f875af1158015614c12573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614c369190615a15565b6010819055606490614c49906062615954565b614c5391906159d4565b601055601554614c63575f614c7f565b6064601554601054614c759190615954565b614c7f91906159d4565b600680546001600160a01b039081165f9081526001602090815260408083209590955554925490911681529190912054614cb991906159d4565b6006546001600160a01b039081165f9081526001602052604090819020600490810193909355825490516370a0823160e01b8152614d0c938c93928316928416916370a082319161160a913091016154c9565b600254600454614d29916001600160a01b03908116911685614414565b600480546040516335313c2160e11b81526001600160a01b0390911691636a62784291614d58913091016154c9565b6020604051808303815f875af1158015614d74573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190614d989190615a15565b6011819055606490614dab906062615954565b614db591906159d4565b601155601554614dc5575f614de1565b6064601554601154614dd79190615954565b614de191906159d4565b600680546001600160a01b039081165f90815260016020818152604080842083019690965554935490921681529290922090910154614e2091906159d4565b6006546001600160a01b03165f90815260016020526040808220600501929092554260215590517fd0710aa9f2dc3d816b38e246a7683ffc8be7b37ac4ac0363c0cde7841eb9afda9190a150505050505050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261463e9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526152b7565b614ef483614eee613824565b8461500f565b6040805160028082526060820183525f9260208301908036833701905050905083815f81518110614f2757614f27615a2c565b60200260200101906001600160a01b031690816001600160a01b031681525050614f4f6142a4565b81600181518110614f6257614f62615a2c565b60200260200101906001600160a01b031690816001600160a01b031681525050614f8a613824565b6001600160a01b0316635c11d79584848430426040518663ffffffff1660e01b8152600401614fbd959493929190615adc565b5f604051808303815f87803b158015614fd4575f80fd5b505af1158015614fe6573d5f803e3d5ffd5b5050505050505050565b6124f68363a9059cbb60e01b8484604051602401614eab92919061598d565b8015806150875750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015615061573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906150859190615a15565b155b61508f575f80fd5b6124f68363095ea7b360e01b8484604051602401614eab92919061598d565b5f6064601654600d546150c19190615954565b6150cb91906159d4565b90505f60025f9054906101000a90046001600160a01b03166001600160a01b031663373556cf6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561511e573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061514291906159a6565b90505f61514d6142a4565b6007549091506001600160a01b038083169116146152975761517181614a7b613824565b604080516002808252606080830184529260208301908036833701905050905081815f815181106151a4576151a4615a2c565b6001600160a01b0392831660209182029290920101526007548251911690829060019081106151d5576151d5615a2c565b60200260200101906001600160a01b031690816001600160a01b0316815250506151fd613824565b6001600160a01b0316635c11d79585878430426040518663ffffffff1660e01b8152600401615230959493929190615adc565b5f604051808303815f87803b158015615247575f80fd5b505af1158015615259573d5f803e3d5ffd5b50506007546040516370a0823160e01b815261529593506001600160a01b039091169150859082906370a082319061160a9030906004016154c9565b505b6007546001600160a01b0380831691160361463e5761463e818385614414565b5f6152fc826040518060400160405280600e81526020016d5361666545524332303a206c6f7760901b815250856001600160a01b031661535c9092919063ffffffff16565b8051909150156124f6578080602001905181019061531a9190615874565b6124f65760405162461bcd60e51b815260206004820152601360248201527205361666545524332303a204552433230206f7606c1b6044820152606401610c05565b606061536a84845f85615372565b949350505050565b6060824710156153b65760405162461bcd60e51b815260206004820152600f60248201526e20b2323932b9b99d1034b739bab33360891b6044820152606401610c05565b5f80866001600160a01b031685876040516153d19190615ac1565b5f6040518083038185875af1925050503d805f811461540b576040519150601f19603f3d011682016040523d82523d5f602084013e615410565b606091505b50915091506154218783838761542c565b979650505050505050565b6060831561549a5782515f03615493576001600160a01b0385163b6154935760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610c05565b508161536a565b61536a83838151156154af5781518083602001fd5b8060405162461bcd60e51b8152600401610c059190615b4d565b6001600160a01b0391909116815260200190565b5f602082840312156154ed575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715615531576155316154f4565b604052919050565b5f67ffffffffffffffff821115615552576155526154f4565b5060051b60200190565b5f82601f83011261556b575f80fd5b8135602061558061557b83615539565b615508565b8083825260208201915060208460051b8701019350868411156155a1575f80fd5b602086015b848110156155bd57803583529183019183016155a6565b509695505050505050565b5f602082840312156155d8575f80fd5b813567ffffffffffffffff8111156155ee575f80fd5b61536a8482850161555c565b5f806040838503121561560b575f80fd5b823567ffffffffffffffff80821115615622575f80fd5b61562e8683870161555c565b93506020850135915080821115615643575f80fd5b506156508582860161555c565b9150509250929050565b5f806040838503121561566b575f80fd5b50508035926020909101359150565b6001600160a01b0381168114614411575f80fd5b5f805f606084860312156156a0575f80fd5b833592506020840135915060408401356156b98161567a565b809150509250925092565b5f602082840312156156d4575f80fd5b81356156df8161567a565b9392505050565b5f805f805f8060c087890312156156fb575f80fd5b505084359660208601359650604086013595606081013595506080810135945060a0013592509050565b8015158114614411575f80fd5b5f8060408385031215615743575f80fd5b823561574e8161567a565b9150602083013561575e81615725565b809150509250929050565b5f602080838503121561577a575f80fd5b823567ffffffffffffffff811115615790575f80fd5b8301601f810185136157a0575f80fd5b80356157ae61557b82615539565b81815260059190911b820183019083810190878311156157cc575f80fd5b928401925b828410156154215783356157e48161567a565b825292840192908401906157d1565b5f805f8060808587031215615806575f80fd5b84356158118161567a565b935060208501356158218161567a565b93969395505050506040820135916060013590565b5f60208284031215615846575f80fd5b81356156df81615725565b6020808252600990820152681c99595b9d1c985b9d60ba1b604082015260600190565b5f60208284031215615884575f80fd5b81516156df81615725565b6020808252600490820152631cdbdd5d60e21b604082015260600190565b602080825260069082015265195e1a5d195960d21b604082015260600190565b6020808252600990820152681b9bc8185b5bdd5b9d60ba1b604082015260600190565b634e487b7160e01b5f52601160045260245ffd5b8082018082111561250a5761250a6158f0565b602080825260079082015266074696d652075760cc1b604082015260600190565b60208082526002908201526126a160f11b604082015260600190565b808202811582820484141761250a5761250a6158f0565b6020808252600890820152671bdd995c9cdbdb1960c21b604082015260600190565b6001600160a01b03929092168252602082015260400190565b5f602082840312156159b6575f80fd5b81516156df8161567a565b8181038181111561250a5761250a6158f0565b5f826159ee57634e487b7160e01b5f52601260045260245ffd5b500490565b5f8060408385031215615a04575f80fd5b505080516020909101519092909150565b5f60208284031215615a25575f80fd5b5051919050565b634e487b7160e01b5f52603260045260245ffd5b602080825260079082015266616c726561647960c81b604082015260600190565b6001600160801b03828116828216039080821115612c6057612c606158f0565b60208082526004908201526339302f3760e01b604082015260600190565b5f5b83811015615ab9578181015183820152602001615aa1565b50505f910152565b5f8251615ad2818460208701615a9f565b9190910192915050565b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b81811015615b2c5784516001600160a01b031683529383019391830191600101615b07565b50506001600160a01b03969096166060850152505050608001529392505050565b602081525f8251806020840152615b6b816040850160208701615a9f565b601f01601f1916919091016040019291505056fea2646970667358221220d33e51511ed5052d591f93ae7fcc1bd4ff69c346bb1366903b0a5769fe5213f764736f6c63430008180033a2646970667358221220b4e037fbc04249ffa3e35c21c03620c0c3f5654a228c087bfed6d579dd0fe76964736f6c63430008180033

Deployed Bytecode Sourcemap

3084:456:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3192:345;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;848:32:1;;;830:51;;818:2;803:18;3192:345:0;;;;;;;3117:68;;;;;-1:-1:-1;;;;;3117:68:0;;;3192:345;3275:11;3332:5;-1:-1:-1;;;;;3307:30:0;3312:5;-1:-1:-1;;;;;3307:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;3307:30:0;;:100;;;;-1:-1:-1;3357:8:0;;3348:30;;;-1:-1:-1;;;3348:30:0;;;;3397:10;;-1:-1:-1;;;;;3357:8:0;;3348:28;;:30;;;;;;;;;;;;;;3357:8;3348:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;3341:50:0;;:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;3341:66:0;;3307:100;3299:122;;;;-1:-1:-1;;;3299:122:0;;1350:2:1;3299:122:0;;;1332:21:1;1389:1;1369:18;;;1362:29;-1:-1:-1;;;1407:18:1;;;1400:39;1456:18;;3299:122:0;;;;;;;;3456:10;3468:5;3475:7;3484:15;3501:5;3446:61;;;;;:::i;:::-;-1:-1:-1;;;;;1800:15:1;;;1782:34;;1852:15;;;1847:2;1832:18;;1825:43;1904:15;;;1899:2;1884:18;;1877:43;1951:2;1936:18;;1929:34;2000:15;;;1994:3;1979:19;;1972:44;1731:3;1716:19;3446:61:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3432:76:0;3192:345;-1:-1:-1;;;;3192:345:0:o;-1:-1:-1:-;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;69:70;14:131;:::o;150:529::-;227:6;235;243;296:2;284:9;275:7;271:23;267:32;264:52;;;312:1;309;302:12;264:52;351:9;338:23;370:31;395:5;370:31;:::i;:::-;420:5;-1:-1:-1;477:2:1;462:18;;449:32;490:33;449:32;490:33;:::i;:::-;542:7;-1:-1:-1;601:2:1;586:18;;573:32;614:33;573:32;614:33;:::i;:::-;666:7;656:17;;;150:529;;;;;:::o;892:251::-;962:6;1015:2;1003:9;994:7;990:23;986:32;983:52;;;1031:1;1028;1021:12;983:52;1063:9;1057:16;1082:31;1107:5;1082:31;:::i;:::-;1132:5;892:251;-1:-1:-1;;;892:251:1:o

Swarm Source

ipfs://b4e037fbc04249ffa3e35c21c03620c0c3f5654a228c087bfed6d579dd0fe769

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.