POL Price: $0.70463 (+1.71%)
Gas: 30.5 GWei
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 POL

POL Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Add Order616854082024-09-11 7:14:4986 days ago1726038889IN
0x5D36b36c...e25Bd888B
0 POL0.0135242236.77699384
Add Order For ET...551674252024-03-28 6:52:54253 days ago1711608774IN
0x5D36b36c...e25Bd888B
0 POL0.0317473269.02583842
Add Order With E...551673662024-03-28 6:50:48253 days ago1711608648IN
0x5D36b36c...e25Bd888B
27 POL0.0363941577.95450533
Add Order For ET...546673042024-03-15 0:25:43267 days ago1710462343IN
0x5D36b36c...e25Bd888B
0 POL0.05322301116.939224
Add Order With E...546665322024-03-14 23:55:57267 days ago1710460557IN
0x5D36b36c...e25Bd888B
15.66202382 POL0.0431926982.52235701
Cancel Order For...544275942024-03-08 21:41:29273 days ago1709934089IN
0x5D36b36c...e25Bd888B
0 POL0.02298842159.36188027
Add Order502360042023-11-22 2:54:18381 days ago1700621658IN
0x5D36b36c...e25Bd888B
0 POL0.0182562939.00000038
Add Order With E...494550852023-11-02 13:35:07400 days ago1698932107IN
0x5D36b36c...e25Bd888B
0.1 POL0.0428477991.78025716
Add Order For ET...458003992023-08-02 1:00:46493 days ago1690938046IN
0x5D36b36c...e25Bd888B
0 POL0.05436786116.99310652
Add Order For ET...458003792023-08-02 0:59:32493 days ago1690937972IN
0x5D36b36c...e25Bd888B
0 POL0.0440453594.78029985
Add Order With E...458002842023-08-02 0:56:10493 days ago1690937770IN
0x5D36b36c...e25Bd888B
0.1 POL0.04872724112.6245748
Add Order With E...458002442023-08-02 0:54:44493 days ago1690937684IN
0x5D36b36c...e25Bd888B
0.1 POL0.04575411105.75268808
Add Order With E...444294532023-06-28 7:37:44527 days ago1687937864IN
0x5D36b36c...e25Bd888B
90 POL0.18140949403.34374725
Add Order With E...435188402023-06-04 12:24:45551 days ago1685881485IN
0x5D36b36c...e25Bd888B
1 POL0.1027191228.39055508
Add Order For ET...427461622023-05-15 19:29:27571 days ago1684178967IN
0x5D36b36c...e25Bd888B
0 POL0.09692357201.16053809
Add Order For ET...426994412023-05-14 15:34:16572 days ago1684078456IN
0x5D36b36c...e25Bd888B
0 POL0.11074532229.84124675
Cancel Order For...421283382023-04-30 7:43:08586 days ago1682840588IN
0x5D36b36c...e25Bd888B
0 POL0.06652087410.4833108
Add Order For ET...421010932023-04-29 14:51:07587 days ago1682779867IN
0x5D36b36c...e25Bd888B
0 POL0.23343862448.00202331
Add Order For ET...419803222023-04-26 12:28:55590 days ago1682512135IN
0x5D36b36c...e25Bd888B
0 POL0.22949608440.43573634
Cancel Order For...419438192023-04-25 14:45:47591 days ago1682433947IN
0x5D36b36c...e25Bd888B
0 POL0.08176876566.8427304
Cancel Order For...419437742023-04-25 14:44:11591 days ago1682433851IN
0x5D36b36c...e25Bd888B
0 POL0.08807412545.84747673
Add Order With E...418958052023-04-24 8:41:45592 days ago1682325705IN
0x5D36b36c...e25Bd888B
45 POL0.34853895774.93741502
Cancel Order For...418745422023-04-23 18:43:00593 days ago1682275380IN
0x5D36b36c...e25Bd888B
0 POL0.06356819451.18062885
Add Order With E...418744222023-04-23 18:38:44593 days ago1682275124IN
0x5D36b36c...e25Bd888B
54 POL0.29764413568.68083877
Add Order For ET...413686892023-04-10 13:12:00606 days ago1681132320IN
0x5D36b36c...e25Bd888B
0 POL0.07284924183.11100648
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
551674252024-03-28 6:52:54253 days ago1711608774
0x5D36b36c...e25Bd888B
26.50595642 POL
551674252024-03-28 6:52:54253 days ago1711608774
0x5D36b36c...e25Bd888B
26.50595642 POL
551673662024-03-28 6:50:48253 days ago1711608648
0x5D36b36c...e25Bd888B
27 POL
546673042024-03-15 0:25:43267 days ago1710462343
0x5D36b36c...e25Bd888B
15.47590701 POL
546673042024-03-15 0:25:43267 days ago1710462343
0x5D36b36c...e25Bd888B
15.47590701 POL
546665322024-03-14 23:55:57267 days ago1710460557
0x5D36b36c...e25Bd888B
15.66202382 POL
494550852023-11-02 13:35:07400 days ago1698932107
0x5D36b36c...e25Bd888B
0.1 POL
458003992023-08-02 1:00:46493 days ago1690938046
0x5D36b36c...e25Bd888B
0.10000082 POL
458003992023-08-02 1:00:46493 days ago1690938046
0x5D36b36c...e25Bd888B
0.10000082 POL
458003792023-08-02 0:59:32493 days ago1690937972
0x5D36b36c...e25Bd888B
0.10000099 POL
458003792023-08-02 0:59:32493 days ago1690937972
0x5D36b36c...e25Bd888B
0.10000099 POL
458002842023-08-02 0:56:10493 days ago1690937770
0x5D36b36c...e25Bd888B
0.1 POL
458002442023-08-02 0:54:44493 days ago1690937684
0x5D36b36c...e25Bd888B
0.1 POL
444294532023-06-28 7:37:44527 days ago1687937864
0x5D36b36c...e25Bd888B
90 POL
435188402023-06-04 12:24:45551 days ago1685881485
0x5D36b36c...e25Bd888B
1 POL
427461622023-05-15 19:29:27571 days ago1684178967
0x5D36b36c...e25Bd888B
7.00000114 POL
427461622023-05-15 19:29:27571 days ago1684178967
0x5D36b36c...e25Bd888B
7.00000114 POL
426994412023-05-14 15:34:16572 days ago1684078456
0x5D36b36c...e25Bd888B
21.99999159 POL
426994412023-05-14 15:34:16572 days ago1684078456
0x5D36b36c...e25Bd888B
21.99999159 POL
421010932023-04-29 14:51:07587 days ago1682779867
0x5D36b36c...e25Bd888B
13.85258801 POL
421010932023-04-29 14:51:07587 days ago1682779867
0x5D36b36c...e25Bd888B
13.85258801 POL
419925462023-04-26 19:55:27590 days ago1682538927
0x5D36b36c...e25Bd888B
0.40996475 POL
419925462023-04-26 19:55:27590 days ago1682538927
0x5D36b36c...e25Bd888B
0.40996475 POL
419925272023-04-26 19:54:45590 days ago1682538885
0x5D36b36c...e25Bd888B
13.35711203 POL
419925272023-04-26 19:54:45590 days ago1682538885
0x5D36b36c...e25Bd888B
13.35711203 POL
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MyTradeOrderBook

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 1 : MyTradeOrderBook.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.6.0 <0.8.0;

/**
 * @title SafeMath
 * @dev Unsigned math operations with safety checks that revert on error.
 */
library SafeMath {
    /**
     * @dev Multiplies two unsigned integers, reverts on overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b,"mul");

        return c;
    }

    /**
     * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0,"div");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a,"sub");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Adds two unsigned integers, reverts on overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a,"add");

        return c;
    }

}
/**
 * @title ERC20 interface
 * @dev see https://eips.ethereum.org/EIPS/eip-20
 */
interface IERC20 {
    function transfer(address to, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
    function balanceOf(address who) external view returns (uint256);

}
interface IUniswapV2Factory {
    function getPair(address tokenA, address tokenB) external view returns (address pair);
}
interface IUniswapV2Pair {
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
}
/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
    address private _owner;

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

    /**
     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
     * account.
     */
    constructor () {
        _owner = msg.sender;
        emit OwnershipTransferred(address(0), _owner);
    }

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

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

    /**
     * @return true if `msg.sender` is the owner of the contract.
     */
    function isOwner() public view returns (bool) {
        return msg.sender == _owner;
    }

    /**
     * @dev Allows the current owner to relinquish control of the contract.
     * It will not be possible to call the functions with the `onlyOwner`
     * modifier anymore.
     * @notice Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Allows the current owner to transfer control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function transferOwnership(address newOwner) public onlyOwner {
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers control of the contract to a newOwner.
     * @param newOwner The address to transfer ownership to.
     */
    function _transferOwnership(address newOwner) internal {
        require(newOwner != address(0),"incorrect address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}
contract ReentrancyGuard {
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;
    uint256 private _status;
    constructor () {
        _status = _NOT_ENTERED;
    }
    modifier nonReentrant() {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
        _status = _ENTERED;
        _;
        _status = _NOT_ENTERED;
    }
}
interface IWETH {
    function deposit() external payable;

    function transfer(address to, uint value) external returns (bool);

    function withdraw(uint) external;
}
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('approve(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: MyTradeOrderBook APPROVE_FAILED');
    }

    function safeTransfer(address token, address to, uint value) internal {
        // bytes4(keccak256(bytes('transfer(address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: MyTradeOrderBook TRANSFER_FAILED');
    }

    function safeTransferFrom(address token, address from, address to, uint value) internal {
        // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: MyTradeOrderBook TRANSFER_FROM_FAILED');
    }

    function safeTransferETH(address to, uint value) internal {
        (bool success,) = to.call{value:value}(new bytes(0));
        require(success, 'TransferHelper: MyTradeOrderBook ETH_TRANSFER_FAILED');
    }
}

interface IMyTradeOrderBookExt{
    function liquidityPrice(
        address _fromTokenAddr,
        address _toTokenAddr,
        address _pairAddr,
        uint _reserve0,
        uint _reserve1
    )external;
    function cancelOrderWithNum(//按数量取消订单
        address _fromTokenAddr,// 卖出token地址
        address _toTokenAddr,// 买入token地址
        uint256 _orderIndex,// 具体订单号(目前是订单的唯一性标识)
        uint256 _num
    )external;

    function addOrder(
        address _maker,
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _fromTokenNumber,
        uint256 _toTokenNumber,
        uint256 _orderIndex
    )external;
    function updateOrderInfo(
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _orderIndex,
        uint256 _outNum,
        uint256 _inNum
    )external;
    function getOrderIndexsForMaker(
        address _fromTokenAddr,
        address _toTokenAddr,
        address _maker
    )external view returns(uint256[] memory cindexs);
    function getOrderInfo(
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _orderIndex
   )external view returns(uint256 _orderTime,uint256 _toTokenSum);
}
interface IMyTradeOrderMining{
    function updateOrderMiningNumByOuter() external returns (bool);
}
interface ISwapMining {
    function swap(address account, address input, address output, uint256 amount) external returns (bool);
}
library OrderBookHelper{
    using SafeMath for uint;
   
   // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
        uint amountInWithFee = amountIn.mul(997);
        uint numerator = amountInWithFee.mul(reserveOut);
        uint denominator = reserveIn.mul(1000).add(amountInWithFee);
        amountOut = numerator / denominator;
    }
     // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
    function sqrt(uint256 y) internal pure returns (uint256 z) {
        if (y > 3) {
            z = y;
            uint x = y / 2 + 1;
            while (x < z) {
                z = x;
                x = (y / x + x) / 2;
            }
        } else if (y != 0) {
            z = 1;
        }
    }
    function getInAmount(
        uint256 fromNum,
        uint256 toNum,
        uint256 reserveA,
        uint256 reserveB
    ) internal pure returns(uint256 z){
        uint256 p=reserveA.mul(reserveB).mul(fromNum).mul(1000)/997/toNum;
        uint256 q=reserveA.mul(reserveA).mul(8973)/3964107892;
        uint256 x=sqrt(p.add(q));

        uint256 y=reserveA.mul(1997)/1994;
        if(x>y){
            z=x.sub(y).add(1);
        }else{
            z=0;
        }
    }
    function joinNumber(
        uint256 _number,
        uint256[] memory narray
    )internal pure returns(uint256[] memory){
        if(_number==0){
            return narray;
        }
        uint256 nl=narray.length;
        uint256[] memory narray1=new uint256[](nl+1);
        for(uint256 i=0;i<nl;i++){
            narray1[i]=narray[i];
        }
        narray1[nl]=_number;
        return narray1;
    }
    function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    }
}
contract MyTradeOrderBook is Ownable,ReentrancyGuard{
    using SafeMath for uint;
    IUniswapV2Factory immutable public uniswapV2Factory;
    address immutable public WETH;
    address public feeAddr;
    uint256 constant UINT256_MAX = ~uint256(0);
    IMyTradeOrderBookExt myTradeOrderBookExt;
    address public myTradeOrderMining;
    address public swapMining;
    function setMyTradeOrderMining(address _myTradeOrderMining) public onlyOwner {
        myTradeOrderMining = _myTradeOrderMining;
    }
    address public forPreDiposit;
     function setForPreDiposit(address _forPreDiposit) public onlyOwner {
        forPreDiposit = _forPreDiposit;
    }
    function setSwapMining(address _swapMininng) public onlyOwner {
        swapMining = _swapMininng;
    }
    //最小数量限额:0.1,可外部设置
    mapping (address  => uint) minLimitMap;
    /**
     *设置最小允许的数
     */
    function setMinLimit(
        address _tokenAddr,
        uint _minLimit
    ) onlyOwner public returns(bool) {
        minLimitMap[_tokenAddr] = _minLimit;
        return true;
    }
    
    struct Order{
        address maker;
        address fromTokenAddr;
        address toTokenAddr;
        uint256 remainNumber;
        uint256 fromTokenNumber;// 代币挂单金额
        uint256 toTokenNumber;// 意向代币目标金额
    }
    struct TokenPair{
        uint256 orderMaxIndex;
        mapping(address=> uint256) lastIndex;
        mapping(uint256=> Order) orderMap;// orderIndex=》Order
        mapping(uint256=> uint256) orderNextSequence;// 价格低的orderIndex=》价格高的orderIndex
        mapping(uint256=> uint256) orderPreSequence;// 价格高的orderIndex=》价格低的orderIndex
    }
    mapping (address=> mapping (uint  => uint8)) isForEth;
    TokenPair[] tokenPairArray;// tokenPair数组
    mapping (address  => uint256) tokenPairIndexMap;// tokenPairAddr=>tokenPair数组下标
    address immutable public flashLoan;
    constructor(
        address _WETH,
        address _uniswapV2Factory
    ) payable  {
        WETH=_WETH;
        feeAddr=msg.sender;
        tokenPairArray.push();
        uniswapV2Factory=IUniswapV2Factory(_uniswapV2Factory);
        flashLoan=address(new FlashLoan(msg.sender));
    }
    function safeApproveFlashLoan(
        address tokenA
    )public{
    	TransferHelper.safeApprove(
            tokenA,
            flashLoan,
            UINT256_MAX
        );
    }
    function setMyTradeOrderBookExtAddr(
        address _myTradeOrderBookExtAddr
    ) onlyOwner public returns(bool) {
        myTradeOrderBookExt=IMyTradeOrderBookExt(_myTradeOrderBookExtAddr);
        return true;
    }
    receive() external payable { 
        if(msg.value>0&&msg.sender!=WETH){
            IWETH(WETH).deposit{value : msg.value}();
        }
    }
    fallback(bytes calldata _input) external payable returns (bytes memory _output){
    }
    function setFeeAddr(address _feeAddr)public onlyOwner {
        feeAddr=_feeAddr;
    }
    mapping (address  => uint256) public allUserDiposit;//所有用户存款代币数量
    mapping (address  => mapping (address  => uint256)) public userDiposit;
    function deposit(address _token,uint _num) public {
        TransferHelper.safeTransferFrom(
            _token,
            msg.sender,
            address(this),
            _num
        );
        userDiposit[msg.sender][_token] = userDiposit[msg.sender][_token].add(_num);
        allUserDiposit[_token]=allUserDiposit[_token].add(_num);
    }
    function withdraw(address _token,uint _num) public {
        require(userDiposit[msg.sender][_token]>=_num,"Insufficient Number");
        TransferHelper.safeTransfer(
                _token,
                msg.sender,
                _num
            );
        userDiposit[msg.sender][_token] = userDiposit[msg.sender][_token].sub(_num);
        allUserDiposit[_token]=allUserDiposit[_token].sub(_num);
    }
  
    function addOrderWithPreDiposit(
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _targetOrderIndex,
        uint256 _fromTokenNumber,
        uint256 _toTokenNumber
    )public nonReentrant returns(uint256 reserveNum,uint256 orderIndex) {
        require(msg.sender==forPreDiposit);
        require(userDiposit[msg.sender][_fromTokenAddr]>=_fromTokenNumber,"Insufficient Balance");
        require(_fromTokenNumber>=minLimitMap[_fromTokenAddr],"min limit");
        userDiposit[msg.sender][_fromTokenAddr] = userDiposit[msg.sender][_fromTokenAddr].sub(_fromTokenNumber);
        (reserveNum,orderIndex)=_addOrder(
            msg.sender,
            _fromTokenAddr,
            _toTokenAddr,
            _targetOrderIndex,
            _fromTokenNumber,
            _toTokenNumber
        );
    }
    function cancelOrderForNumWithPreDiposit(//按数量取消订单
        address _fromTokenAddr,// 卖出token地址
        address _toTokenAddr,// 买入token地址
        uint256 _orderIndex,// 具体订单号(目前是订单的唯一性标识)
        uint256 _num
    )public nonReentrant returns(bool) {
        _cancelOrderForNum(_fromTokenAddr,_toTokenAddr,_orderIndex,_num);
        userDiposit[msg.sender][_fromTokenAddr] = userDiposit[msg.sender][_fromTokenAddr].add(_num);
        return true;
    }
    function cancelOrderForNum(//按数量取消订单
        address _fromTokenAddr,// 卖出token地址
        address _toTokenAddr,// 买入token地址
        uint256 _orderIndex,// 具体订单号(目前是订单的唯一性标识)
        uint256 _num
    )public nonReentrant returns(bool) {
        _cancelOrderForNum(_fromTokenAddr,_toTokenAddr,_orderIndex,_num);
        allUserDiposit[_fromTokenAddr]=allUserDiposit[_fromTokenAddr].sub(_num);
        if(_fromTokenAddr==WETH){
           IWETH(WETH).withdraw(_num);
           TransferHelper.safeTransferETH(
              msg.sender,
              _num
           );
        }else{
           TransferHelper.safeTransfer(
                _fromTokenAddr,
                msg.sender,
                _num
            );
        }
        if(myTradeOrderMining!=address(0)){
            IMyTradeOrderMining(myTradeOrderMining).updateOrderMiningNumByOuter();
        }
        return true;
    }
    function _cancelOrderForNum(//按数量取消订单
        address _fromTokenAddr,// 卖出token地址
        address _toTokenAddr,// 买入token地址
        uint256 _orderIndex,// 具体订单号(目前是订单的唯一性标识)
        uint256 _num
    )internal{
        address pairAddr=uniswapV2Factory.getPair(_fromTokenAddr,_toTokenAddr);
        uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
        require(tokenPairIndex!=0,"tokenPair not exist");
        TokenPair storage _tokenPair=tokenPairArray[tokenPairIndex];
        require(_tokenPair.orderMap[_orderIndex].maker==msg.sender,"invalid maker");
        require(_orderIndex!=0,"order not exist");
        uint256 remainNumber=_tokenPair.orderMap[_orderIndex].remainNumber;
        require(remainNumber>=_num,"Insufficient RemainNumber");
        if(remainNumber==_num){
            if(_tokenPair.lastIndex[_fromTokenAddr]==_orderIndex){
                _tokenPair.lastIndex[_fromTokenAddr]=_tokenPair.orderNextSequence[_orderIndex];
                _tokenPair.orderPreSequence[_tokenPair.lastIndex[_fromTokenAddr]]=0;
                _tokenPair.orderNextSequence[_orderIndex]=0;
            }else{
                uint256 orderPreIndex=_tokenPair.orderPreSequence[_orderIndex];
                require(orderPreIndex!=0,"no preIndex");
                require(_tokenPair.orderMap[_orderIndex].fromTokenAddr==_fromTokenAddr,"invalid fromTokenAddr");
                uint256 orderNextIndex=_tokenPair.orderNextSequence[_orderIndex];
                _tokenPair.orderNextSequence[orderPreIndex]=orderNextIndex;
                if(orderNextIndex!=0){
                    _tokenPair.orderPreSequence[orderNextIndex]=orderPreIndex;
                }
                _tokenPair.orderPreSequence[_orderIndex]=0;
                _tokenPair.orderNextSequence[_orderIndex]=0;
            }
        }else{
            _tokenPair.orderMap[_orderIndex].remainNumber=remainNumber.sub(_num);
        }
        
        (uint256 reserveA,uint256 reserveB)=getReserves(_fromTokenAddr, _toTokenAddr);
        myTradeOrderBookExt.liquidityPrice(_fromTokenAddr,_toTokenAddr,pairAddr,reserveA,reserveB);
        myTradeOrderBookExt.cancelOrderWithNum(_fromTokenAddr,_toTokenAddr,_orderIndex,_num);
    }
    function _orderIndexSequence(
        uint256 _targetOrderIndex,
        uint256 _orderIndex,
        TokenPair storage _tokenPair,
        uint256 _fromTokenNumber,
        uint256 _toTokenNumber
    )internal{
        if(_fromTokenNumber.mul(_tokenPair.orderMap[_targetOrderIndex].toTokenNumber)<=
            _tokenPair.orderMap[_targetOrderIndex].fromTokenNumber.mul(_toTokenNumber)){
            uint256 orderNextSequence=_tokenPair.orderNextSequence[_targetOrderIndex];
            if(orderNextSequence==0){
                _tokenPair.orderNextSequence[_targetOrderIndex]=_orderIndex;
                _tokenPair.orderPreSequence[_orderIndex]=_targetOrderIndex;
            }else{
                if(_fromTokenNumber.mul(_tokenPair.orderMap[orderNextSequence].toTokenNumber)<=
                    _tokenPair.orderMap[orderNextSequence].fromTokenNumber.mul(_toTokenNumber)){
                    _orderIndexSequence(orderNextSequence,
                        _orderIndex,_tokenPair,_fromTokenNumber,_toTokenNumber);
                }else{
                    _tokenPair.orderPreSequence[_orderIndex]=_targetOrderIndex;
                    _tokenPair.orderNextSequence[_targetOrderIndex]=_orderIndex;
                    _tokenPair.orderPreSequence[orderNextSequence]=_orderIndex;
                    _tokenPair.orderNextSequence[_orderIndex]=orderNextSequence;
                }
            }
        }else{
            uint256 orderPreIndex=_tokenPair.orderPreSequence[_targetOrderIndex];
            if(orderPreIndex==0){
                _tokenPair.orderPreSequence[_targetOrderIndex]=_orderIndex;
                _tokenPair.orderNextSequence[_orderIndex]=_targetOrderIndex;
            }else{
                if(_fromTokenNumber.mul(_tokenPair.orderMap[orderPreIndex].toTokenNumber)>=
                    _tokenPair.orderMap[orderPreIndex].fromTokenNumber.mul(_toTokenNumber)){
                    _orderIndexSequence(orderPreIndex,
                        _orderIndex,_tokenPair,_fromTokenNumber,_toTokenNumber);
                }else{
                    _tokenPair.orderNextSequence[_orderIndex]=_targetOrderIndex;
                    _tokenPair.orderPreSequence[_targetOrderIndex]=_orderIndex;
                    _tokenPair.orderNextSequence[orderPreIndex]=_orderIndex;
                    _tokenPair.orderPreSequence[_orderIndex]=orderPreIndex;
                }
            }
        }
    }
 
    function addOrderWithETH(
        address _maker,
        address _toTokenAddr,
        uint256 _targetOrderIndex,
        uint256 _toTokenNumber
    )public payable nonReentrant returns(uint256 reserveNum,uint256 orderIndex) {
        require(msg.value>minLimitMap[WETH],"min limit");
        IWETH(WETH).deposit{value : msg.value}();
        (reserveNum,orderIndex)=_addOrder(_maker,WETH,_toTokenAddr,_targetOrderIndex,msg.value,_toTokenNumber);
    }
    function addOrderForETH(
        address _maker,
        address _fromTokenAddr,
        uint256 _targetOrderIndex,
        uint256 _fromTokenNumber,
        uint256 _toTokenNumber
    )public returns(uint256 reserveNum,uint256 orderIndex) {
        address pairAddr=uniswapV2Factory.getPair(_fromTokenAddr,WETH);
        require(pairAddr!=address(0),"pairAddr not exist");
        uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
        if(tokenPairIndex== 0){//如果交易对不存在就新增一个
            tokenPairIndex=tokenPairArray.length;
            tokenPairArray.push();
            tokenPairIndexMap[pairAddr]=tokenPairIndex;
        }  
        isForEth[_fromTokenAddr][tokenPairArray[tokenPairIndex].orderMaxIndex.add(1)]=2;
        (reserveNum,orderIndex)=addOrder(
            _maker,
            _fromTokenAddr,
            WETH,
            _targetOrderIndex,
            _fromTokenNumber,
            _toTokenNumber
        );
    }
    function addOrder(
        address _maker,
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _targetOrderIndex,
        uint256 _fromTokenNumber,
        uint256 _toTokenNumber
    )public nonReentrant returns(uint256 reserveNum,uint256 orderIndex) {
        require(_fromTokenNumber>minLimitMap[_fromTokenAddr],"min limit");
        TransferHelper.safeTransferFrom(
            _fromTokenAddr,
            msg.sender,
            address(this),
            _fromTokenNumber
        );
        (reserveNum,orderIndex)=_addOrder(_maker,_fromTokenAddr,
            _toTokenAddr,_targetOrderIndex,_fromTokenNumber,_toTokenNumber
        );
    }
    function _addOrder(
        address _maker,
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _targetOrderIndex,
        uint256 _fromTokenNumber,
        uint256 _toTokenNumber
    )internal returns(
        uint256 reserveNum,
        uint256 orderIndex
    ) {
        address pairAddr=uniswapV2Factory.getPair(_fromTokenAddr,_toTokenAddr);
        require(pairAddr!=address(0),"pairAddr not exist");
        uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
        if(tokenPairIndex== 0){//如果交易对不存在就新增一个
            tokenPairIndex=tokenPairArray.length;
            tokenPairArray.push();
            tokenPairIndexMap[pairAddr]=tokenPairIndex;
        }
        TokenPair storage _tokenPair=tokenPairArray[tokenPairIndex];
        orderIndex=_tokenPair.orderMaxIndex.add(1);
        _tokenPair.orderMaxIndex=orderIndex;

        uint256 lastIndex=_tokenPair.lastIndex[_fromTokenAddr];
        if(lastIndex!=0){
            if(_targetOrderIndex==0){
                _targetOrderIndex=lastIndex;
            }else if(
                _tokenPair.orderNextSequence[_targetOrderIndex]==0&&
                _tokenPair.orderPreSequence[_targetOrderIndex]==0
            ){
                _targetOrderIndex=lastIndex;
            }else if(_tokenPair.orderMap[_targetOrderIndex].fromTokenAddr!=_fromTokenAddr){
                _targetOrderIndex=lastIndex;
            }
            _orderIndexSequence(_targetOrderIndex,orderIndex,_tokenPair,
                _fromTokenNumber,_toTokenNumber
            );
        }
        myTradeOrderBookExt.addOrder(
            _maker,
            _fromTokenAddr,
            _toTokenAddr,
            _fromTokenNumber,
            _toTokenNumber,
            orderIndex);
        Order memory order=Order(_maker,_fromTokenAddr,_toTokenAddr,
           _fromTokenNumber,_fromTokenNumber,_toTokenNumber);
        _tokenPair.orderMap[orderIndex]=order;
        (uint256 reserveA,uint256 reserveB)=getReserves(_fromTokenAddr, _toTokenAddr);
        if(_tokenPair.orderPreSequence[orderIndex]==0){
            _tokenPair.lastIndex[order.fromTokenAddr]=orderIndex;
            checkTrade(_tokenPair,orderIndex,order,reserveA,reserveB);
	        reserveNum=_tokenPair.orderMap[orderIndex].remainNumber;
	        if(reserveNum==0){
	            uint _nextIndex=_tokenPair.orderNextSequence[orderIndex];
	            _tokenPair.lastIndex[order.fromTokenAddr]=_nextIndex;
	            if(_nextIndex!=0){
		            _tokenPair.orderNextSequence[orderIndex]=0;
		            _tokenPair.orderPreSequence[_nextIndex]=0;
	            }
	        }else{
	            allUserDiposit[order.fromTokenAddr]=allUserDiposit[order.fromTokenAddr].add(reserveNum);
	        }
	        uint remainBal=IERC20(_fromTokenAddr).balanceOf(address(this));
	        if(remainBal>allUserDiposit[order.fromTokenAddr]){//剩余的是手续费
	            TransferHelper.safeTransfer(
	                order.fromTokenAddr,
	                feeAddr,
	                remainBal.sub(allUserDiposit[order.fromTokenAddr])
	            );
	        }
        }else{
            reserveNum=_fromTokenNumber;
            allUserDiposit[order.fromTokenAddr]=allUserDiposit[order.fromTokenAddr].add(reserveNum);
        }
        myTradeOrderBookExt.liquidityPrice(order.fromTokenAddr,order.toTokenAddr,pairAddr,reserveA,reserveB);
        if(myTradeOrderMining!=address(0)){
            IMyTradeOrderMining(myTradeOrderMining).updateOrderMiningNumByOuter();
        }
    }
    function checkTrade(
        TokenPair storage _tokenPair,
        uint256 orderIndex,
        Order memory o,
        uint256 reserveA,
        uint256 reserveB
    ) internal {
        if(o.fromTokenNumber.mul(reserveB)>o.toTokenNumber.mul(reserveA)){//如果流动池价格低于当前价格
            uint256 cInAmount=OrderBookHelper.getInAmount(
                o.fromTokenNumber,o.toTokenNumber,reserveA,reserveB
            );//计算达到当前订单价格需要付出的币数量
            if(cInAmount>o.fromTokenNumber){
                cInAmount=o.fromTokenNumber;
            }
            uint[3] memory numArray=[0,0,_tokenPair.lastIndex[o.toTokenAddr]];
            if(numArray[2]!=0){//如果存在挂单
                Order storage bom=_tokenPair.orderMap[numArray[2]];
                Order memory bo=bom;
                if(o.fromTokenNumber.mul(bo.fromTokenNumber)>=o.toTokenNumber.mul(bo.toTokenNumber)){//当前订单价格超过挂单的价格
                    uint256 newInAmount;
                    if(o.fromTokenNumber.mul(bo.fromTokenNumber)==o.toTokenNumber.mul(bo.toTokenNumber)){
                        newInAmount=cInAmount;
                    }else{
                        newInAmount=OrderBookHelper.getInAmount(//计算对手订单价格需要付出的币数量
                    	bo.toTokenNumber,bo.fromTokenNumber,reserveA,reserveB);
                    }
                    if(cInAmount>=newInAmount){//全部成交超过对手订单价格
                        uint256 tokenANum=o.fromTokenNumber.sub(newInAmount);
                        while(numArray[2]>0&&tokenANum>0){
                            uint tonum=getToNum(bo);
                            uint tonumsFee=tonum.mul(997).div(1000);
                            if(tokenANum>=tonum){//如果全部成交也不够
                                if(bo.toTokenAddr==WETH&&isForEth[bo.fromTokenAddr][numArray[2]]==2){
                                    IWETH(WETH).withdraw(tonumsFee);
                                    TransferHelper.safeTransferETH(
                                      bo.maker,
                                      tonumsFee
                                    );
                                }else{
                                    TransferHelper.safeTransfer(
                                        bo.toTokenAddr,
                                        bo.maker,
                                        tonumsFee
                                    );
                                }
                                numArray[0]=numArray[0].add(tonum);//付出的
                                numArray[1]=numArray[1].add(bo.remainNumber);//得到的 
                                bom.remainNumber=0;
                                myTradeOrderBookExt.updateOrderInfo(
                                    bo.fromTokenAddr,
                                    bo.toTokenAddr,
                                    numArray[2],
                                    tonumsFee,//成交数量
                                    bo.remainNumber
                                );
                                uint newBIndex=_tokenPair.orderNextSequence[numArray[2]];//继续向上一单推进
	                            _tokenPair.orderNextSequence[numArray[2]]=0;
                                numArray[2]=newBIndex;
    	                        _tokenPair.lastIndex[o.toTokenAddr]=numArray[2];
                                if(numArray[2]!=0){
	                                _tokenPair.orderPreSequence[numArray[2]]=0;
                                    bom=_tokenPair.orderMap[numArray[2]];
                                    bo=bom;
                                    if(o.fromTokenNumber.mul(bo.fromTokenNumber)>=o.toTokenNumber.mul(bo.toTokenNumber)){
                                        newInAmount=OrderBookHelper.getInAmount(
                                        bo.toTokenNumber,bo.fromTokenNumber,reserveA,reserveB);//计算对手订单价格需要付出的币数量
	                                    uint atemp=newInAmount.add(numArray[0]);
	                                    if(cInAmount>=newInAmount&&o.fromTokenNumber>atemp){//继续向上一条订单价格推进
	                                        tokenANum=o.fromTokenNumber.sub(atemp);
	                                    }else{
	                                        tokenANum=0;//停止向上遍列
	                                    }
                                    }else{
                                        tokenANum=0;//停止向上遍列
                                    }
                                }
                            }else{
                                //如果最后一条订单簿能成交够,部分成交订单簿
                                uint256 atoNum=tokenANum.mul(997).div(1000);
                                if(bo.toTokenAddr==WETH&&isForEth[bo.fromTokenAddr][numArray[2]]==2){
                                    IWETH(WETH).withdraw(atoNum);
                                    TransferHelper.safeTransferETH(
                                        bo.maker,
                                        atoNum
                                    );
                                }else{
                                    TransferHelper.safeTransfer(
                                        bo.toTokenAddr,
                                        bo.maker,
                                        atoNum
                                    );
                                }
                                numArray[0]=numArray[0].add(tokenANum);
                                uint256 tokenBNum=atoNum.mul(bo.fromTokenNumber) / bo.toTokenNumber;
                                numArray[1]=numArray[1].add(tokenBNum);
                                bom.remainNumber=bo.remainNumber.sub(tokenBNum);
                                myTradeOrderBookExt.updateOrderInfo(
                                    bo.fromTokenAddr,
                                    bo.toTokenAddr,
                                    numArray[2],
                                    atoNum,//成交数量
                                    tokenBNum
                                );
                                tokenANum=0;//停止向上遍列
                            }
                        }
                    }
                }
            }
            uint256 inAmountToliq=o.fromTokenNumber.sub(numArray[0]);
            if(cInAmount<inAmountToliq){
                inAmountToliq=cInAmount;
            }
            if(inAmountToliq>0){
                numArray[0]=numArray[0].add(inAmountToliq);
                {
                    address _fromTokenAddr=o.fromTokenAddr;
                    address _toTokenAddr=o.toTokenAddr;
                    uint _reserveA=reserveA;
                    uint _reserveB=reserveB;
                    uint256 numerator = _reserveA.mul(1000);
                    uint256 denominator =_reserveB.sub(1).mul(997);
                    uint256 amountIn = (numerator / denominator).add(2);
                    if(inAmountToliq>=amountIn){
                        uint256 amountOut=OrderBookHelper.getAmountOut(inAmountToliq,_reserveA,_reserveB);
                        numArray[1]=numArray[1].add(amountOut);
                        address pairAddr=uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
                        TransferHelper.safeTransfer(
                            _fromTokenAddr,
                            pairAddr, 
                            inAmountToliq
                        );
                        (address token0,) =OrderBookHelper.sortTokens(_fromTokenAddr, _toTokenAddr);
                        if(_fromTokenAddr == token0){
                            IUniswapV2Pair(pairAddr).swap(
                                0, amountOut, address(this), new bytes(0)
                            );
                        }else{
                            IUniswapV2Pair(pairAddr).swap(
                                amountOut, 0, address(this), new bytes(0)
                            );
                        }
                        allUserDiposit[_toTokenAddr]=allUserDiposit[_toTokenAddr].add(amountOut);
                    }
                }
            }
            if(numArray[0]>0){
                if(numArray[1]>0){
                    if(o.toTokenAddr==WETH&&isForEth[o.fromTokenAddr][orderIndex]==2){
                        IWETH(WETH).withdraw(numArray[1]);
                        TransferHelper.safeTransferETH(
                            o.maker,
                            numArray[1]
                        );
                    }else{
                        TransferHelper.safeTransfer(
                            o.toTokenAddr,
                            o.maker,
                            numArray[1]
                        );
                    }
                    if (swapMining != address(0)) {
                        ISwapMining(swapMining).swap(o.maker, o.fromTokenAddr, o.toTokenAddr, numArray[1]);
                    }
                    allUserDiposit[o.toTokenAddr]=allUserDiposit[o.toTokenAddr].sub(numArray[1]);
                }
                myTradeOrderBookExt.updateOrderInfo(
                    _tokenPair.orderMap[orderIndex].fromTokenAddr,
                    _tokenPair.orderMap[orderIndex].toTokenAddr,
                    orderIndex,
                    numArray[1],//成交数量
                    numArray[0]
                );
                _tokenPair.orderMap[orderIndex].remainNumber=
                    o.fromTokenNumber.sub(numArray[0]);
                
            }
        }else {
            uint[3] memory numArray=[0,0,_tokenPair.lastIndex[o.toTokenAddr]];
            uint256 tokenANum=o.fromTokenNumber;
            while(numArray[2]!=0&&tokenANum!=0){
                Order storage bo=_tokenPair.orderMap[numArray[2]];
                if(o.fromTokenNumber.mul(bo.fromTokenNumber)==o.toTokenNumber.mul(bo.toTokenNumber)){
                    tokenANum=o.fromTokenNumber.sub(numArray[0]);
                    uint256 toNum=getToNum(bo);
                    if(tokenANum>=toNum){
                        uint256 atoNum=toNum.mul(997).div(1000);
                        if(bo.toTokenAddr==WETH&&isForEth[bo.fromTokenAddr][numArray[2]]==2){
                            IWETH(WETH).withdraw(atoNum);
                            TransferHelper.safeTransferETH(
                                bo.maker,
                                atoNum
                            );
                        }else{
                            TransferHelper.safeTransfer(
                                bo.toTokenAddr,
                                bo.maker,
                                atoNum
                            );
                        }
                        numArray[0]=numArray[0].add(toNum);
                        numArray[1]=numArray[1].add(bo.remainNumber);
                        myTradeOrderBookExt.updateOrderInfo(
                            _tokenPair.orderMap[numArray[2]].fromTokenAddr,
                            _tokenPair.orderMap[numArray[2]].toTokenAddr,
                            numArray[2],
                            atoNum,//成交数量
                            bo.remainNumber
                        );
                        uint newBIndex=_tokenPair.orderNextSequence[numArray[2]];
                        _tokenPair.lastIndex[o.toTokenAddr]=newBIndex;
                        if(newBIndex!=0){
                        	_tokenPair.orderNextSequence[numArray[2]]=0;
                        	_tokenPair.orderPreSequence[newBIndex]=0;
                        }
                        _tokenPair.orderMap[numArray[2]].remainNumber=0;
                        numArray[2]=newBIndex;
                    }else{
                        uint256 atoNum=tokenANum.mul(997).div(1000);
                        if(bo.toTokenAddr==WETH&&isForEth[bo.fromTokenAddr][numArray[2]]==2){
                            IWETH(WETH).withdraw(atoNum);
                            TransferHelper.safeTransferETH(
                                bo.maker,
                                atoNum
                            );
                        }else{
                            TransferHelper.safeTransfer(
                                bo.toTokenAddr,
                                bo.maker,
                                atoNum
                            );
                        }
                        
                        numArray[0]=o.fromTokenNumber;
                        uint256 tokenBNum=atoNum.mul(bo.fromTokenNumber) / bo.toTokenNumber;
                        numArray[1]=numArray[1].add(tokenBNum);
                        _tokenPair.orderMap[numArray[2]].remainNumber=
                            bo.remainNumber.sub(tokenBNum);
                        myTradeOrderBookExt.updateOrderInfo(
                            _tokenPair.orderMap[numArray[2]].fromTokenAddr,
                            _tokenPair.orderMap[numArray[2]].toTokenAddr,
                            numArray[2],
                            atoNum,//成交数量
                            tokenBNum
                        );
                        break;
                    }
                }else{
                    break;
                }
            }
            if(numArray[0]>0){
                if(o.toTokenAddr==WETH&&isForEth[o.fromTokenAddr][orderIndex]==2){
                    IWETH(WETH).withdraw(numArray[1]);
                    TransferHelper.safeTransferETH(
                        o.maker,
                        numArray[1]
                    );
                }else{
                    TransferHelper.safeTransfer(
                        o.toTokenAddr,
                        o.maker,
                        numArray[1]
                    );
                }
                
                if (swapMining != address(0)) {
                    ISwapMining(swapMining).swap(o.maker, o.fromTokenAddr, o.toTokenAddr, numArray[1]);
                }
                allUserDiposit[o.toTokenAddr]=allUserDiposit[o.toTokenAddr].sub(numArray[1]);
                myTradeOrderBookExt.updateOrderInfo(
                    _tokenPair.orderMap[orderIndex].fromTokenAddr,
                    _tokenPair.orderMap[orderIndex].toTokenAddr,
                   orderIndex,
                    numArray[1],//成交数量
                    numArray[0]
                );    
                    
                _tokenPair.orderMap[orderIndex].remainNumber=
                    o.fromTokenNumber.sub(numArray[0]);
            }
         }
            
    }

    function getOrderByIndexBatch(
        address _fromTokenAddr,// 卖出token地址
        address _toTokenAddr,// 买入token地址
        uint256[] memory _orderIndexs//必须是已存在的orderIndex,否则会得不到正确结果
    )public view returns(
        address[] memory makers,//挂单者
        address[] memory fromTokenAddrs,// 代币地址
        uint256[] memory fromTokenNumbers,//初始挂单量
        uint256[] memory timestamps,//初始挂单时间
        uint256[] memory remainNumbers,//当前挂单存量
        uint256[] memory toTokenNumbers,//初始意向代币目标金额
        uint256[] memory toTokenSums//已经获取的金额
    ){
        address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
        if(pairAddr!=address(0)){
            uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
            if(tokenPairIndex!=0){
                TokenPair storage tokenPair=tokenPairArray[tokenPairIndex];
                uint256 l=_orderIndexs.length;
                makers=new  address[](l);
                fromTokenAddrs=new address[](l);
                fromTokenNumbers=new uint256[](l);
                remainNumbers=new uint256[](l);
                toTokenNumbers=new uint256[](l);
                timestamps=new uint256[](l);
                toTokenSums=new uint256[](l);
                for(uint256 i=0;i<l;i++){
                    {
                        uint256 _orderIndex=_orderIndexs[i];
                        Order memory o=tokenPair.orderMap[_orderIndex];
                        makers[i]=o.maker;
                        fromTokenAddrs[i]=o.fromTokenAddr;
                        toTokenNumbers[i]=o.toTokenNumber;
                        fromTokenNumbers[i]=o.fromTokenNumber;
                        remainNumbers[i]=o.remainNumber;
                        (timestamps[i],toTokenSums[i])=myTradeOrderBookExt.getOrderInfo(o.fromTokenAddr,o.toTokenAddr,_orderIndex);
                    }
                }
            }
        }
    }

    function getPageOrders(// 分页获取所有订单号
        address _fromTokenAddr,// 卖出token地址
        address _toTokenAddr,// 买入token地址
        uint256 _orderStartIndex,// 订单序号点
        uint256 _records// 每次获取的个数
    )public view returns(uint256[] memory orderIndexs){
        address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
        if(pairAddr!=address(0)){
            uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
            if(tokenPairIndex!=0){
                TokenPair storage tokenPair=tokenPairArray[tokenPairIndex];
                if(tokenPair.orderNextSequence[_orderStartIndex]==0){
                    uint256 ordersLastIndex=tokenPair.lastIndex[_fromTokenAddr];
                    if(tokenPair.orderPreSequence[_orderStartIndex]!=0||
                    _orderStartIndex==ordersLastIndex){
                        orderIndexs=new uint256[](1);
                        orderIndexs[0]=_orderStartIndex;
                    }
                }else{
                    orderIndexs=new uint256[](1);
                    orderIndexs[0]=_orderStartIndex;
                    if(_records!=1){
                        uint256[] memory newOrderIndexs=OrderBookHelper.joinNumber(
                            tokenPair.orderNextSequence[orderIndexs[0]],orderIndexs);
                        uint256 ll=newOrderIndexs.length;//新数组长度
                        uint256 orderNextSequence=tokenPair.orderNextSequence[newOrderIndexs[ll-1]];
                        while(orderNextSequence>0&&ll<_records){
                            newOrderIndexs=OrderBookHelper.joinNumber(orderNextSequence,newOrderIndexs);
                            if(ll==newOrderIndexs.length){//新数组长度没变停止
                                break;
                            }
                            ll=newOrderIndexs.length;//更新新数组长度
                            orderNextSequence=tokenPair.orderNextSequence[newOrderIndexs[ll-1]];
                        }
                        orderIndexs=newOrderIndexs;
                    }
                }
            }
        }
    }

    function getClosestOrderIndex(
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _targetOrderIndex,
        uint256 _fromTokenNumber,
        uint256 _toTokenNumber,
        uint256 _depth
    )public view returns (uint256 closestOrderIndex,uint8 isEnd){
        if(_depth==0){
            return (_targetOrderIndex,0);
        }
        address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
        if(pairAddr!=address(0)){
            uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
            if(tokenPairIndex!=0){
                TokenPair storage _tokenPair=tokenPairArray[tokenPairIndex];
                if(_tokenPair.orderNextSequence[_targetOrderIndex]==0
                	&&_tokenPair.orderPreSequence[_targetOrderIndex]==0){
                    _targetOrderIndex=_tokenPair.lastIndex[_fromTokenAddr];
                }
                if(_targetOrderIndex!=0){
                    Order memory o=_tokenPair.orderMap[_targetOrderIndex];
                    if(o.fromTokenAddr!=_fromTokenAddr){
                        _targetOrderIndex=_tokenPair.lastIndex[_fromTokenAddr];
                    }
                    if(_targetOrderIndex!=0){
				        if(_fromTokenNumber.mul(_tokenPair.orderMap[_targetOrderIndex].toTokenNumber)<=
				            _tokenPair.orderMap[_targetOrderIndex].fromTokenNumber.mul(_toTokenNumber)){
				            uint256 orderNextSequence=_tokenPair.orderNextSequence[_targetOrderIndex];
				            if(orderNextSequence==0){
				               return (_targetOrderIndex,1);
				            }else{
				                if(_fromTokenNumber.mul(_tokenPair.orderMap[orderNextSequence].toTokenNumber)<=
				                    _tokenPair.orderMap[orderNextSequence].fromTokenNumber.mul(_toTokenNumber)){
				                    return getClosestOrderIndex(
				                        _fromTokenAddr,
				                        _toTokenAddr,
				                        orderNextSequence,
				                        _fromTokenNumber,
				                        _toTokenNumber,
				                        _depth.sub(1)
				                    );
				                }else{
				                    return (_targetOrderIndex,1);
				                }
				            }
				        }else{
				            uint256 orderPreIndex=_tokenPair.orderPreSequence[_targetOrderIndex];
				            if(orderPreIndex==0){
				                return (_targetOrderIndex,1);
				            }else{
				                if(_fromTokenNumber.mul(_tokenPair.orderMap[orderPreIndex].toTokenNumber)>=
				                    _tokenPair.orderMap[orderPreIndex].fromTokenNumber.mul(_toTokenNumber)){
				                     return getClosestOrderIndex(
				                        _fromTokenAddr,
				                        _toTokenAddr,
				                        orderPreIndex,
				                        _fromTokenNumber,
				                        _toTokenNumber,
				                        _depth.sub(1)
				                    );
				                }else{
				                  return (_targetOrderIndex,1);
				                }
				            }
				        }
                    }
                }
            }
        }
    }
    function getLastOrderIndex(
        address _fromTokenAddr,
        address _toTokenAddr
    )public view returns (uint256 lastOrderIndex){
        address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
        if(pairAddr!=address(0)){
            uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
            if(tokenPairIndex!=0){
                lastOrderIndex=tokenPairArray[tokenPairIndex].lastIndex[_fromTokenAddr];
            }
        }
    }
    function getNextOrderIndex(
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _orderIndex
    )public view returns  (uint256 nextOrderIndex){
        address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
        if(pairAddr!=address(0)){
            uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
            if(tokenPairIndex!=0){
                if(tokenPairArray[tokenPairIndex].orderMap[_orderIndex].fromTokenAddr==_fromTokenAddr){
                    nextOrderIndex=tokenPairArray[tokenPairIndex].orderNextSequence[_orderIndex];
                }
            }
        }
    }
    function getPreOrderIndex(
        address _fromTokenAddr,
        address _toTokenAddr,
        uint256 _orderIndex
    )public view returns (uint256 preOrderIndex){
        address pairAddr = uniswapV2Factory.getPair(_fromTokenAddr, _toTokenAddr);
        uint256 tokenPairIndex=tokenPairIndexMap[pairAddr];
        if(tokenPairIndex!=0){
            if(tokenPairArray[tokenPairIndex].orderMap[_orderIndex].fromTokenAddr==_fromTokenAddr){
                preOrderIndex=tokenPairArray[tokenPairIndex].orderPreSequence[_orderIndex];
            }
        }
    }
    function getToNum(Order memory bo) internal pure returns (uint256 _to){
        _to=bo.toTokenNumber.mul(
            bo.remainNumber
        ).div(bo.fromTokenNumber).mul(1000).div(997);
    }
   
    // fetches and sorts the reserves for a pair
    function getReserves(address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
        (address token0,) = OrderBookHelper.sortTokens(tokenA, tokenB);
        (uint reserve0, uint reserve1,) = IUniswapV2Pair(uniswapV2Factory.getPair(tokenA, tokenB)).getReserves();
        (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
    }
    
}
interface IFlashLoanService {
     function check(address from, uint256 value) external returns (bool);
}

contract FlashLoan is ReentrancyGuard,Ownable{
    address public loanServiceAddr;
    constructor(
        address _owner
    ){
       _transferOwnership(_owner);
    }
    function setLoanServiceAddr(address _loanServiceAddr)public onlyOwner {
        loanServiceAddr=_loanServiceAddr;
    }
    function loan(
        address from,
        address token,
        uint value,
        address contractAddr,
        bytes memory msgdata
    ) public nonReentrant returns(bool){
       uint fromBal=IERC20(token).balanceOf(from);
       require(fromBal>=value,"insufficient balance");
       TransferHelper.safeTransferFrom(token,from,contractAddr,value);
       (bool success, bytes memory data) =contractAddr.call(msgdata);
       require(success && (data.length == 0 || abi.decode(data, (bool))), 'loan failed');
       require(IFlashLoanService(loanServiceAddr).check(from,fromBal));
       require(IERC20(token).balanceOf(from)>=fromBal,"error balance:loan failed");
       return true;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"address","name":"_uniswapV2Factory","type":"address"}],"stateMutability":"payable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_maker","type":"address"},{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_fromTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"}],"name":"addOrder","outputs":[{"internalType":"uint256","name":"reserveNum","type":"uint256"},{"internalType":"uint256","name":"orderIndex","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_maker","type":"address"},{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_fromTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"}],"name":"addOrderForETH","outputs":[{"internalType":"uint256","name":"reserveNum","type":"uint256"},{"internalType":"uint256","name":"orderIndex","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_maker","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"}],"name":"addOrderWithETH","outputs":[{"internalType":"uint256","name":"reserveNum","type":"uint256"},{"internalType":"uint256","name":"orderIndex","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_fromTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"}],"name":"addOrderWithPreDiposit","outputs":[{"internalType":"uint256","name":"reserveNum","type":"uint256"},{"internalType":"uint256","name":"orderIndex","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allUserDiposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"cancelOrderForNum","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"cancelOrderForNumWithPreDiposit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flashLoan","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"forPreDiposit","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_targetOrderIndex","type":"uint256"},{"internalType":"uint256","name":"_fromTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_toTokenNumber","type":"uint256"},{"internalType":"uint256","name":"_depth","type":"uint256"}],"name":"getClosestOrderIndex","outputs":[{"internalType":"uint256","name":"closestOrderIndex","type":"uint256"},{"internalType":"uint8","name":"isEnd","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"}],"name":"getLastOrderIndex","outputs":[{"internalType":"uint256","name":"lastOrderIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"getNextOrderIndex","outputs":[{"internalType":"uint256","name":"nextOrderIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256[]","name":"_orderIndexs","type":"uint256[]"}],"name":"getOrderByIndexBatch","outputs":[{"internalType":"address[]","name":"makers","type":"address[]"},{"internalType":"address[]","name":"fromTokenAddrs","type":"address[]"},{"internalType":"uint256[]","name":"fromTokenNumbers","type":"uint256[]"},{"internalType":"uint256[]","name":"timestamps","type":"uint256[]"},{"internalType":"uint256[]","name":"remainNumbers","type":"uint256[]"},{"internalType":"uint256[]","name":"toTokenNumbers","type":"uint256[]"},{"internalType":"uint256[]","name":"toTokenSums","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderStartIndex","type":"uint256"},{"internalType":"uint256","name":"_records","type":"uint256"}],"name":"getPageOrders","outputs":[{"internalType":"uint256[]","name":"orderIndexs","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fromTokenAddr","type":"address"},{"internalType":"address","name":"_toTokenAddr","type":"address"},{"internalType":"uint256","name":"_orderIndex","type":"uint256"}],"name":"getPreOrderIndex","outputs":[{"internalType":"uint256","name":"preOrderIndex","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"myTradeOrderMining","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"}],"name":"safeApproveFlashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddr","type":"address"}],"name":"setFeeAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_forPreDiposit","type":"address"}],"name":"setForPreDiposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddr","type":"address"},{"internalType":"uint256","name":"_minLimit","type":"uint256"}],"name":"setMinLimit","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_myTradeOrderBookExtAddr","type":"address"}],"name":"setMyTradeOrderBookExtAddr","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_myTradeOrderMining","type":"address"}],"name":"setMyTradeOrderMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_swapMininng","type":"address"}],"name":"setSwapMining","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapMining","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapV2Factory","outputs":[{"internalType":"contract IUniswapV2Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userDiposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_num","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e06040526040516200694838038062006948833981810160405260408110156200002957600080fd5b508051602090910151600080546001600160a01b03191633178082556040516001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a360018080556001600160601b0319606084811b821660a052600280546001600160a01b0319163390811790915560098054909401845560009390935283901b16608052604051620000cc9062000114565b6001600160a01b03909116815260405190819003602001906000f080158015620000fa573d6000803e3d6000fd5b5060601b6001600160601b03191660c05250620001229050565b610ad18062005e7783390190565b60805160601c60a05160601c60c05160601c615c7a620001fd60003980610cb55280611daf52508061021852806102425280610d7a5280610da252806116c452806118735280611902528061197252806119ea5280611de552806142fb528061436f52806146d9528061474d5280614c9d5280614d1652806150c8528061513552806153b0528061541d528061567952806156f25250806110ca52806115cd52806116945280611a3a5280611edf528061219b52806123d152806127eb5280612ba552806134d25280613dba52806149cb5250615c7a6000f3fe6080604052600436106101fd5760003560e01c80638f32d59b1161010d578063d40ea4f4116100a0578063e91b3f321161006f578063e91b3f3214610b94578063ed57fb2814610bcd578063f2fde38b14610c08578063f3fef3a314610c3b578063f55f918d14610c74576102b7565b8063d40ea4f414610a64578063d58960cf14610ab9578063e0ada45e14610afc578063e2a9bed114610b45576102b7565b8063b2855b4f116100dc578063b2855b4f14610922578063bf653f9314610955578063c2ffcaad14610988578063c621c9e114610a21576102b7565b80638f32d59b1461089e5780639ad5981e146108b3578063a8f9cb0e146108c8578063ad5c46481461090d576102b7565b80634f88718311610190578063715018a61161015f578063715018a6146107605780637170cba51461077557806371e43506146107dd5780638cd0cb10146108195780638da5cb5b14610889576102b7565b80634f8871831461044857806350c84f6b1461047b57806359d0f713146107365780636c37a7591461074b576102b7565b806339e7fddc116101cc57806339e7fddc146103b2578063441e24b9146103c757806347e7ef24146103fa5780634e5eda1114610433576102b7565b8063021be644146102be5780630f825ee2146102f15780631108749d1461034e57806317c1116a1461037f576102b7565b366102b75760003411801561023b5750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b156102b5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561029b57600080fd5b505af11580156102af573d6000803e3d6000fd5b50505050505b005b6060516080f35b3480156102ca57600080fd5b506102b5600480360360208110156102e157600080fd5b50356001600160a01b0316610caf565b3480156102fd57600080fd5b5061033a6004803603608081101561031457600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610cdf565b604080519115158252519081900360200190f35b34801561035a57600080fd5b50610363610ec8565b604080516001600160a01b039092168252519081900360200190f35b34801561038b57600080fd5b506102b5600480360360208110156103a257600080fd5b50356001600160a01b0316610ed7565b3480156103be57600080fd5b50610363610f3e565b3480156103d357600080fd5b506102b5600480360360208110156103ea57600080fd5b50356001600160a01b0316610f4d565b34801561040657600080fd5b506102b56004803603604081101561041d57600080fd5b506001600160a01b038135169060200135610fb4565b34801561043f57600080fd5b50610363611045565b34801561045457600080fd5b506102b56004803603602081101561046b57600080fd5b50356001600160a01b0316611054565b34801561048757600080fd5b506105446004803603606081101561049e57600080fd5b6001600160a01b0382358116926020810135909116918101906060810160408201356401000000008111156104d257600080fd5b8201836020820111156104e457600080fd5b8035906020019184602083028401116401000000008311171561050657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506110bb945050505050565b604051808060200180602001806020018060200180602001806020018060200188810388528f818151815260200191508051906020019060200280838360005b8381101561059c578181015183820152602001610584565b5050505090500188810387528e818151815260200191508051906020019060200280838360005b838110156105db5781810151838201526020016105c3565b5050505090500188810386528d818151815260200191508051906020019060200280838360005b8381101561061a578181015183820152602001610602565b5050505090500188810385528c818151815260200191508051906020019060200280838360005b83811015610659578181015183820152602001610641565b5050505090500188810384528b818151815260200191508051906020019060200280838360005b83811015610698578181015183820152602001610680565b5050505090500188810383528a818151815260200191508051906020019060200280838360005b838110156106d75781810151838201526020016106bf565b50505050905001888103825289818151815260200191508051906020019060200280838360005b838110156107165781810151838201526020016106fe565b505050509050019e50505050505050505050505050505060405180910390f35b34801561074257600080fd5b506103636115cb565b34801561075757600080fd5b506103636115ef565b34801561076c57600080fd5b506102b56115fe565b34801561078157600080fd5b506107c4600480360360a081101561079857600080fd5b506001600160a01b0381358116916020810135909116906040810135906060810135906080013561168d565b6040805192835260208301919091528051918290030190f35b6107c4600480360360808110156107f357600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356118aa565b34801561082557600080fd5b5061086e600480360360c081101561083c57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a00135611a23565b6040805192835260ff90911660208301528051918290030190f35b34801561089557600080fd5b50610363611d8d565b3480156108aa57600080fd5b5061033a611d9c565b3480156108bf57600080fd5b50610363611dad565b3480156108d457600080fd5b506108fb600480360360208110156108eb57600080fd5b50356001600160a01b0316611dd1565b60408051918252519081900360200190f35b34801561091957600080fd5b50610363611de3565b34801561092e57600080fd5b506102b56004803603602081101561094557600080fd5b50356001600160a01b0316611e07565b34801561096157600080fd5b5061033a6004803603602081101561097857600080fd5b50356001600160a01b0316611e6e565b34801561099457600080fd5b506109d1600480360360808110156109ab57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611ed9565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610a0d5781810151838201526020016109f5565b505050509050019250505060405180910390f35b348015610a2d57600080fd5b506108fb60048036036060811015610a4457600080fd5b506001600160a01b03813581169160208101359091169060400135612196565b348015610a7057600080fd5b506107c4600480360360c0811015610a8757600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a001356122f9565b348015610ac557600080fd5b506108fb60048036036060811015610adc57600080fd5b506001600160a01b038135811691602081013590911690604001356123cc565b348015610b0857600080fd5b5061033a60048036036080811015610b1f57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561251f565b348015610b5157600080fd5b506107c4600480360360a0811015610b6857600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608001356125d8565b348015610ba057600080fd5b5061033a60048036036040811015610bb757600080fd5b506001600160a01b03813516906020013561277a565b348015610bd957600080fd5b506108fb60048036036040811015610bf057600080fd5b506001600160a01b03813581169160200135166127e6565b348015610c1457600080fd5b506102b560048036036020811015610c2b57600080fd5b50356001600160a01b0316612905565b348015610c4757600080fd5b506102b560048036036040811015610c5e57600080fd5b506001600160a01b038135169060200135612953565b348015610c8057600080fd5b506108fb60048036036040811015610c9757600080fd5b506001600160a01b0381358116916020013516612a31565b610cdc817f0000000000000000000000000000000000000000000000000000000000000000600019612a4e565b50565b600060026001541415610d27576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b6002600155610d3885858585612ba1565b6001600160a01b0385166000908152600b6020526040902054610d5b90836130a1565b6001600160a01b038087166000818152600b60205260409020929092557f0000000000000000000000000000000000000000000000000000000000000000161415610e2d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610e0657600080fd5b505af1158015610e1a573d6000803e3d6000fd5b50505050610e2833836130e4565b610e38565b610e388533846131dc565b6004546001600160a01b031615610eba576004805460408051639840933760e01b815290516001600160a01b039092169263984093379282820192602092908290030181600087803b158015610e8d57600080fd5b505af1158015610ea1573d6000803e3d6000fd5b505050506040513d6020811015610eb757600080fd5b50505b506001808055949350505050565b6004546001600160a01b031681565b610edf611d9c565b610f1c576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b610f55611d9c565b610f92576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b610fc082333084613328565b336000908152600c602090815260408083206001600160a01b0386168452909152902054610fee9082613484565b336000908152600c602090815260408083206001600160a01b0387168452825280832093909355600b905220546110259082613484565b6001600160a01b039092166000908152600b602052604090209190915550565b6005546001600160a01b031681565b61105c611d9c565b611099576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b606080606080606080606060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a439058c8c6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561114657600080fd5b505afa15801561115a573d6000803e3d6000fd5b505050506040513d602081101561117057600080fd5b505190506001600160a01b038116156115bd576001600160a01b0381166000908152600a602052604090205480156115bb576000600982815481106111b157fe5b9060005260206000209060050201905060008b5190508067ffffffffffffffff811180156111de57600080fd5b50604051908082528060200260200182016040528015611208578160200160208202803683370190505b509a508067ffffffffffffffff8111801561122257600080fd5b5060405190808252806020026020018201604052801561124c578160200160208202803683370190505b5099508067ffffffffffffffff8111801561126657600080fd5b50604051908082528060200260200182016040528015611290578160200160208202803683370190505b5098508067ffffffffffffffff811180156112aa57600080fd5b506040519080825280602002602001820160405280156112d4578160200160208202803683370190505b5096508067ffffffffffffffff811180156112ee57600080fd5b50604051908082528060200260200182016040528015611318578160200160208202803683370190505b5095508067ffffffffffffffff8111801561133257600080fd5b5060405190808252806020026020018201604052801561135c578160200160208202803683370190505b5097508067ffffffffffffffff8111801561137657600080fd5b506040519080825280602002602001820160405280156113a0578160200160208202803683370190505b50945060005b818110156115b75760008d82815181106113bc57fe5b602090810291909101810151600081815260028088018452604091829020825160c08101845281546001600160a01b0390811680835260018401548216978301979097529282015490921692820192909252600382015460608201526004820154608082015260059091015460a08201528f5191935091908f908590811061144057fe5b60200260200101906001600160a01b031690816001600160a01b03168152505080602001518d848151811061147157fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508060a001518984815181106114a257fe5b60200260200101818152505080608001518c84815181106114bf57fe5b60200260200101818152505080606001518a84815181106114dc57fe5b602090810291909101810191909152600354908201516040808401518151625d2d6f60e21b81526001600160a01b03938416600482015290831660248201526044810186905281519290931692630174b5bc9260648083019392829003018186803b15801561154a57600080fd5b505afa15801561155e573d6000803e3d6000fd5b505050506040513d604081101561157457600080fd5b5080516020909101518c518d908690811061158b57fe5b602002602001018a868151811061159e57fe5b60209081029190910101919091525250506001016113a6565b5050505b505b509397509397509397909450565b7f000000000000000000000000000000000000000000000000000000000000000081565b6006546001600160a01b031681565b611606611d9c565b611643576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a43905887f00000000000000000000000000000000000000000000000000000000000000006040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561173057600080fd5b505afa158015611744573d6000803e3d6000fd5b505050506040513d602081101561175a57600080fd5b505190506001600160a01b0381166117ae576040805162461bcd60e51b81526020600482015260126024820152711c185a5c9059191c881b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6001600160a01b0381166000908152600a6020526040902054806117f4575060098054600181019091556001600160a01b0382166000908152600a602052604090208190555b6002600860008a6001600160a01b03166001600160a01b03168152602001908152602001600020600061184660016009868154811061182f57fe5b600091825260209091206005909102015490613484565b815260200190815260200160002060006101000a81548160ff021916908360ff16021790555061189a89897f00000000000000000000000000000000000000000000000000000000000000008a8a8a6122f9565b909a909950975050505050505050565b600080600260015414156118f3576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166000908152600760205260409020543411611970576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156119cb57600080fd5b505af11580156119df573d6000803e3d6000fd5b5050505050611a12867f0000000000000000000000000000000000000000000000000000000000000000878734886134cb565b600180559097909650945050505050565b60008082611a3657508490506000611d82565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a439058a8a6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505190506001600160a01b03811615611d80576001600160a01b0381166000908152600a60205260409020548015611d7e57600060098281548110611b2157fe5b906000526020600020906005020190508060030160008a8152602001908152602001600020546000148015611b6457506000898152600482016020526040902054155b15611b87576001600160a01b038b16600090815260018201602052604090205498505b8815611d7c57600089815260028083016020908152604092839020835160c08101855281546001600160a01b039081168252600183015481169382018490529382015484169481019490945260038101546060850152600481015460808501526005015460a0840152908d1614611c16576001600160a01b038c16600090815260018301602052604090205499505b8915611d7a5760008a8152600283016020526040902060040154611c3a9089613bec565b60008b8152600284016020526040902060050154611c59908b90613bec565b11611cfe5760008a815260038301602052604090205480611c85578a6001965096505050505050611d82565b6000818152600284016020526040902060040154611ca3908a613bec565b6000828152600285016020526040902060050154611cc2908c90613bec565b11611ced57611cdf8d8d838d8d611cda8e60016130a1565b611a23565b965096505050505050611d82565b8a6001965096505050505050611d82565b60008a815260048301602052604090205480611d25578a6001965096505050505050611d82565b6000818152600284016020526040902060040154611d43908a613bec565b6000828152600285016020526040902060050154611d62908c90613bec565b10611ced57611cdf8d8d838d8d611cda8e60016130a1565b505b505b505b505b965096945050505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b7f000000000000000000000000000000000000000000000000000000000000000081565b600b6020526000908152604090205481565b7f000000000000000000000000000000000000000000000000000000000000000081565b611e0f611d9c565b611e4c576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000611e78611d9c565b611eb5576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b50600380546001600160a01b0319166001600160a01b03831617905560015b919050565b606060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390587876040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611f5b57600080fd5b505afa158015611f6f573d6000803e3d6000fd5b505050506040513d6020811015611f8557600080fd5b505190506001600160a01b0381161561218d576001600160a01b0381166000908152600a6020526040902054801561218b57600060098281548110611fc657fe5b906000526020600020906005020190508060030160008781526020019081526020016000205460001415612072576001600160a01b0388166000908152600182016020908152604080832054898452600485019092529091205415158061202c57508087145b1561206c576040805160018082528183019092529060208083019080368337019050509450868560008151811061205f57fe5b6020026020010181815250505b50612189565b604080516001808252818301909252906020808301908036833701905050935085846000815181106120a057fe5b602002602001018181525050846001146121895760006120e9826003016000876000815181106120cc57fe5b602002602001015181526020019081526020016000205486613c41565b80519091506000600384018184600019850185811061210457fe5b602002602001015181526020019081526020016000205490505b60008111801561212d57508782105b156121835761213c8184613c41565b9250825182141561214c57612183565b8251915060038401600084600019850185811061216557fe5b6020026020010151815260200190815260200160002054905061211e565b50909450505b505b505b50949350505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561221757600080fd5b505afa15801561222b573d6000803e3d6000fd5b505050506040513d602081101561224157600080fd5b505190506001600160a01b038116156122f1576001600160a01b0381166000908152600a602052604090205480156122ef57856001600160a01b03166009828154811061228a57fe5b60009182526020808320888452600260059093020191909101905260409020600101546001600160a01b031614156122ef57600981815481106122c957fe5b906000526020600020906005020160030160008581526020019081526020016000205492505b505b509392505050565b60008060026001541415612342576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556001600160a01b038716600090815260076020526040902054841161239f576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b6123ab87333087613328565b6123b98888888888886134cb565b6001805590999098509650505050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561244d57600080fd5b505afa158015612461573d6000803e3d6000fd5b505050506040513d602081101561247757600080fd5b50516001600160a01b0381166000908152600a602052604090205490915080156122ef57856001600160a01b0316600982815481106124b257fe5b60009182526020808320888452600260059093020191909101905260409020600101546001600160a01b031614156122ef57600981815481106124f157fe5b9060005260206000209060050201600401600085815260200190815260200160002054925050509392505050565b600060026001541415612567576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b600260015561257885858585612ba1565b336000908152600c602090815260408083206001600160a01b03891684529091529020546125a69083613484565b336000908152600c602090815260408083206001600160a01b038a168452909152902055506001808055949350505050565b60008060026001541415612621576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556006546001600160a01b0316331461263d57600080fd5b336000908152600c602090815260408083206001600160a01b038b1684529091529020548411156126ac576040805162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742042616c616e636560601b604482015290519081900360640190fd5b6001600160a01b038716600090815260076020526040902054841015612705576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b336000908152600c602090815260408083206001600160a01b038b16845290915290205461273390856130a1565b336000818152600c602090815260408083206001600160a01b038d1684529091529020919091556127689088888888886134cb565b60018055909890975095505050505050565b6000612784611d9c565b6127c1576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b506001600160a01b038216600090815260076020526040902081905560015b92915050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390585856040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561286757600080fd5b505afa15801561287b573d6000803e3d6000fd5b505050506040513d602081101561289157600080fd5b505190506001600160a01b038116156128fe576001600160a01b0381166000908152600a602052604090205480156128fc57600981815481106128d057fe5b600091825260208083206001600160a01b03891684526001600590930201919091019052604090205492505b505b5092915050565b61290d611d9c565b61294a576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b610cdc81613cf9565b336000908152600c602090815260408083206001600160a01b03861684529091529020548111156129c1576040805162461bcd60e51b815260206004820152601360248201527224b739bab33334b1b4b2b73a10273ab6b132b960691b604482015290519081900360640190fd5b6129cc8233836131dc565b336000908152600c602090815260408083206001600160a01b03861684529091529020546129fa90826130a1565b336000908152600c602090815260408083206001600160a01b0387168452825280832093909355600b9052205461102590826130a1565b600c60209081526000928352604080842090915290825290205481565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1781529251825160009485949389169392918291908083835b60208310612aca5780518252601f199092019160209182019101612aab565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612b2c576040519150601f19603f3d011682016040523d82523d6000602084013e612b31565b606091505b5091509150818015612b5f575080511580612b5f5750808060200190516020811015612b5c57600080fd5b50515b612b9a5760405162461bcd60e51b815260040180806020018281038252602f815260200180615b5d602f913960400191505060405180910390fd5b5050505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015612c2157600080fd5b505afa158015612c35573d6000803e3d6000fd5b505050506040513d6020811015612c4b57600080fd5b50516001600160a01b0381166000908152600a602052604090205490915080612cb1576040805162461bcd60e51b81526020600482015260136024820152721d1bdad95b94185a5c881b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b600060098281548110612cc057fe5b60009182526020808320888452600260059093020191820190526040909120549091506001600160a01b03163314612d2f576040805162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21036b0b5b2b960991b604482015290519081900360640190fd5b84612d73576040805162461bcd60e51b815260206004820152600f60248201526e1bdc99195c881b9bdd08195e1a5cdd608a1b604482015290519081900360640190fd5b600085815260028201602052604090206003015484811015612ddc576040805162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e742052656d61696e4e756d62657200000000000000604482015290519081900360640190fd5b84811415612f65576001600160a01b0388166000908152600183016020526040902054861415612e4d576000868152600383016020818152604080842080546001600160a01b038e168652600188018452828620819055855260048701835290842084905589845291905255612f60565b600086815260048301602052604090205480612e9e576040805162461bcd60e51b815260206004820152600b60248201526a0dcde40e0e4ca92dcc8caf60ab1b604482015290519081900360640190fd5b60008781526002840160205260409020600101546001600160a01b038a8116911614612f09576040805162461bcd60e51b815260206004820152601560248201527434b73b30b634b210333937b6aa37b5b2b720b2323960591b604482015290519081900360640190fd5b60008781526003840160205260408082205483835291208190558015612f3d57600081815260048501602052604090208290555b505060008681526004830160209081526040808320839055600385019091528120555b612f84565b612f6f81866130a1565b60008781526002840160205260409020600301555b600080612f918a8a613da3565b60035460408051636128bde760e01b81526001600160a01b038f811660048301528e811660248301528b81166044830152606482018690526084820185905291519496509294501691636128bde79160a48082019260009290919082900301818387803b15801561300157600080fd5b505af1158015613015573d6000803e3d6000fd5b505060035460408051636430f85b60e11b81526001600160a01b038f811660048301528e81166024830152604482018e9052606482018d9052915191909216935063c861f0b69250608480830192600092919082900301818387803b15801561307d57600080fd5b505af1158015613091573d6000803e3d6000fd5b5050505050505050505050505050565b6000828211156130de576040805162461bcd60e51b815260206004820152600360248201526239bab160e91b604482015290519081900360640190fd5b50900390565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106131305780518252601f199092019160209182019101613111565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613192576040519150601f19603f3d011682016040523d82523d6000602084013e613197565b606091505b50509050806131d75760405162461bcd60e51b8152600401808060200182810382526034815260200180615bac6034913960400191505060405180910390fd5b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1781529251825160009485949389169392918291908083835b602083106132585780518252601f199092019160209182019101613239565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146132ba576040519150601f19603f3d011682016040523d82523d6000602084013e6132bf565b606091505b50915091508180156132ed5750805115806132ed57508080602001905160208110156132ea57600080fd5b50515b612b9a5760405162461bcd60e51b8152600401808060200182810382526030815260200180615be06030913960400191505060405180910390fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b602083106133ac5780518252601f19909201916020918201910161338d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461340e576040519150601f19603f3d011682016040523d82523d6000602084013e613413565b606091505b5091509150818015613441575080511580613441575080806020019051602081101561343e57600080fd5b50515b61347c5760405162461bcd60e51b8152600401808060200182810382526035815260200180615c106035913960400191505060405180910390fd5b505050505050565b6000828201838110156134c4576040805162461bcd60e51b815260206004820152600360248201526218591960ea1b604482015290519081900360640190fd5b9392505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390589896040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561354e57600080fd5b505afa158015613562573d6000803e3d6000fd5b505050506040513d602081101561357857600080fd5b505190506001600160a01b0381166135cc576040805162461bcd60e51b81526020600482015260126024820152711c185a5c9059191c881b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6001600160a01b0381166000908152600a602052604090205480613612575060098054600181019091556001600160a01b0382166000908152600a602052604090208190555b60006009828154811061362157fe5b906000526020600020906005020190506136496001826000015461348490919063ffffffff16565b8082556001600160a01b038b16600090815260018301602052604090205490945080156136ed578861367d578098506136e0565b60008981526003830160205260409020541580156136a957506000898152600483016020526040902054155b156136b6578098506136e0565b60008981526002830160205260409020600101546001600160a01b038c81169116146136e0578098505b6136ed8986848b8b613f19565b60035460408051633503a93d60e21b81526001600160a01b038f811660048301528e811660248301528d81166044830152606482018c9052608482018b905260a482018990529151919092169163d40ea4f49160c480830192600092919082900301818387803b15801561376057600080fd5b505af1158015613774573d6000803e3d6000fd5b5050505060006040518060c001604052808e6001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b031681526020018a81526020018a81526020018981525090508083600201600088815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600301556080820151816004015560a0820151816005015590505060008061388f8e8e613da3565b60008a81526004880160205260409020549193509150613a7f576020808401516001600160a01b0316600090815260018701909152604090208890556138d88589858585614109565b6000888152600286016020526040902060030154985088613953576000888152600386016020908152604080832054868301516001600160a01b0316845260018901909252909120819055801561394d5760008981526003870160209081526040808320839055838352600489019091528120555b5061399a565b6020808401516001600160a01b03166000908152600b909152604090205461397b908a613484565b6020808501516001600160a01b03166000908152600b90915260409020555b60008e6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156139e957600080fd5b505afa1580156139fd573d6000803e3d6000fd5b505050506040513d6020811015613a1357600080fd5b50516020858101516001600160a01b03166000908152600b9091526040902054909150811115613a79576020808501516002546001600160a01b038083166000908152600b909452604090932054613a799390911690613a749085906130a1565b6131dc565b50613ac9565b6020808401516001600160a01b03166000908152600b90915260409020548b9950613aaa908a613484565b6020808501516001600160a01b03166000908152600b90915260409020555b60035460208401516040808601518151636128bde760e01b81526001600160a01b03938416600482015290831660248201528a83166044820152606481018690526084810185905290519190921691636128bde79160a480830192600092919082900301818387803b158015613b3e57600080fd5b505af1158015613b52573d6000803e3d6000fd5b50506004546001600160a01b0316159150613bda9050576004805460408051639840933760e01b815290516001600160a01b039092169263984093379282820192602092908290030181600087803b158015613bad57600080fd5b505af1158015613bc1573d6000803e3d6000fd5b505050506040513d6020811015613bd757600080fd5b50505b50505050505050965096945050505050565b600082613bfb575060006127e0565b82820282848281613c0857fe5b04146134c4576040805162461bcd60e51b81526020600482015260036024820152621b5d5b60ea1b604482015290519081900360640190fd5b606082613c4f5750806127e0565b815160006001820167ffffffffffffffff81118015613c6d57600080fd5b50604051908082528060200260200182016040528015613c97578160200160208202803683370190505b50905060005b82811015613cd857848181518110613cb157fe5b6020026020010151828281518110613cc557fe5b6020908102919091010152600101613c9d565b5084818381518110613ce657fe5b6020908102919091010152949350505050565b6001600160a01b038116613d48576040805162461bcd60e51b8152602060048201526011602482015270696e636f7272656374206164647265737360781b604482015290519081900360640190fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000613db2858561595f565b5090506000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a4390588886040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015613e3657600080fd5b505afa158015613e4a573d6000803e3d6000fd5b505050506040513d6020811015613e6057600080fd5b505160408051630240bc6b60e21b815290516001600160a01b0390921691630902f1ac91600480820192606092909190829003018186803b158015613ea457600080fd5b505afa158015613eb8573d6000803e3d6000fd5b505050506040513d6060811015613ece57600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506001600160a01b0387811690841614613f08578082613f0b565b81815b909890975095505050505050565b6000858152600284016020526040902060040154613f379082613bec565b6000868152600285016020526040902060050154613f56908490613bec565b1161403357600085815260038401602052604090205480613f9b576000868152600385016020908152604080832088905587835260048701909152902086905561402d565b6000818152600285016020526040902060040154613fb99083613bec565b6000828152600286016020526040902060050154613fd8908590613bec565b11613fef57613fea8186868686613f19565b61402d565b600085815260048501602081815260408084208a9055898452600388018083528185208a905585855292825280842089905588845291905290208190555b50612b9a565b600085815260048401602052604090205480614073576000868152600485016020908152604080832088905587835260038701909152902086905561347c565b60008181526002850160205260409020600401546140919083613bec565b60008281526002860160205260409020600501546140b0908590613bec565b106140c7576140c28186868686613f19565b61347c565b600085815260038501602081815260408084208a9055988352600490960180875288832088905583835290865287822087905595815294909352505091902055565b60a08301516141189083613bec565b60808401516141279083613bec565b1115614f8557600061414384608001518560a001518585615990565b90508360800151811115614158575060808301515b6040805160608101825260008082526020808301829052878401516001600160a01b0316825260018a0190528290205491810182905290156148ea576000876002016000836002600381106141a957fe5b602090810291909101518252818101929092526040908101600020815160c08101835281546001600160a01b03908116825260018301548116948201949094526002820154909316918301919091526003810154606083015260048101546080830152600581015460a08084018290528901519193506142299190613bec565b6080808301519089015161423c91613bec565b106148e757600061425e8260a001518960a00151613bec90919063ffffffff16565b608080840151908a015161427191613bec565b141561427e575083614295565b6142928260a0015183608001518989615990565b90505b8085106148e55760808801516000906142ae90836130a1565b90505b6040850151158015906142c45750600081115b156148e35760006142d484615a42565b905060006142f06103e86142ea846103e5613bec565b90615a73565b90508183106146c1577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685604001516001600160a01b031614801561436857506020858101516001600160a01b031660009081526008825260408082208a8201518352909252205460ff166002145b156143fe577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156143d357600080fd5b505af11580156143e7573d6000803e3d6000fd5b505050506143f98560000151826130e4565b614411565b61441185604001518660000151836131dc565b614424828860005b602002015190613484565b8752606085015161443790886001614419565b602080890191909152600060038881018290555491870151604080890151818c015160608b015183516342dc858d60e01b81526001600160a01b03958616600482015292851660248401526044830191909152606482018790526084820152905191909316926342dc858d9260a480830193919282900301818387803b1580156144c057600080fd5b505af11580156144d4573d6000803e3d6000fd5b5060009250505060038e01818960026020020151815260200190815260200160002054905060008e60030160008a60026003811061450e57fe5b6020020151815260200190815260200160002081905550808860026003811061453357fe5b602002015287600260200201518e60010160008e604001516001600160a01b03166001600160a01b03168152602001908152602001600020819055508760026003811061457c57fe5b6020020151156146bb57600060048f01818a600260200201518152602001908152602001600020819055508d6002016000896002600381106145ba57fe5b602090810291909101518252818101929092526040908101600020815160c08101835281546001600160a01b03908116825260018301548116948201949094526002820154909316918301919091526003810154606083015260048101546080830152600581015460a08084018290528f015191995091975061463c91613bec565b608080880151908e015161464f91613bec565b106146b6576146688660a0015187608001518d8d615990565b885190955060009061467b908790613484565b9050858a101580156146905750808d60800151115b156146ab5760808d01516146a490826130a1565b94506146b0565b600094505b506146bb565b600093505b506148dc565b60006146d56103e86142ea866103e5613bec565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031686604001516001600160a01b031614801561474657506020868101516001600160a01b031660009081526008825260408082208b8201518352909252205460ff166002145b156147dc577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156147b157600080fd5b505af11580156147c5573d6000803e3d6000fd5b505050506147d78660000151826130e4565b6147ef565b6147ef86604001518760000151836131dc565b6147fb84896000614419565b885260a0860151608087015160009190614816908490613bec565b8161481d57fe5b04905061482c818a6001614419565b60208a0152606087015161484090826130a1565b6003898101919091555460208801516040808a01518c82015182516342dc858d60e01b81526001600160a01b039485166004820152918416602483015260448201526064810186905260848101859052905191909216916342dc858d9160a480830192600092919082900301818387803b1580156148bd57600080fd5b505af11580156148d1573d6000803e3d6000fd5b505050506000945050505b50506142b1565b505b505b50505b600061490282825b60200201516080880151906130a1565b90508083101561490f5750815b8015614c8a5761492181836000614419565b8252602086015160408701518686600061493d836103e8613bec565b905060006149586103e56149528560016130a1565b90613bec565b90506000614971600283858161496a57fe5b0490613484565b9050808810614c82576000614987898787615ac3565b9050614995818b6001614419565b60208b8101919091526040805163e6a4390560e01b81526001600160a01b038b811660048301528a8116602483015291516000937f00000000000000000000000000000000000000000000000000000000000000009093169263e6a439059260448082019391829003018186803b158015614a0f57600080fd5b505afa158015614a23573d6000803e3d6000fd5b505050506040513d6020811015614a3957600080fd5b50519050614a4889828c6131dc565b6000614a548a8a61595f565b509050806001600160a01b03168a6001600160a01b03161415614b5b57604080516000808252602082019283905263022c0d9f60e01b835260248201818152604483018790523060648401819052608060848501908152845160a486018190526001600160a01b0389169663022c0d9f968b9590939092909160c48501918083838b5b83811015614aef578181015183820152602001614ad7565b50505050905090810190601f168015614b1c5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015614b3e57600080fd5b505af1158015614b52573d6000803e3d6000fd5b50505050614c42565b604080516000808252602082019283905263022c0d9f60e01b835260248201868152604483018290523060648401819052608060848501908152845160a486018190526001600160a01b0389169663022c0d9f968b969590939092909160c48501918083838a5b83811015614bda578181015183820152602001614bc2565b50505050905090810190601f168015614c075780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015614c2957600080fd5b505af1158015614c3d573d6000803e3d6000fd5b505050505b6001600160a01b0389166000908152600b6020526040902054614c659084613484565b6001600160a01b038a166000908152600b60205260409020555050505b505050505050505b815115614f7d57602082015115614eba577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031686604001516001600160a01b0316148015614d0757506020868101516001600160a01b031660009081526008825260408082208a8352909252205460ff166002145b15614dab576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016632e1a7d4d83600160200201516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015614d7957600080fd5b505af1158015614d8d573d6000803e3d6000fd5b50508751614da6925090508360015b60200201516130e4565b614dc5565b60408601518651614dc591908460015b60200201516131dc565b6005546001600160a01b031615614e725760055486516020808901516040808b015187840151825163152cf14360e31b81526001600160a01b03968716600482015293861660248501529085166044840152606483015251929093169263a9678a1892608480830193928290030181600087803b158015614e4557600080fd5b505af1158015614e59573d6000803e3d6000fd5b505050506040513d6020811015614e6f57600080fd5b50505b6020808301516040808901516001600160a01b03166000908152600b90935290912054614e9e916130a1565b6040808801516001600160a01b03166000908152600b60205220555b600354600088815260028a810160209081526040808420600181015493015491870151875182516342dc858d60e01b81526001600160a01b0395861660048201529385166024850152604484018e9052606484019190915260848301525191909316926342dc858d9260a480830193919282900301818387803b158015614f4057600080fd5b505af1158015614f54573d6000803e3d6000fd5b50505050614f68826000600381106148f257fe5b600088815260028a0160205260409020600301555b505050612b9a565b6040805160608101825260008082526020808301829052868401516001600160a01b03168252600189019052829020549181019190915260808401515b604082015115801590614fd457508015155b1561567057600087600201600084600260038110614fee57fe5b60200201518152602001908152602001600020905061501e81600501548760a00151613bec90919063ffffffff16565b6004820154608088015161503191613bec565b1415615664576150428360006148f2565b6040805160c08101825283546001600160a01b039081168252600185015481166020830152600285015416918101919091526003830154606082015260048301546080820152600583015460a08201529092506000906150a190615a42565b90508083106153925760006150be6103e86142ea846103e5613bec565b60028401549091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03908116911614801561512e575060018301546001600160a01b0316600090815260086020908152604080832088820151845290915290205460ff166002145b156151cc577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561519957600080fd5b505af11580156151ad573d6000803e3d6000fd5b505084546151c792506001600160a01b03169050826130e4565b6151ea565b600283015483546151ea916001600160a01b039081169116836131dc565b6151f682866000614419565b8552600383015461520990866001614419565b602086810191909152600354604080880151600090815260028e810194859052918120600101546001600160a01b03938416946342dc858d94909116929091908a9060209081029190910151825281019190915260409081016000908120600201548a83015160038a015484516001600160e01b031960e089901b1681526001600160a01b0396871660048201529590921660248601526044850152606484018790526084840152905160a48084019382900301818387803b1580156152ce57600080fd5b505af11580156152e2573d6000803e3d6000fd5b50505050604085810151600090815260038c016020908152828220548b8401516001600160a01b0316835260018e01909152919020819055801561534857604080870151600090815260038d01602090815282822082905583825260048e019052908120555b60008b60020160008860026003811061535d57fe5b6020020151815260200190815260200160002060030181905550808660026003811061538557fe5b60200201525061565e9050565b60006153a66103e86142ea866103e5613bec565b60028401549091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081169116148015615416575060018301546001600160a01b0316600090815260086020908152604080832088820151845290915290205460ff166002145b156154b4577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561548157600080fd5b505af1158015615495573d6000803e3d6000fd5b505084546154af92506001600160a01b03169050826130e4565b6154d2565b600283015483546154d2916001600160a01b039081169116836131dc565b6080880151855260058301546004840154600091906154f2908490613bec565b816154f957fe5b04905061550881876001614419565b6020870152600384015461551c90826130a1565b8b60020160008860026003811061552f57fe5b6020020151815260200190815260200160002060030181905550600360009054906101000a90046001600160a01b03166001600160a01b03166342dc858d8c60020160008960026003811061558057fe5b6020020151815260200190815260200160002060010160009054906101000a90046001600160a01b03168d60020160008a6002600381106155bd57fe5b60209081029190910151825281019190915260409081016000908120600201548b83015183516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909116602485015260448401526064830187905260848301869052905160a48084019382900301818387803b15801561563d57600080fd5b505af1158015615651573d6000803e3d6000fd5b5050505050505050615670565b5061566a565b50615670565b50614fc2565b815115615956577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685604001516001600160a01b03161480156156e357506020858101516001600160a01b03166000908152600882526040808220898352909252205460ff166002145b15615781576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016632e1a7d4d83600160200201516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561575557600080fd5b505af1158015615769573d6000803e3d6000fd5b5050865161577c92509050836001614d9c565b615795565b604085015185516157959190846001614dbb565b6005546001600160a01b0316156158425760055485516020808801516040808a015187840151825163152cf14360e31b81526001600160a01b03968716600482015293861660248501529085166044840152606483015251929093169263a9678a1892608480830193928290030181600087803b15801561581557600080fd5b505af1158015615829573d6000803e3d6000fd5b505050506040513d602081101561583f57600080fd5b50505b6020808301516040808801516001600160a01b03166000908152600b9093529091205461586e916130a1565b6040868101516001600160a01b039081166000908152600b6020908152838220949094556003548a825260028c81018652848320600181015491015495880151885186516342dc858d60e01b815292861660048401529685166024830152604482018d905260648201526084810195909552925192909116926342dc858d9260a4808301939282900301818387803b15801561590957600080fd5b505af115801561591d573d6000803e3d6000fd5b505050506159418260006003811061593157fe5b60200201516080870151906130a1565b60008781526002890160205260409020600301555b50505050505050565b600080826001600160a01b0316846001600160a01b031610615982578284615985565b83835b909590945092505050565b600080846103e56159a96103e86149528a818a8a613bec565b816159b057fe5b04816159b857fe5b049050600063ec477c746159d261230d6149528880613bec565b816159d957fe5b04905060006159f06159eb8484613484565b615b0b565b905060006107ca615a03886107cd613bec565b81615a0a57fe5b04905080821115615a3157615a2a6001615a2484846130a1565b90613484565b9450615a36565b600094505b50505050949350505050565b60006127e06103e56142ea6103e861495286608001516142ea88606001518960a00151613bec90919063ffffffff16565b6000808211615aaf576040805162461bcd60e51b81526020600482015260036024820152623234bb60e91b604482015290519081900360640190fd5b6000828481615aba57fe5b04949350505050565b600080615ad2856103e5613bec565b90506000615ae08285613bec565b90506000615af483615a24886103e8613bec565b9050808281615aff57fe5b04979650505050505050565b60006003821115615b4e575080600160028204015b81811015615b4857809150600281828581615b3757fe5b040181615b4057fe5b049050615b20565b50611ed4565b8115611ed45750600191905056fe5472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b20415050524f56455f4641494c45445265656e7472616e637947756172643a207265656e7472616e742063616c6c005472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f4641494c45445472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f46524f4d5f4641494c4544a2646970667358221220897532e588292b1fee078ed1f909ed34dfe9d24c1a3fbf6b86c72e1045574e7064736f6c63430007060033608060405234801561001057600080fd5b50604051610ad1380380610ad18339818101604052602081101561003357600080fd5b50516001600081815581546001600160a01b0319163317918290556040516001600160a01b039290921691600080516020610ab1833981519152908290a361007a81610080565b50610119565b6001600160a01b0381166100cf576040805162461bcd60e51b8152602060048201526011602482015270696e636f7272656374206164647265737360781b604482015290519081900360640190fd5b6001546040516001600160a01b03808416921690600080516020610ab183398151915290600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b610989806101286000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c80638f32d59b1161005b5780638f32d59b14610190578063a96d222714610198578063cb7cce16146101a0578063f2fde38b146101c65761007d565b80635e86973014610082578063715018a6146101625780638da5cb5b1461016c575b600080fd5b61014e600480360360a081101561009857600080fd5b6001600160a01b0382358116926020810135821692604082013592606083013516919081019060a0810160808201356401000000008111156100d957600080fd5b8201836020820111156100eb57600080fd5b8035906020019184600183028401116401000000008311171561010d57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506101ec945050505050565b604080519115158252519081900360200190f35b61016a6105a1565b005b610174610630565b604080516001600160a01b039092168252519081900360200190f35b61014e61063f565b610174610650565b61016a600480360360208110156101b657600080fd5b50356001600160a01b031661065f565b61016a600480360360208110156101dc57600080fd5b50356001600160a01b03166106c6565b600060026000541415610246576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026000819055506000856001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561029d57600080fd5b505afa1580156102b1573d6000803e3d6000fd5b505050506040513d60208110156102c757600080fd5b5051905084811015610317576040805162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b604482015290519081900360640190fd5b61032386888688610717565b600080856001600160a01b0316856040518082805190602001908083835b602083106103605780518252601f199092019160209182019101610341565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146103c2576040519150601f19603f3d011682016040523d82523d6000602084013e6103c7565b606091505b50915091508180156103f55750805115806103f557508080602001905160208110156103f257600080fd5b50515b610434576040805162461bcd60e51b815260206004820152600b60248201526a1b1bd85b8819985a5b195960aa1b604482015290519081900360640190fd5b600254604080516396fb721760e01b81526001600160a01b038c8116600483015260248201879052915191909216916396fb72179160448083019260209291908290030181600087803b15801561048a57600080fd5b505af115801561049e573d6000803e3d6000fd5b505050506040513d60208110156104b457600080fd5b50516104bf57600080fd5b82886001600160a01b03166370a082318b6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561050d57600080fd5b505afa158015610521573d6000803e3d6000fd5b505050506040513d602081101561053757600080fd5b5051101561058c576040805162461bcd60e51b815260206004820152601960248201527f6572726f722062616c616e63653a6c6f616e206661696c656400000000000000604482015290519081900360640190fd5b60019350505050600160005595945050505050565b6105a961063f565b6105e6576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b6001546001600160a01b031690565b6001546001600160a01b0316331490565b6002546001600160a01b031681565b61066761063f565b6106a4576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6106ce61063f565b61070b576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b61071481610873565b50565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b6020831061079b5780518252601f19909201916020918201910161077c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146107fd576040519150601f19603f3d011682016040523d82523d6000602084013e610802565b606091505b5091509150818015610830575080511580610830575080806020019051602081101561082d57600080fd5b50515b61086b5760405162461bcd60e51b815260040180806020018281038252603581526020018061091f6035913960400191505060405180910390fd5b505050505050565b6001600160a01b0381166108c2576040805162461bcd60e51b8152602060048201526011602482015270696e636f7272656374206164647265737360781b604482015290519081900360640190fd5b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b039290921691909117905556fe5472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f46524f4d5f4641494c4544a2646970667358221220f34f03197cd6cdbdac3da9f2bf4749659ea5baee38066392730d9a572c198e3764736f6c634300070600338be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e00000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12700000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b2

Deployed Bytecode

0x6080604052600436106101fd5760003560e01c80638f32d59b1161010d578063d40ea4f4116100a0578063e91b3f321161006f578063e91b3f3214610b94578063ed57fb2814610bcd578063f2fde38b14610c08578063f3fef3a314610c3b578063f55f918d14610c74576102b7565b8063d40ea4f414610a64578063d58960cf14610ab9578063e0ada45e14610afc578063e2a9bed114610b45576102b7565b8063b2855b4f116100dc578063b2855b4f14610922578063bf653f9314610955578063c2ffcaad14610988578063c621c9e114610a21576102b7565b80638f32d59b1461089e5780639ad5981e146108b3578063a8f9cb0e146108c8578063ad5c46481461090d576102b7565b80634f88718311610190578063715018a61161015f578063715018a6146107605780637170cba51461077557806371e43506146107dd5780638cd0cb10146108195780638da5cb5b14610889576102b7565b80634f8871831461044857806350c84f6b1461047b57806359d0f713146107365780636c37a7591461074b576102b7565b806339e7fddc116101cc57806339e7fddc146103b2578063441e24b9146103c757806347e7ef24146103fa5780634e5eda1114610433576102b7565b8063021be644146102be5780630f825ee2146102f15780631108749d1461034e57806317c1116a1461037f576102b7565b366102b75760003411801561023b5750336001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12701614155b156102b5577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561029b57600080fd5b505af11580156102af573d6000803e3d6000fd5b50505050505b005b6060516080f35b3480156102ca57600080fd5b506102b5600480360360208110156102e157600080fd5b50356001600160a01b0316610caf565b3480156102fd57600080fd5b5061033a6004803603608081101561031457600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135610cdf565b604080519115158252519081900360200190f35b34801561035a57600080fd5b50610363610ec8565b604080516001600160a01b039092168252519081900360200190f35b34801561038b57600080fd5b506102b5600480360360208110156103a257600080fd5b50356001600160a01b0316610ed7565b3480156103be57600080fd5b50610363610f3e565b3480156103d357600080fd5b506102b5600480360360208110156103ea57600080fd5b50356001600160a01b0316610f4d565b34801561040657600080fd5b506102b56004803603604081101561041d57600080fd5b506001600160a01b038135169060200135610fb4565b34801561043f57600080fd5b50610363611045565b34801561045457600080fd5b506102b56004803603602081101561046b57600080fd5b50356001600160a01b0316611054565b34801561048757600080fd5b506105446004803603606081101561049e57600080fd5b6001600160a01b0382358116926020810135909116918101906060810160408201356401000000008111156104d257600080fd5b8201836020820111156104e457600080fd5b8035906020019184602083028401116401000000008311171561050657600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506110bb945050505050565b604051808060200180602001806020018060200180602001806020018060200188810388528f818151815260200191508051906020019060200280838360005b8381101561059c578181015183820152602001610584565b5050505090500188810387528e818151815260200191508051906020019060200280838360005b838110156105db5781810151838201526020016105c3565b5050505090500188810386528d818151815260200191508051906020019060200280838360005b8381101561061a578181015183820152602001610602565b5050505090500188810385528c818151815260200191508051906020019060200280838360005b83811015610659578181015183820152602001610641565b5050505090500188810384528b818151815260200191508051906020019060200280838360005b83811015610698578181015183820152602001610680565b5050505090500188810383528a818151815260200191508051906020019060200280838360005b838110156106d75781810151838201526020016106bf565b50505050905001888103825289818151815260200191508051906020019060200280838360005b838110156107165781810151838201526020016106fe565b505050509050019e50505050505050505050505050505060405180910390f35b34801561074257600080fd5b506103636115cb565b34801561075757600080fd5b506103636115ef565b34801561076c57600080fd5b506102b56115fe565b34801561078157600080fd5b506107c4600480360360a081101561079857600080fd5b506001600160a01b0381358116916020810135909116906040810135906060810135906080013561168d565b6040805192835260208301919091528051918290030190f35b6107c4600480360360808110156107f357600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356118aa565b34801561082557600080fd5b5061086e600480360360c081101561083c57600080fd5b506001600160a01b03813581169160208101359091169060408101359060608101359060808101359060a00135611a23565b6040805192835260ff90911660208301528051918290030190f35b34801561089557600080fd5b50610363611d8d565b3480156108aa57600080fd5b5061033a611d9c565b3480156108bf57600080fd5b50610363611dad565b3480156108d457600080fd5b506108fb600480360360208110156108eb57600080fd5b50356001600160a01b0316611dd1565b60408051918252519081900360200190f35b34801561091957600080fd5b50610363611de3565b34801561092e57600080fd5b506102b56004803603602081101561094557600080fd5b50356001600160a01b0316611e07565b34801561096157600080fd5b5061033a6004803603602081101561097857600080fd5b50356001600160a01b0316611e6e565b34801561099457600080fd5b506109d1600480360360808110156109ab57600080fd5b506001600160a01b03813581169160208101359091169060408101359060600135611ed9565b60408051602080825283518183015283519192839290830191858101910280838360005b83811015610a0d5781810151838201526020016109f5565b505050509050019250505060405180910390f35b348015610a2d57600080fd5b506108fb60048036036060811015610a4457600080fd5b506001600160a01b03813581169160208101359091169060400135612196565b348015610a7057600080fd5b506107c4600480360360c0811015610a8757600080fd5b506001600160a01b03813581169160208101358216916040820135169060608101359060808101359060a001356122f9565b348015610ac557600080fd5b506108fb60048036036060811015610adc57600080fd5b506001600160a01b038135811691602081013590911690604001356123cc565b348015610b0857600080fd5b5061033a60048036036080811015610b1f57600080fd5b506001600160a01b0381358116916020810135909116906040810135906060013561251f565b348015610b5157600080fd5b506107c4600480360360a0811015610b6857600080fd5b506001600160a01b038135811691602081013590911690604081013590606081013590608001356125d8565b348015610ba057600080fd5b5061033a60048036036040811015610bb757600080fd5b506001600160a01b03813516906020013561277a565b348015610bd957600080fd5b506108fb60048036036040811015610bf057600080fd5b506001600160a01b03813581169160200135166127e6565b348015610c1457600080fd5b506102b560048036036020811015610c2b57600080fd5b50356001600160a01b0316612905565b348015610c4757600080fd5b506102b560048036036040811015610c5e57600080fd5b506001600160a01b038135169060200135612953565b348015610c8057600080fd5b506108fb60048036036040811015610c9757600080fd5b506001600160a01b0381358116916020013516612a31565b610cdc817f0000000000000000000000000c41fd2585a0c158b9d760a8e400c55db56971e4600019612a4e565b50565b600060026001541415610d27576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b6002600155610d3885858585612ba1565b6001600160a01b0385166000908152600b6020526040902054610d5b90836130a1565b6001600160a01b038087166000818152600b60205260409020929092557f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270161415610e2d577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610e0657600080fd5b505af1158015610e1a573d6000803e3d6000fd5b50505050610e2833836130e4565b610e38565b610e388533846131dc565b6004546001600160a01b031615610eba576004805460408051639840933760e01b815290516001600160a01b039092169263984093379282820192602092908290030181600087803b158015610e8d57600080fd5b505af1158015610ea1573d6000803e3d6000fd5b505050506040513d6020811015610eb757600080fd5b50505b506001808055949350505050565b6004546001600160a01b031681565b610edf611d9c565b610f1c576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6002546001600160a01b031681565b610f55611d9c565b610f92576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600680546001600160a01b0319166001600160a01b0392909216919091179055565b610fc082333084613328565b336000908152600c602090815260408083206001600160a01b0386168452909152902054610fee9082613484565b336000908152600c602090815260408083206001600160a01b0387168452825280832093909355600b905220546110259082613484565b6001600160a01b039092166000908152600b602052604090209190915550565b6005546001600160a01b031681565b61105c611d9c565b611099576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600580546001600160a01b0319166001600160a01b0392909216919091179055565b606080606080606080606060007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a439058c8c6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561114657600080fd5b505afa15801561115a573d6000803e3d6000fd5b505050506040513d602081101561117057600080fd5b505190506001600160a01b038116156115bd576001600160a01b0381166000908152600a602052604090205480156115bb576000600982815481106111b157fe5b9060005260206000209060050201905060008b5190508067ffffffffffffffff811180156111de57600080fd5b50604051908082528060200260200182016040528015611208578160200160208202803683370190505b509a508067ffffffffffffffff8111801561122257600080fd5b5060405190808252806020026020018201604052801561124c578160200160208202803683370190505b5099508067ffffffffffffffff8111801561126657600080fd5b50604051908082528060200260200182016040528015611290578160200160208202803683370190505b5098508067ffffffffffffffff811180156112aa57600080fd5b506040519080825280602002602001820160405280156112d4578160200160208202803683370190505b5096508067ffffffffffffffff811180156112ee57600080fd5b50604051908082528060200260200182016040528015611318578160200160208202803683370190505b5095508067ffffffffffffffff8111801561133257600080fd5b5060405190808252806020026020018201604052801561135c578160200160208202803683370190505b5097508067ffffffffffffffff8111801561137657600080fd5b506040519080825280602002602001820160405280156113a0578160200160208202803683370190505b50945060005b818110156115b75760008d82815181106113bc57fe5b602090810291909101810151600081815260028088018452604091829020825160c08101845281546001600160a01b0390811680835260018401548216978301979097529282015490921692820192909252600382015460608201526004820154608082015260059091015460a08201528f5191935091908f908590811061144057fe5b60200260200101906001600160a01b031690816001600160a01b03168152505080602001518d848151811061147157fe5b60200260200101906001600160a01b031690816001600160a01b0316815250508060a001518984815181106114a257fe5b60200260200101818152505080608001518c84815181106114bf57fe5b60200260200101818152505080606001518a84815181106114dc57fe5b602090810291909101810191909152600354908201516040808401518151625d2d6f60e21b81526001600160a01b03938416600482015290831660248201526044810186905281519290931692630174b5bc9260648083019392829003018186803b15801561154a57600080fd5b505afa15801561155e573d6000803e3d6000fd5b505050506040513d604081101561157457600080fd5b5080516020909101518c518d908690811061158b57fe5b602002602001018a868151811061159e57fe5b60209081029190910101919091525250506001016113a6565b5050505b505b509397509397509397909450565b7f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b281565b6006546001600160a01b031681565b611606611d9c565b611643576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60008060007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a43905887f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561173057600080fd5b505afa158015611744573d6000803e3d6000fd5b505050506040513d602081101561175a57600080fd5b505190506001600160a01b0381166117ae576040805162461bcd60e51b81526020600482015260126024820152711c185a5c9059191c881b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6001600160a01b0381166000908152600a6020526040902054806117f4575060098054600181019091556001600160a01b0382166000908152600a602052604090208190555b6002600860008a6001600160a01b03166001600160a01b03168152602001908152602001600020600061184660016009868154811061182f57fe5b600091825260209091206005909102015490613484565b815260200190815260200160002060006101000a81548160ff021916908360ff16021790555061189a89897f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12708a8a8a6122f9565b909a909950975050505050505050565b600080600260015414156118f3576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270166000908152600760205260409020543411611970576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b7f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156119cb57600080fd5b505af11580156119df573d6000803e3d6000fd5b5050505050611a12867f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270878734886134cb565b600180559097909650945050505050565b60008082611a3657508490506000611d82565b60007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a439058a8a6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611ab657600080fd5b505afa158015611aca573d6000803e3d6000fd5b505050506040513d6020811015611ae057600080fd5b505190506001600160a01b03811615611d80576001600160a01b0381166000908152600a60205260409020548015611d7e57600060098281548110611b2157fe5b906000526020600020906005020190508060030160008a8152602001908152602001600020546000148015611b6457506000898152600482016020526040902054155b15611b87576001600160a01b038b16600090815260018201602052604090205498505b8815611d7c57600089815260028083016020908152604092839020835160c08101855281546001600160a01b039081168252600183015481169382018490529382015484169481019490945260038101546060850152600481015460808501526005015460a0840152908d1614611c16576001600160a01b038c16600090815260018301602052604090205499505b8915611d7a5760008a8152600283016020526040902060040154611c3a9089613bec565b60008b8152600284016020526040902060050154611c59908b90613bec565b11611cfe5760008a815260038301602052604090205480611c85578a6001965096505050505050611d82565b6000818152600284016020526040902060040154611ca3908a613bec565b6000828152600285016020526040902060050154611cc2908c90613bec565b11611ced57611cdf8d8d838d8d611cda8e60016130a1565b611a23565b965096505050505050611d82565b8a6001965096505050505050611d82565b60008a815260048301602052604090205480611d25578a6001965096505050505050611d82565b6000818152600284016020526040902060040154611d43908a613bec565b6000828152600285016020526040902060050154611d62908c90613bec565b10611ced57611cdf8d8d838d8d611cda8e60016130a1565b505b505b505b505b965096945050505050565b6000546001600160a01b031690565b6000546001600160a01b0316331490565b7f0000000000000000000000000c41fd2585a0c158b9d760a8e400c55db56971e481565b600b6020526000908152604090205481565b7f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127081565b611e0f611d9c565b611e4c576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b6000611e78611d9c565b611eb5576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b50600380546001600160a01b0319166001600160a01b03831617905560015b919050565b606060007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390587876040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015611f5b57600080fd5b505afa158015611f6f573d6000803e3d6000fd5b505050506040513d6020811015611f8557600080fd5b505190506001600160a01b0381161561218d576001600160a01b0381166000908152600a6020526040902054801561218b57600060098281548110611fc657fe5b906000526020600020906005020190508060030160008781526020019081526020016000205460001415612072576001600160a01b0388166000908152600182016020908152604080832054898452600485019092529091205415158061202c57508087145b1561206c576040805160018082528183019092529060208083019080368337019050509450868560008151811061205f57fe5b6020026020010181815250505b50612189565b604080516001808252818301909252906020808301908036833701905050935085846000815181106120a057fe5b602002602001018181525050846001146121895760006120e9826003016000876000815181106120cc57fe5b602002602001015181526020019081526020016000205486613c41565b80519091506000600384018184600019850185811061210457fe5b602002602001015181526020019081526020016000205490505b60008111801561212d57508782105b156121835761213c8184613c41565b9250825182141561214c57612183565b8251915060038401600084600019850185811061216557fe5b6020026020010151815260200190815260200160002054905061211e565b50909450505b505b505b50949350505050565b6000807f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561221757600080fd5b505afa15801561222b573d6000803e3d6000fd5b505050506040513d602081101561224157600080fd5b505190506001600160a01b038116156122f1576001600160a01b0381166000908152600a602052604090205480156122ef57856001600160a01b03166009828154811061228a57fe5b60009182526020808320888452600260059093020191909101905260409020600101546001600160a01b031614156122ef57600981815481106122c957fe5b906000526020600020906005020160030160008581526020019081526020016000205492505b505b509392505050565b60008060026001541415612342576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556001600160a01b038716600090815260076020526040902054841161239f576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b6123ab87333087613328565b6123b98888888888886134cb565b6001805590999098509650505050505050565b6000807f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561244d57600080fd5b505afa158015612461573d6000803e3d6000fd5b505050506040513d602081101561247757600080fd5b50516001600160a01b0381166000908152600a602052604090205490915080156122ef57856001600160a01b0316600982815481106124b257fe5b60009182526020808320888452600260059093020191909101905260409020600101546001600160a01b031614156122ef57600981815481106124f157fe5b9060005260206000209060050201600401600085815260200190815260200160002054925050509392505050565b600060026001541415612567576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b600260015561257885858585612ba1565b336000908152600c602090815260408083206001600160a01b03891684529091529020546125a69083613484565b336000908152600c602090815260408083206001600160a01b038a168452909152902055506001808055949350505050565b60008060026001541415612621576040805162461bcd60e51b815260206004820152601f6024820152600080516020615b8c833981519152604482015290519081900360640190fd5b60026001556006546001600160a01b0316331461263d57600080fd5b336000908152600c602090815260408083206001600160a01b038b1684529091529020548411156126ac576040805162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742042616c616e636560601b604482015290519081900360640190fd5b6001600160a01b038716600090815260076020526040902054841015612705576040805162461bcd60e51b81526020600482015260096024820152681b5a5b881b1a5b5a5d60ba1b604482015290519081900360640190fd5b336000908152600c602090815260408083206001600160a01b038b16845290915290205461273390856130a1565b336000818152600c602090815260408083206001600160a01b038d1684529091529020919091556127689088888888886134cb565b60018055909890975095505050505050565b6000612784611d9c565b6127c1576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b506001600160a01b038216600090815260076020526040902081905560015b92915050565b6000807f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390585856040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561286757600080fd5b505afa15801561287b573d6000803e3d6000fd5b505050506040513d602081101561289157600080fd5b505190506001600160a01b038116156128fe576001600160a01b0381166000908152600a602052604090205480156128fc57600981815481106128d057fe5b600091825260208083206001600160a01b03891684526001600590930201919091019052604090205492505b505b5092915050565b61290d611d9c565b61294a576040805162461bcd60e51b815260206004820152600960248201526837b7363ca7bbb732b960b91b604482015290519081900360640190fd5b610cdc81613cf9565b336000908152600c602090815260408083206001600160a01b03861684529091529020548111156129c1576040805162461bcd60e51b815260206004820152601360248201527224b739bab33334b1b4b2b73a10273ab6b132b960691b604482015290519081900360640190fd5b6129cc8233836131dc565b336000908152600c602090815260408083206001600160a01b03861684529091529020546129fa90826130a1565b336000908152600c602090815260408083206001600160a01b0387168452825280832093909355600b9052205461102590826130a1565b600c60209081526000928352604080842090915290825290205481565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b1781529251825160009485949389169392918291908083835b60208310612aca5780518252601f199092019160209182019101612aab565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114612b2c576040519150601f19603f3d011682016040523d82523d6000602084013e612b31565b606091505b5091509150818015612b5f575080511580612b5f5750808060200190516020811015612b5c57600080fd5b50515b612b9a5760405162461bcd60e51b815260040180806020018281038252602f815260200180615b5d602f913960400191505060405180910390fd5b5050505050565b60007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390586866040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015612c2157600080fd5b505afa158015612c35573d6000803e3d6000fd5b505050506040513d6020811015612c4b57600080fd5b50516001600160a01b0381166000908152600a602052604090205490915080612cb1576040805162461bcd60e51b81526020600482015260136024820152721d1bdad95b94185a5c881b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b600060098281548110612cc057fe5b60009182526020808320888452600260059093020191820190526040909120549091506001600160a01b03163314612d2f576040805162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b21036b0b5b2b960991b604482015290519081900360640190fd5b84612d73576040805162461bcd60e51b815260206004820152600f60248201526e1bdc99195c881b9bdd08195e1a5cdd608a1b604482015290519081900360640190fd5b600085815260028201602052604090206003015484811015612ddc576040805162461bcd60e51b815260206004820152601960248201527f496e73756666696369656e742052656d61696e4e756d62657200000000000000604482015290519081900360640190fd5b84811415612f65576001600160a01b0388166000908152600183016020526040902054861415612e4d576000868152600383016020818152604080842080546001600160a01b038e168652600188018452828620819055855260048701835290842084905589845291905255612f60565b600086815260048301602052604090205480612e9e576040805162461bcd60e51b815260206004820152600b60248201526a0dcde40e0e4ca92dcc8caf60ab1b604482015290519081900360640190fd5b60008781526002840160205260409020600101546001600160a01b038a8116911614612f09576040805162461bcd60e51b815260206004820152601560248201527434b73b30b634b210333937b6aa37b5b2b720b2323960591b604482015290519081900360640190fd5b60008781526003840160205260408082205483835291208190558015612f3d57600081815260048501602052604090208290555b505060008681526004830160209081526040808320839055600385019091528120555b612f84565b612f6f81866130a1565b60008781526002840160205260409020600301555b600080612f918a8a613da3565b60035460408051636128bde760e01b81526001600160a01b038f811660048301528e811660248301528b81166044830152606482018690526084820185905291519496509294501691636128bde79160a48082019260009290919082900301818387803b15801561300157600080fd5b505af1158015613015573d6000803e3d6000fd5b505060035460408051636430f85b60e11b81526001600160a01b038f811660048301528e81166024830152604482018e9052606482018d9052915191909216935063c861f0b69250608480830192600092919082900301818387803b15801561307d57600080fd5b505af1158015613091573d6000803e3d6000fd5b5050505050505050505050505050565b6000828211156130de576040805162461bcd60e51b815260206004820152600360248201526239bab160e91b604482015290519081900360640190fd5b50900390565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106131305780518252601f199092019160209182019101613111565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114613192576040519150601f19603f3d011682016040523d82523d6000602084013e613197565b606091505b50509050806131d75760405162461bcd60e51b8152600401808060200182810382526034815260200180615bac6034913960400191505060405180910390fd5b505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1781529251825160009485949389169392918291908083835b602083106132585780518252601f199092019160209182019101613239565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146132ba576040519150601f19603f3d011682016040523d82523d6000602084013e6132bf565b606091505b50915091508180156132ed5750805115806132ed57508080602001905160208110156132ea57600080fd5b50515b612b9a5760405162461bcd60e51b8152600401808060200182810382526030815260200180615be06030913960400191505060405180910390fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b602083106133ac5780518252601f19909201916020918201910161338d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461340e576040519150601f19603f3d011682016040523d82523d6000602084013e613413565b606091505b5091509150818015613441575080511580613441575080806020019051602081101561343e57600080fd5b50515b61347c5760405162461bcd60e51b8152600401808060200182810382526035815260200180615c106035913960400191505060405180910390fd5b505050505050565b6000828201838110156134c4576040805162461bcd60e51b815260206004820152600360248201526218591960ea1b604482015290519081900360640190fd5b9392505050565b60008060007f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390589896040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561354e57600080fd5b505afa158015613562573d6000803e3d6000fd5b505050506040513d602081101561357857600080fd5b505190506001600160a01b0381166135cc576040805162461bcd60e51b81526020600482015260126024820152711c185a5c9059191c881b9bdd08195e1a5cdd60721b604482015290519081900360640190fd5b6001600160a01b0381166000908152600a602052604090205480613612575060098054600181019091556001600160a01b0382166000908152600a602052604090208190555b60006009828154811061362157fe5b906000526020600020906005020190506136496001826000015461348490919063ffffffff16565b8082556001600160a01b038b16600090815260018301602052604090205490945080156136ed578861367d578098506136e0565b60008981526003830160205260409020541580156136a957506000898152600483016020526040902054155b156136b6578098506136e0565b60008981526002830160205260409020600101546001600160a01b038c81169116146136e0578098505b6136ed8986848b8b613f19565b60035460408051633503a93d60e21b81526001600160a01b038f811660048301528e811660248301528d81166044830152606482018c9052608482018b905260a482018990529151919092169163d40ea4f49160c480830192600092919082900301818387803b15801561376057600080fd5b505af1158015613774573d6000803e3d6000fd5b5050505060006040518060c001604052808e6001600160a01b031681526020018d6001600160a01b031681526020018c6001600160a01b031681526020018a81526020018a81526020018981525090508083600201600088815260200190815260200160002060008201518160000160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060208201518160010160006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060408201518160020160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550606082015181600301556080820151816004015560a0820151816005015590505060008061388f8e8e613da3565b60008a81526004880160205260409020549193509150613a7f576020808401516001600160a01b0316600090815260018701909152604090208890556138d88589858585614109565b6000888152600286016020526040902060030154985088613953576000888152600386016020908152604080832054868301516001600160a01b0316845260018901909252909120819055801561394d5760008981526003870160209081526040808320839055838352600489019091528120555b5061399a565b6020808401516001600160a01b03166000908152600b909152604090205461397b908a613484565b6020808501516001600160a01b03166000908152600b90915260409020555b60008e6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156139e957600080fd5b505afa1580156139fd573d6000803e3d6000fd5b505050506040513d6020811015613a1357600080fd5b50516020858101516001600160a01b03166000908152600b9091526040902054909150811115613a79576020808501516002546001600160a01b038083166000908152600b909452604090932054613a799390911690613a749085906130a1565b6131dc565b50613ac9565b6020808401516001600160a01b03166000908152600b90915260409020548b9950613aaa908a613484565b6020808501516001600160a01b03166000908152600b90915260409020555b60035460208401516040808601518151636128bde760e01b81526001600160a01b03938416600482015290831660248201528a83166044820152606481018690526084810185905290519190921691636128bde79160a480830192600092919082900301818387803b158015613b3e57600080fd5b505af1158015613b52573d6000803e3d6000fd5b50506004546001600160a01b0316159150613bda9050576004805460408051639840933760e01b815290516001600160a01b039092169263984093379282820192602092908290030181600087803b158015613bad57600080fd5b505af1158015613bc1573d6000803e3d6000fd5b505050506040513d6020811015613bd757600080fd5b50505b50505050505050965096945050505050565b600082613bfb575060006127e0565b82820282848281613c0857fe5b04146134c4576040805162461bcd60e51b81526020600482015260036024820152621b5d5b60ea1b604482015290519081900360640190fd5b606082613c4f5750806127e0565b815160006001820167ffffffffffffffff81118015613c6d57600080fd5b50604051908082528060200260200182016040528015613c97578160200160208202803683370190505b50905060005b82811015613cd857848181518110613cb157fe5b6020026020010151828281518110613cc557fe5b6020908102919091010152600101613c9d565b5084818381518110613ce657fe5b6020908102919091010152949350505050565b6001600160a01b038116613d48576040805162461bcd60e51b8152602060048201526011602482015270696e636f7272656374206164647265737360781b604482015290519081900360640190fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000806000613db2858561595f565b5090506000807f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b26001600160a01b031663e6a4390588886040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b158015613e3657600080fd5b505afa158015613e4a573d6000803e3d6000fd5b505050506040513d6020811015613e6057600080fd5b505160408051630240bc6b60e21b815290516001600160a01b0390921691630902f1ac91600480820192606092909190829003018186803b158015613ea457600080fd5b505afa158015613eb8573d6000803e3d6000fd5b505050506040513d6060811015613ece57600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506001600160a01b0387811690841614613f08578082613f0b565b81815b909890975095505050505050565b6000858152600284016020526040902060040154613f379082613bec565b6000868152600285016020526040902060050154613f56908490613bec565b1161403357600085815260038401602052604090205480613f9b576000868152600385016020908152604080832088905587835260048701909152902086905561402d565b6000818152600285016020526040902060040154613fb99083613bec565b6000828152600286016020526040902060050154613fd8908590613bec565b11613fef57613fea8186868686613f19565b61402d565b600085815260048501602081815260408084208a9055898452600388018083528185208a905585855292825280842089905588845291905290208190555b50612b9a565b600085815260048401602052604090205480614073576000868152600485016020908152604080832088905587835260038701909152902086905561347c565b60008181526002850160205260409020600401546140919083613bec565b60008281526002860160205260409020600501546140b0908590613bec565b106140c7576140c28186868686613f19565b61347c565b600085815260038501602081815260408084208a9055988352600490960180875288832088905583835290865287822087905595815294909352505091902055565b60a08301516141189083613bec565b60808401516141279083613bec565b1115614f8557600061414384608001518560a001518585615990565b90508360800151811115614158575060808301515b6040805160608101825260008082526020808301829052878401516001600160a01b0316825260018a0190528290205491810182905290156148ea576000876002016000836002600381106141a957fe5b602090810291909101518252818101929092526040908101600020815160c08101835281546001600160a01b03908116825260018301548116948201949094526002820154909316918301919091526003810154606083015260048101546080830152600581015460a08084018290528901519193506142299190613bec565b6080808301519089015161423c91613bec565b106148e757600061425e8260a001518960a00151613bec90919063ffffffff16565b608080840151908a015161427191613bec565b141561427e575083614295565b6142928260a0015183608001518989615990565b90505b8085106148e55760808801516000906142ae90836130a1565b90505b6040850151158015906142c45750600081115b156148e35760006142d484615a42565b905060006142f06103e86142ea846103e5613bec565b90615a73565b90508183106146c1577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031685604001516001600160a01b031614801561436857506020858101516001600160a01b031660009081526008825260408082208a8201518352909252205460ff166002145b156143fe577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156143d357600080fd5b505af11580156143e7573d6000803e3d6000fd5b505050506143f98560000151826130e4565b614411565b61441185604001518660000151836131dc565b614424828860005b602002015190613484565b8752606085015161443790886001614419565b602080890191909152600060038881018290555491870151604080890151818c015160608b015183516342dc858d60e01b81526001600160a01b03958616600482015292851660248401526044830191909152606482018790526084820152905191909316926342dc858d9260a480830193919282900301818387803b1580156144c057600080fd5b505af11580156144d4573d6000803e3d6000fd5b5060009250505060038e01818960026020020151815260200190815260200160002054905060008e60030160008a60026003811061450e57fe5b6020020151815260200190815260200160002081905550808860026003811061453357fe5b602002015287600260200201518e60010160008e604001516001600160a01b03166001600160a01b03168152602001908152602001600020819055508760026003811061457c57fe5b6020020151156146bb57600060048f01818a600260200201518152602001908152602001600020819055508d6002016000896002600381106145ba57fe5b602090810291909101518252818101929092526040908101600020815160c08101835281546001600160a01b03908116825260018301548116948201949094526002820154909316918301919091526003810154606083015260048101546080830152600581015460a08084018290528f015191995091975061463c91613bec565b608080880151908e015161464f91613bec565b106146b6576146688660a0015187608001518d8d615990565b885190955060009061467b908790613484565b9050858a101580156146905750808d60800151115b156146ab5760808d01516146a490826130a1565b94506146b0565b600094505b506146bb565b600093505b506148dc565b60006146d56103e86142ea866103e5613bec565b90507f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031686604001516001600160a01b031614801561474657506020868101516001600160a01b031660009081526008825260408082208b8201518352909252205460ff166002145b156147dc577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156147b157600080fd5b505af11580156147c5573d6000803e3d6000fd5b505050506147d78660000151826130e4565b6147ef565b6147ef86604001518760000151836131dc565b6147fb84896000614419565b885260a0860151608087015160009190614816908490613bec565b8161481d57fe5b04905061482c818a6001614419565b60208a0152606087015161484090826130a1565b6003898101919091555460208801516040808a01518c82015182516342dc858d60e01b81526001600160a01b039485166004820152918416602483015260448201526064810186905260848101859052905191909216916342dc858d9160a480830192600092919082900301818387803b1580156148bd57600080fd5b505af11580156148d1573d6000803e3d6000fd5b505050506000945050505b50506142b1565b505b505b50505b600061490282825b60200201516080880151906130a1565b90508083101561490f5750815b8015614c8a5761492181836000614419565b8252602086015160408701518686600061493d836103e8613bec565b905060006149586103e56149528560016130a1565b90613bec565b90506000614971600283858161496a57fe5b0490613484565b9050808810614c82576000614987898787615ac3565b9050614995818b6001614419565b60208b8101919091526040805163e6a4390560e01b81526001600160a01b038b811660048301528a8116602483015291516000937f0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b29093169263e6a439059260448082019391829003018186803b158015614a0f57600080fd5b505afa158015614a23573d6000803e3d6000fd5b505050506040513d6020811015614a3957600080fd5b50519050614a4889828c6131dc565b6000614a548a8a61595f565b509050806001600160a01b03168a6001600160a01b03161415614b5b57604080516000808252602082019283905263022c0d9f60e01b835260248201818152604483018790523060648401819052608060848501908152845160a486018190526001600160a01b0389169663022c0d9f968b9590939092909160c48501918083838b5b83811015614aef578181015183820152602001614ad7565b50505050905090810190601f168015614b1c5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015614b3e57600080fd5b505af1158015614b52573d6000803e3d6000fd5b50505050614c42565b604080516000808252602082019283905263022c0d9f60e01b835260248201868152604483018290523060648401819052608060848501908152845160a486018190526001600160a01b0389169663022c0d9f968b969590939092909160c48501918083838a5b83811015614bda578181015183820152602001614bc2565b50505050905090810190601f168015614c075780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015614c2957600080fd5b505af1158015614c3d573d6000803e3d6000fd5b505050505b6001600160a01b0389166000908152600b6020526040902054614c659084613484565b6001600160a01b038a166000908152600b60205260409020555050505b505050505050505b815115614f7d57602082015115614eba577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031686604001516001600160a01b0316148015614d0757506020868101516001600160a01b031660009081526008825260408082208a8352909252205460ff166002145b15614dab576001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127016632e1a7d4d83600160200201516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015614d7957600080fd5b505af1158015614d8d573d6000803e3d6000fd5b50508751614da6925090508360015b60200201516130e4565b614dc5565b60408601518651614dc591908460015b60200201516131dc565b6005546001600160a01b031615614e725760055486516020808901516040808b015187840151825163152cf14360e31b81526001600160a01b03968716600482015293861660248501529085166044840152606483015251929093169263a9678a1892608480830193928290030181600087803b158015614e4557600080fd5b505af1158015614e59573d6000803e3d6000fd5b505050506040513d6020811015614e6f57600080fd5b50505b6020808301516040808901516001600160a01b03166000908152600b90935290912054614e9e916130a1565b6040808801516001600160a01b03166000908152600b60205220555b600354600088815260028a810160209081526040808420600181015493015491870151875182516342dc858d60e01b81526001600160a01b0395861660048201529385166024850152604484018e9052606484019190915260848301525191909316926342dc858d9260a480830193919282900301818387803b158015614f4057600080fd5b505af1158015614f54573d6000803e3d6000fd5b50505050614f68826000600381106148f257fe5b600088815260028a0160205260409020600301555b505050612b9a565b6040805160608101825260008082526020808301829052868401516001600160a01b03168252600189019052829020549181019190915260808401515b604082015115801590614fd457508015155b1561567057600087600201600084600260038110614fee57fe5b60200201518152602001908152602001600020905061501e81600501548760a00151613bec90919063ffffffff16565b6004820154608088015161503191613bec565b1415615664576150428360006148f2565b6040805160c08101825283546001600160a01b039081168252600185015481166020830152600285015416918101919091526003830154606082015260048301546080820152600583015460a08201529092506000906150a190615a42565b90508083106153925760006150be6103e86142ea846103e5613bec565b60028401549091507f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b03908116911614801561512e575060018301546001600160a01b0316600090815260086020908152604080832088820151845290915290205460ff166002145b156151cc577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561519957600080fd5b505af11580156151ad573d6000803e3d6000fd5b505084546151c792506001600160a01b03169050826130e4565b6151ea565b600283015483546151ea916001600160a01b039081169116836131dc565b6151f682866000614419565b8552600383015461520990866001614419565b602086810191909152600354604080880151600090815260028e810194859052918120600101546001600160a01b03938416946342dc858d94909116929091908a9060209081029190910151825281019190915260409081016000908120600201548a83015160038a015484516001600160e01b031960e089901b1681526001600160a01b0396871660048201529590921660248601526044850152606484018790526084840152905160a48084019382900301818387803b1580156152ce57600080fd5b505af11580156152e2573d6000803e3d6000fd5b50505050604085810151600090815260038c016020908152828220548b8401516001600160a01b0316835260018e01909152919020819055801561534857604080870151600090815260038d01602090815282822082905583825260048e019052908120555b60008b60020160008860026003811061535d57fe5b6020020151815260200190815260200160002060030181905550808660026003811061538557fe5b60200201525061565e9050565b60006153a66103e86142ea866103e5613bec565b60028401549091507f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b039081169116148015615416575060018301546001600160a01b0316600090815260086020908152604080832088820151845290915290205460ff166002145b156154b4577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561548157600080fd5b505af1158015615495573d6000803e3d6000fd5b505084546154af92506001600160a01b03169050826130e4565b6154d2565b600283015483546154d2916001600160a01b039081169116836131dc565b6080880151855260058301546004840154600091906154f2908490613bec565b816154f957fe5b04905061550881876001614419565b6020870152600384015461551c90826130a1565b8b60020160008860026003811061552f57fe5b6020020151815260200190815260200160002060030181905550600360009054906101000a90046001600160a01b03166001600160a01b03166342dc858d8c60020160008960026003811061558057fe5b6020020151815260200190815260200160002060010160009054906101000a90046001600160a01b03168d60020160008a6002600381106155bd57fe5b60209081029190910151825281019190915260409081016000908120600201548b83015183516001600160e01b031960e088901b1681526001600160a01b03958616600482015294909116602485015260448401526064830187905260848301869052905160a48084019382900301818387803b15801561563d57600080fd5b505af1158015615651573d6000803e3d6000fd5b5050505050505050615670565b5061566a565b50615670565b50614fc2565b815115615956577f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12706001600160a01b031685604001516001600160a01b03161480156156e357506020858101516001600160a01b03166000908152600882526040808220898352909252205460ff166002145b15615781576001600160a01b037f0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf127016632e1a7d4d83600160200201516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561575557600080fd5b505af1158015615769573d6000803e3d6000fd5b5050865161577c92509050836001614d9c565b615795565b604085015185516157959190846001614dbb565b6005546001600160a01b0316156158425760055485516020808801516040808a015187840151825163152cf14360e31b81526001600160a01b03968716600482015293861660248501529085166044840152606483015251929093169263a9678a1892608480830193928290030181600087803b15801561581557600080fd5b505af1158015615829573d6000803e3d6000fd5b505050506040513d602081101561583f57600080fd5b50505b6020808301516040808801516001600160a01b03166000908152600b9093529091205461586e916130a1565b6040868101516001600160a01b039081166000908152600b6020908152838220949094556003548a825260028c81018652848320600181015491015495880151885186516342dc858d60e01b815292861660048401529685166024830152604482018d905260648201526084810195909552925192909116926342dc858d9260a4808301939282900301818387803b15801561590957600080fd5b505af115801561591d573d6000803e3d6000fd5b505050506159418260006003811061593157fe5b60200201516080870151906130a1565b60008781526002890160205260409020600301555b50505050505050565b600080826001600160a01b0316846001600160a01b031610615982578284615985565b83835b909590945092505050565b600080846103e56159a96103e86149528a818a8a613bec565b816159b057fe5b04816159b857fe5b049050600063ec477c746159d261230d6149528880613bec565b816159d957fe5b04905060006159f06159eb8484613484565b615b0b565b905060006107ca615a03886107cd613bec565b81615a0a57fe5b04905080821115615a3157615a2a6001615a2484846130a1565b90613484565b9450615a36565b600094505b50505050949350505050565b60006127e06103e56142ea6103e861495286608001516142ea88606001518960a00151613bec90919063ffffffff16565b6000808211615aaf576040805162461bcd60e51b81526020600482015260036024820152623234bb60e91b604482015290519081900360640190fd5b6000828481615aba57fe5b04949350505050565b600080615ad2856103e5613bec565b90506000615ae08285613bec565b90506000615af483615a24886103e8613bec565b9050808281615aff57fe5b04979650505050505050565b60006003821115615b4e575080600160028204015b81811015615b4857809150600281828581615b3757fe5b040181615b4057fe5b049050615b20565b50611ed4565b8115611ed45750600191905056fe5472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b20415050524f56455f4641494c45445265656e7472616e637947756172643a207265656e7472616e742063616c6c005472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f4641494c45445472616e7366657248656c7065723a204d7954726164654f72646572426f6f6b205452414e534645525f46524f4d5f4641494c4544a2646970667358221220897532e588292b1fee078ed1f909ed34dfe9d24c1a3fbf6b86c72e1045574e7064736f6c63430007060033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12700000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b2

-----Decoded View---------------
Arg [0] : _WETH (address): 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270
Arg [1] : _uniswapV2Factory (address): 0x3EE4154c7F42D94e1092ad8cE5debb4B743ed0B2

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270
Arg [1] : 0000000000000000000000003ee4154c7f42d94e1092ad8ce5debb4b743ed0b2


Block Transaction 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
[ 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.