POL Price: $0.124011 (-2.56%)
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 POL

POL Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Add Order With E...821007832026-01-25 6:12:181 hr ago1769321538IN
0x5D36b36c...e25Bd888B
130 POL0.0154820134.41509743
Add Order With E...821006832026-01-25 6:08:582 hrs ago1769321338IN
0x5D36b36c...e25Bd888B
120 POL0.0155328734.52816437
Add Order With E...821006042026-01-25 6:06:202 hrs ago1769321180IN
0x5D36b36c...e25Bd888B
120 POL0.015732734.97237196
Add Order With E...821004832026-01-25 6:02:182 hrs ago1769320938IN
0x5D36b36c...e25Bd888B
120 POL0.0159102635.36706979
Add Order With E...821003932026-01-25 5:59:182 hrs ago1769320758IN
0x5D36b36c...e25Bd888B
110 POL0.0160686835.71923276
Add Order With E...821003252026-01-25 5:57:022 hrs ago1769320622IN
0x5D36b36c...e25Bd888B
100 POL0.0170097337.81108608
Add Order With E...821002062026-01-25 5:53:042 hrs ago1769320384IN
0x5D36b36c...e25Bd888B
85 POL0.0189202542.05801298
Add Order With E...820999622026-01-25 5:44:562 hrs ago1769319896IN
0x5D36b36c...e25Bd888B
75 POL0.0190584442.36518947
Add Order With E...820978102026-01-25 4:33:123 hrs ago1769315592IN
0x5D36b36c...e25Bd888B
65 POL0.0387054286.03862233
Add Order With E...820977452026-01-25 4:31:023 hrs ago1769315462IN
0x5D36b36c...e25Bd888B
57 POL0.0360696580.17955528
Add Order With E...820976642026-01-25 4:28:203 hrs ago1769315300IN
0x5D36b36c...e25Bd888B
47 POL0.0309413168.77972222
Add Order With E...820968252026-01-25 4:00:224 hrs ago1769313622IN
0x5D36b36c...e25Bd888B
39 POL0.0303179467.39403436
Add Order With E...820962692026-01-25 3:41:504 hrs ago1769312510IN
0x5D36b36c...e25Bd888B
32 POL0.04938424109.77667328
Add Order With E...820960492026-01-25 3:34:304 hrs ago1769312070IN
0x5D36b36c...e25Bd888B
25 POL0.07182032159.65003587
Add Order With E...820958052026-01-25 3:26:224 hrs ago1769311582IN
0x5D36b36c...e25Bd888B
21 POL0.0442000198.25261291
Add Order With E...820954712026-01-25 3:15:144 hrs ago1769310914IN
0x5D36b36c...e25Bd888B
8 POL0.05634541125.25071713
Add Order With E...820954002026-01-25 3:12:524 hrs ago1769310772IN
0x5D36b36c...e25Bd888B
3 POL0.05481689126.66782412
Add Order With E...820952582026-01-25 3:08:085 hrs ago1769310488IN
0x5D36b36c...e25Bd888B
43 POL0.04775528106.15565045
Add Order With E...820950382026-01-25 3:00:485 hrs ago1769310048IN
0x5D36b36c...e25Bd888B
67 POL0.05129498114.02406788
Add Order With E...820949452026-01-25 2:57:425 hrs ago1769309862IN
0x5D36b36c...e25Bd888B
51 POL0.0445546699.04097004
Add Order With E...820947652026-01-25 2:51:425 hrs ago1769309502IN
0x5D36b36c...e25Bd888B
39 POL0.0409060787.60061847
Add Order With E...820912542026-01-25 0:54:407 hrs ago1769302480IN
0x5D36b36c...e25Bd888B
0.1 POL0.05377337115.18292675
Add Order For ET...820253472026-01-23 12:17:4643 hrs ago1769170666IN
0x5D36b36c...e25Bd888B
0 POL0.1312788245.4759166
Add Order For ET...819883122026-01-22 15:43:162 days ago1769096596IN
0x5D36b36c...e25Bd888B
0 POL0.2298418499.72128553
Add Order With E...819838142026-01-22 13:13:202 days ago1769087600IN
0x5D36b36c...e25Bd888B
67 POL0.3039072600
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
821007832026-01-25 6:12:181 hr ago1769321538
0x5D36b36c...e25Bd888B
130 POL
821006832026-01-25 6:08:582 hrs ago1769321338
0x5D36b36c...e25Bd888B
120 POL
821006042026-01-25 6:06:202 hrs ago1769321180
0x5D36b36c...e25Bd888B
120 POL
821004832026-01-25 6:02:182 hrs ago1769320938
0x5D36b36c...e25Bd888B
120 POL
821003932026-01-25 5:59:182 hrs ago1769320758
0x5D36b36c...e25Bd888B
110 POL
821003252026-01-25 5:57:022 hrs ago1769320622
0x5D36b36c...e25Bd888B
100 POL
821002062026-01-25 5:53:042 hrs ago1769320384
0x5D36b36c...e25Bd888B
85 POL
820999622026-01-25 5:44:562 hrs ago1769319896
0x5D36b36c...e25Bd888B
75 POL
820978102026-01-25 4:33:123 hrs ago1769315592
0x5D36b36c...e25Bd888B
65 POL
820977452026-01-25 4:31:023 hrs ago1769315462
0x5D36b36c...e25Bd888B
57 POL
820976642026-01-25 4:28:203 hrs ago1769315300
0x5D36b36c...e25Bd888B
47 POL
820968252026-01-25 4:00:224 hrs ago1769313622
0x5D36b36c...e25Bd888B
39 POL
820962692026-01-25 3:41:504 hrs ago1769312510
0x5D36b36c...e25Bd888B
32 POL
820960492026-01-25 3:34:304 hrs ago1769312070
0x5D36b36c...e25Bd888B
25 POL
820958052026-01-25 3:26:224 hrs ago1769311582
0x5D36b36c...e25Bd888B
21 POL
820954712026-01-25 3:15:144 hrs ago1769310914
0x5D36b36c...e25Bd888B
8 POL
820954002026-01-25 3:12:524 hrs ago1769310772
0x5D36b36c...e25Bd888B
3 POL
820952582026-01-25 3:08:085 hrs ago1769310488
0x5D36b36c...e25Bd888B
43 POL
820950382026-01-25 3:00:485 hrs ago1769310048
0x5D36b36c...e25Bd888B
67 POL
820949452026-01-25 2:57:425 hrs ago1769309862
0x5D36b36c...e25Bd888B
51 POL
820947652026-01-25 2:51:425 hrs ago1769309502
0x5D36b36c...e25Bd888B
39 POL
820912542026-01-25 0:54:407 hrs ago1769302480
0x5D36b36c...e25Bd888B
0.1 POL
820253472026-01-23 12:17:4643 hrs ago1769170666
0x5D36b36c...e25Bd888B
57.92932371 POL
820253472026-01-23 12:17:4643 hrs ago1769170666
0x5D36b36c...e25Bd888B
57.92932371 POL
819883122026-01-22 15:43:162 days ago1769096596
0x5D36b36c...e25Bd888B
9.45472757 POL
View All Internal Transactions
Cross-Chain 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

API
[{"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
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

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

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