false
true
0

Contract Address Details

0x71bb8a2feD36aa2dEa9f8f9Cb43E038315Dd7ba3

Contract Name
Router02
Creator
0xc92879–2db706 at 0xdaa2fa–b5cdca
Balance
0 PLS ( )
Tokens
Fetching tokens...
Transactions
233,815 Transactions
Transfers
0 Transfers
Gas Used
0
Last Balance Update
25964950
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
Router02




Optimization enabled
true
Compiler version
v0.6.12+commit.27d51765




Optimization runs
200
EVM Version
default




Verified at
2023-06-08T06:20:46.751521Z

Constructor Arguments

0x000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27

Arg [0] (address) : 0xe2332e5297b18a21dce0e6ac461e821c353a00ca
Arg [1] (address) : 0xa1077a294dde1b09bb078844df40758a5d0f9a27

              

Contract source code

// SPDX-License-Identifier: MIT

pragma solidity >=0.5.0;

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

    function name() external pure returns (string memory);

    function symbol() external pure returns (string memory);

    function decimals() external pure returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

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

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function PERMIT_TYPEHASH() external pure returns (bytes32);

    function nonces(address owner) external view returns (uint256);

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

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

    function MINIMUM_LIQUIDITY() external pure returns (uint256);

    function factory() external view returns (address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    function price0CumulativeLast() external view returns (uint256);

    function price1CumulativeLast() external view returns (uint256);

    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);

    function burn(address to)
        external
        returns (uint256 amount0, uint256 amount1);

    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to,
        bytes calldata data
    ) external;

    function skim(address to) external;

    function sync() external;

    function initialize(address, address) external;
}

// File: contracts/trader/libraries/SafeMath.sol

pragma solidity =0.6.12;

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)

library SafeMath {
    function add(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x + y) >= x, "ds-math-add-overflow");
    }

    function sub(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require((z = x - y) <= x, "ds-math-sub-underflow");
    }

    function mul(uint256 x, uint256 y) internal pure returns (uint256 z) {
        require(y == 0 || (z = x * y) / y == x, "ds-math-mul-overflow");
    }
}

// File: contracts/trader/libraries/Library.sol

pragma solidity >=0.5.0;

library Library {
    using SafeMath for uint256;

    // returns sorted token addresses, used to handle return values from pairs sorted in this order
    function sortTokens(address tokenA, address tokenB)
        internal
        pure
        returns (address token0, address token1)
    {
        require(tokenA != tokenB, "Library: IDENTICAL_ADDRESSES");
        (token0, token1) = tokenA < tokenB
            ? (tokenA, tokenB)
            : (tokenB, tokenA);
        require(token0 != address(0), "Library: ZERO_ADDRESS");
    }

    // calculates the CREATE2 address for a pair without making any external calls
    function pairFor(
        address factory,
        address tokenA,
        address tokenB
    ) internal pure returns (address pair) {
        (address token0, address token1) = sortTokens(tokenA, tokenB);
        pair = address(
            uint256(
                keccak256(
                    abi.encodePacked(
                        hex"ff",
                        factory,
                        keccak256(abi.encodePacked(token0, token1)),
                        hex"62c6f1e729f434ea3a6205faad8316f45062b0eeaa3935ef181ebc0d3cf298de"
                    )
                )
            )
        );
    }

    // fetches and sorts the reserves for a pair
    function getReserves(
        address factory,
        address tokenA,
        address tokenB
    ) internal view returns (uint256 reserveA, uint256 reserveB) {
        (address token0, ) = sortTokens(tokenA, tokenB);
        (uint256 reserve0, uint256 reserve1, ) = IPair(
            pairFor(factory, tokenA, tokenB)
        ).getReserves();
        (reserveA, reserveB) = tokenA == token0
            ? (reserve0, reserve1)
            : (reserve1, reserve0);
    }

    // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) internal pure returns (uint256 amountB) {
        require(amountA > 0, "Library: INSUFFICIENT_AMOUNT");
        require(
            reserveA > 0 && reserveB > 0,
            "Library: INSUFFICIENT_LIQUIDITY"
        );
        amountB = amountA.mul(reserveB) / reserveA;
    }

    // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256 amountOut) {
        require(amountIn > 0, "Library: INSUFFICIENT_INPUT_AMOUNT");
        require(
            reserveIn > 0 && reserveOut > 0,
            "Library: INSUFFICIENT_LIQUIDITY"
        );
        uint256 amountInWithFee = amountIn.mul(997);
        uint256 numerator = amountInWithFee.mul(reserveOut);
        uint256 denominator = reserveIn.mul(1000).add(amountInWithFee);
        amountOut = numerator / denominator;
    }

    // given an output amount of an asset and pair reserves, returns a required input amount of the other asset
    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256 amountIn) {
        require(amountOut > 0, "Library: INSUFFICIENT_OUTPUT_AMOUNT");
        require(
            reserveIn > 0 && reserveOut > 0,
            "Library: INSUFFICIENT_LIQUIDITY"
        );
        uint256 numerator = reserveIn.mul(amountOut).mul(1000);
        uint256 denominator = reserveOut.sub(amountOut).mul(997);
        amountIn = (numerator / denominator).add(1);
    }

    // performs chained getAmountOut calculations on any number of pairs
    function getAmountsOut(
        address factory,
        uint256 amountIn,
        address[] memory path
    ) internal view returns (uint256[] memory amounts) {
        require(path.length >= 2, "Library: INVALID_PATH");
        amounts = new uint256[](path.length);
        amounts[0] = amountIn;
        for (uint256 i; i < path.length - 1; i++) {
            (uint256 reserveIn, uint256 reserveOut) = getReserves(
                factory,
                path[i],
                path[i + 1]
            );
            amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
        }
    }

    // performs chained getAmountIn calculations on any number of pairs
    function getAmountsIn(
        address factory,
        uint256 amountOut,
        address[] memory path
    ) internal view returns (uint256[] memory amounts) {
        require(path.length >= 2, "Library: INVALID_PATH");
        amounts = new uint256[](path.length);
        amounts[amounts.length - 1] = amountOut;
        for (uint256 i = path.length - 1; i > 0; i--) {
            (uint256 reserveIn, uint256 reserveOut) = getReserves(
                factory,
                path[i - 1],
                path[i]
            );
            amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
        }
    }
}

// File: contracts/trader/libraries/TransferHelper.sol

pragma solidity >=0.6.0;

// 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,
        uint256 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: APPROVE_FAILED"
        );
    }

    function safeTransfer(
        address token,
        address to,
        uint256 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: TRANSFER_FAILED"
        );
    }

    function safeTransferFrom(
        address token,
        address from,
        address to,
        uint256 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: TRANSFER_FROM_FAILED"
        );
    }

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

pragma solidity >=0.5.0;

interface IFactory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint256
    );

    function feeTo() external view returns (address);

    function feeToSetter() external view returns (address);

    function migrator() external view returns (address);

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

    function allPairs(uint256) external view returns (address pair);

    function allPairsLength() external view returns (uint256);

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

    function setFeeTo(address) external;

    function setFeeToSetter(address) external;

    function setMigrator(address) external;
}

pragma solidity >=0.6.2;

interface IRouter01 {
    function factory() external pure returns (address);

    function WETH() external pure returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        );

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountToken, uint256 amountETH);

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountA, uint256 amountB);

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH);

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable returns (uint256[] memory amounts);

    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) external pure returns (uint256 amountB);

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountOut);

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) external pure returns (uint256 amountIn);

    function getAmountsOut(uint256 amountIn, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);

    function getAmountsIn(uint256 amountOut, address[] calldata path)
        external
        view
        returns (uint256[] memory amounts);
}

// File: contracts/trader/interfaces/IRouter02.sol

pragma solidity >=0.6.2;

interface IRouter02 is IRouter01 {
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountETH);

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountETH);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;
}

// File: contracts/trader/interfaces/IFactory.sol

pragma solidity >=0.5.0;

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

    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender)
        external
        view
        returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);

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

    function transferFrom(
        address from,
        address to,
        uint256 value
    ) external returns (bool);
}

// File: contracts/trader/interfaces/IWETH.sol

pragma solidity >=0.5.0;

interface IWETH {
    function deposit() external payable;

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

    function withdraw(uint256) external;
}

// File: contracts/trader/Router02.sol

pragma solidity =0.6.12;

contract Router02 is IRouter02 {
    using SafeMath for uint256;

    address public immutable override factory;
    address public immutable override WETH;
    mapping(address => bool) public whitelist;
    address public admin;


    modifier ensure(uint256 deadline) {
        require(deadline >= block.timestamp, "Router: EXPIRED");
        _;
    }

    modifier onlyWalletWhitelist() {
        require(isContract(msg.sender) == false || whitelist[msg.sender] == true, "Only wallet and whitelist addresses can call this function");
        _;
    }

    modifier onlyAdmin() {
        require(msg.sender == admin, "Only the contract owner can call this function");
        _;
    }


    function setWhitelist(address addr) public onlyAdmin {
        whitelist[addr] = true;
    }
    
    function transferAdmin(address newAdmin) public onlyAdmin {
        require(newAdmin != address(0), "Invalid new owner address");
        admin = newAdmin;
    }


    constructor(address _factory, address _WETH) public {
        factory = _factory;
        WETH = _WETH;
        admin = msg.sender;
    }

    receive() external payable {
        assert(msg.sender == WETH); // only accept ETH via fallback from the WETH contract
    }

    function isContract(address addr) private view returns (bool) {
        uint size;
        assembly {
            size := extcodesize(addr)
        }
        return size > 0;
    }

    // **** ADD LIQUIDITY ****
    function _addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin
    ) internal virtual returns (uint256 amountA, uint256 amountB) {
        // create the pair if it doesn't exist yet
        if (IFactory(factory).getPair(tokenA, tokenB) == address(0)) {
            IFactory(factory).createPair(tokenA, tokenB);
        }
        (uint256 reserveA, uint256 reserveB) = Library.getReserves(
            factory,
            tokenA,
            tokenB
        );
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint256 amountBOptimal = Library.quote(
                amountADesired,
                reserveA,
                reserveB
            );
            if (amountBOptimal <= amountBDesired) {
                require(
                    amountBOptimal >= amountBMin,
                    "Router: INSUFFICIENT_B_AMOUNT"
                );
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint256 amountAOptimal = Library.quote(
                    amountBDesired,
                    reserveB,
                    reserveA
                );
                assert(amountAOptimal <= amountADesired);
                require(
                    amountAOptimal >= amountAMin,
                    "Router: INSUFFICIENT_A_AMOUNT"
                );
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        external
        virtual
        override
        ensure(deadline)
        returns (
            uint256 amountA,
            uint256 amountB,
            uint256 liquidity
        )
    {
        (amountA, amountB) = _addLiquidity(
            tokenA,
            tokenB,
            amountADesired,
            amountBDesired,
            amountAMin,
            amountBMin
        );
        address pair = Library.pairFor(factory, tokenA, tokenB);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
        liquidity = IPair(pair).mint(to);
    }

    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        virtual
        override
        ensure(deadline)
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        )
    {
        (amountToken, amountETH) = _addLiquidity(
            token,
            WETH,
            amountTokenDesired,
            msg.value,
            amountTokenMin,
            amountETHMin
        );
        address pair = Library.pairFor(factory, token, WETH);
        TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
        IWETH(WETH).deposit{value: amountETH}();
        assert(IWETH(WETH).transfer(pair, amountETH));
        liquidity = IPair(pair).mint(to);
        // refund dust eth, if any
        if (msg.value > amountETH)
            TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
    }

    // **** REMOVE LIQUIDITY ****
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    )
        public
        virtual
        override
        ensure(deadline)
        returns (uint256 amountA, uint256 amountB)
    {
        address pair = Library.pairFor(factory, tokenA, tokenB);
        IPair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair
        (uint256 amount0, uint256 amount1) = IPair(pair).burn(to);
        (address token0, ) = Library.sortTokens(tokenA, tokenB);
        (amountA, amountB) = tokenA == token0
            ? (amount0, amount1)
            : (amount1, amount0);
        require(amountA >= amountAMin, "Router: INSUFFICIENT_A_AMOUNT");
        require(amountB >= amountBMin, "Router: INSUFFICIENT_B_AMOUNT");
    }

    function removeLiquidityETH(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        public
        virtual
        override
        ensure(deadline)
        returns (uint256 amountToken, uint256 amountETH)
    {
        (amountToken, amountETH) = removeLiquidity(
            token,
            WETH,
            liquidity,
            amountTokenMin,
            amountETHMin,
            address(this),
            deadline
        );
        TransferHelper.safeTransfer(token, to, amountToken);
        IWETH(WETH).withdraw(amountETH);
        TransferHelper.safeTransferETH(to, amountETH);
    }

    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override returns (uint256 amountA, uint256 amountB) {
        address pair = Library.pairFor(factory, tokenA, tokenB);
        uint256 value = approveMax ? uint256(-1) : liquidity;
        IPair(pair).permit(
            msg.sender,
            address(this),
            value,
            deadline,
            v,
            r,
            s
        );
        (amountA, amountB) = removeLiquidity(
            tokenA,
            tokenB,
            liquidity,
            amountAMin,
            amountBMin,
            to,
            deadline
        );
    }

    function removeLiquidityETHWithPermit(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    )
        external
        virtual
        override
        returns (uint256 amountToken, uint256 amountETH)
    {
        address pair = Library.pairFor(factory, token, WETH);
        uint256 value = approveMax ? uint256(-1) : liquidity;
        IPair(pair).permit(
            msg.sender,
            address(this),
            value,
            deadline,
            v,
            r,
            s
        );
        (amountToken, amountETH) = removeLiquidityETH(
            token,
            liquidity,
            amountTokenMin,
            amountETHMin,
            to,
            deadline
        );
    }

    // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens) ****
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) public virtual override ensure(deadline) returns (uint256 amountETH) {
        (, amountETH) = removeLiquidity(
            token,
            WETH,
            liquidity,
            amountTokenMin,
            amountETHMin,
            address(this),
            deadline
        );
        TransferHelper.safeTransfer(
            token,
            to,
            IERC20(token).balanceOf(address(this))
        );
        IWETH(WETH).withdraw(amountETH);
        TransferHelper.safeTransferETH(to, amountETH);
    }

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external virtual override returns (uint256 amountETH) {
        address pair = Library.pairFor(factory, token, WETH);
        uint256 value = approveMax ? uint256(-1) : liquidity;
        IPair(pair).permit(
            msg.sender,
            address(this),
            value,
            deadline,
            v,
            r,
            s
        );
        amountETH = removeLiquidityETHSupportingFeeOnTransferTokens(
            token,
            liquidity,
            amountTokenMin,
            amountETHMin,
            to,
            deadline
        );
    }

    // **** SWAP ****
    // requires the initial amount to have already been sent to the first pair
    function _swap(
        uint256[] memory amounts,
        address[] memory path,
        address _to
    ) internal virtual {
        for (uint256 i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0, ) = Library.sortTokens(input, output);
            uint256 amountOut = amounts[i + 1];
            (uint256 amount0Out, uint256 amount1Out) = input == token0
                ? (uint256(0), amountOut)
                : (amountOut, uint256(0));
            address to = i < path.length - 2
                ? Library.pairFor(factory, output, path[i + 2])
                : _to;
            IPair(Library.pairFor(factory, input, output)).swap(
                amount0Out,
                amount1Out,
                to,
                new bytes(0)
            );
        }
    }

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    )
        external
        virtual
        override
        onlyWalletWhitelist
        ensure(deadline)
        returns (uint256[] memory amounts)
    {
        amounts = Library.getAmountsOut(factory, amountIn, path);
        require(
            amounts[amounts.length - 1] >= amountOutMin,
            "Router: INSUFFICIENT_OUTPUT_AMOUNT"
        );
        TransferHelper.safeTransferFrom(
            path[0],
            msg.sender,
            Library.pairFor(factory, path[0], path[1]),
            amounts[0]
        );
        _swap(amounts, path, to);
    }

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    )
        external
        virtual
        override
        onlyWalletWhitelist
        ensure(deadline)
        returns (uint256[] memory amounts)
    {
        amounts = Library.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= amountInMax, "Router: EXCESSIVE_INPUT_AMOUNT");
        TransferHelper.safeTransferFrom(
            path[0],
            msg.sender,
            Library.pairFor(factory, path[0], path[1]),
            amounts[0]
        );
        _swap(amounts, path, to);
    }

    function swapExactETHForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    )
        external
        payable
        virtual
        override
        onlyWalletWhitelist
        ensure(deadline)
        returns (uint256[] memory amounts)
    {
        require(path[0] == WETH, "Router: INVALID_PATH");
        amounts = Library.getAmountsOut(factory, msg.value, path);
        require(
            amounts[amounts.length - 1] >= amountOutMin,
            "Router: INSUFFICIENT_OUTPUT_AMOUNT"
        );
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(
            IWETH(WETH).transfer(
                Library.pairFor(factory, path[0], path[1]),
                amounts[0]
            )
        );
        _swap(amounts, path, to);
    }

    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    )
        external
        virtual
        override
        onlyWalletWhitelist
        ensure(deadline)
        returns (uint256[] memory amounts)
    {
        require(path[path.length - 1] == WETH, "Router: INVALID_PATH");
        amounts = Library.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= amountInMax, "Router: EXCESSIVE_INPUT_AMOUNT");
        TransferHelper.safeTransferFrom(
            path[0],
            msg.sender,
            Library.pairFor(factory, path[0], path[1]),
            amounts[0]
        );
        _swap(amounts, path, address(this));
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
    }

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    )
        external
        virtual
        override
        onlyWalletWhitelist
        ensure(deadline)
        returns (uint256[] memory amounts)
    {
        require(path[path.length - 1] == WETH, "Router: INVALID_PATH");
        amounts = Library.getAmountsOut(factory, amountIn, path);
        require(
            amounts[amounts.length - 1] >= amountOutMin,
            "Router: INSUFFICIENT_OUTPUT_AMOUNT"
        );
        TransferHelper.safeTransferFrom(
            path[0],
            msg.sender,
            Library.pairFor(factory, path[0], path[1]),
            amounts[0]
        );
        _swap(amounts, path, address(this));
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
    }

    function swapETHForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    )
        external
        payable
        virtual
        override
        onlyWalletWhitelist
        ensure(deadline)
        returns (uint256[] memory amounts)
    {
        require(path[0] == WETH, "Router: INVALID_PATH");
        amounts = Library.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= msg.value, "Router: EXCESSIVE_INPUT_AMOUNT");
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(
            IWETH(WETH).transfer(
                Library.pairFor(factory, path[0], path[1]),
                amounts[0]
            )
        );
        _swap(amounts, path, to);
        // refund dust eth, if any
        if (msg.value > amounts[0])
            TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]);
    }

    // **** SWAP (supporting fee-on-transfer tokens) ****
    // requires the initial amount to have already been sent to the first pair
    function _swapSupportingFeeOnTransferTokens(
        address[] memory path,
        address _to
    ) internal virtual {
        for (uint256 i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0, ) = Library.sortTokens(input, output);
            IPair pair = IPair(
                Library.pairFor(factory, input, output)
            );
            uint256 amountInput;
            uint256 amountOutput;
            {
                // scope to avoid stack too deep errors
                (uint256 reserve0, uint256 reserve1, ) = pair.getReserves();
                (uint256 reserveInput, uint256 reserveOutput) = input == token0
                    ? (reserve0, reserve1)
                    : (reserve1, reserve0);
                amountInput = IERC20(input).balanceOf(address(pair)).sub(
                    reserveInput
                );
                amountOutput = Library.getAmountOut(
                    amountInput,
                    reserveInput,
                    reserveOutput
                );
            }
            (uint256 amount0Out, uint256 amount1Out) = input == token0
                ? (uint256(0), amountOutput)
                : (amountOutput, uint256(0));
            address to = i < path.length - 2
                ? Library.pairFor(factory, output, path[i + 2])
                : _to;
            pair.swap(amount0Out, amount1Out, to, new bytes(0));
        }
    }

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override onlyWalletWhitelist ensure(deadline) {
        TransferHelper.safeTransferFrom(
            path[0],
            msg.sender,
            Library.pairFor(factory, path[0], path[1]),
            amountIn
        );
        uint256 balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(path, to);
        require(
            IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >=
                amountOutMin,
            "Router: INSUFFICIENT_OUTPUT_AMOUNT"
        );
    }

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable virtual override onlyWalletWhitelist ensure(deadline) {
        require(path[0] == WETH, "Router: INVALID_PATH");
        uint256 amountIn = msg.value;
        IWETH(WETH).deposit{value: amountIn}();
        assert(
            IWETH(WETH).transfer(
                Library.pairFor(factory, path[0], path[1]),
                amountIn
            )
        );
        uint256 balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(path, to);
        require(
            IERC20(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >=
                amountOutMin,
            "Router: INSUFFICIENT_OUTPUT_AMOUNT"
        );
    }

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external virtual override onlyWalletWhitelist ensure(deadline) {
        require(path[path.length - 1] == WETH, "Router: INVALID_PATH");
        TransferHelper.safeTransferFrom(
            path[0],
            msg.sender,
            Library.pairFor(factory, path[0], path[1]),
            amountIn
        );
        _swapSupportingFeeOnTransferTokens(path, address(this));
        uint256 amountOut = IERC20(WETH).balanceOf(address(this));
        require(
            amountOut >= amountOutMin,
            "Router: INSUFFICIENT_OUTPUT_AMOUNT"
        );
        IWETH(WETH).withdraw(amountOut);
        TransferHelper.safeTransferETH(to, amountOut);
    }

    // **** LIBRARY FUNCTIONS ****
    function quote(
        uint256 amountA,
        uint256 reserveA,
        uint256 reserveB
    ) public pure virtual override returns (uint256 amountB) {
        return Library.quote(amountA, reserveA, reserveB);
    }

    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) public pure virtual override returns (uint256 amountOut) {
        return Library.getAmountOut(amountIn, reserveIn, reserveOut);
    }

    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) public pure virtual override returns (uint256 amountIn) {
        return Library.getAmountIn(amountOut, reserveIn, reserveOut);
    }

    function getAmountsOut(uint256 amountIn, address[] memory path)
        public
        view
        virtual
        override
        returns (uint256[] memory amounts)
    {
        return Library.getAmountsOut(factory, amountIn, path);
    }

    function getAmountsIn(uint256 amountOut, address[] memory path)
        public
        view
        virtual
        override
        returns (uint256[] memory amounts)
    {
        return Library.getAmountsIn(factory, amountOut, path);
    }
}
        

Contract ABI

[{"type":"constructor","inputs":[{"type":"address","name":"_factory","internalType":"address"},{"type":"address","name":"_WETH","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"WETH","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountA","internalType":"uint256"},{"type":"uint256","name":"amountB","internalType":"uint256"},{"type":"uint256","name":"liquidity","internalType":"uint256"}],"name":"addLiquidity","inputs":[{"type":"address","name":"tokenA","internalType":"address"},{"type":"address","name":"tokenB","internalType":"address"},{"type":"uint256","name":"amountADesired","internalType":"uint256"},{"type":"uint256","name":"amountBDesired","internalType":"uint256"},{"type":"uint256","name":"amountAMin","internalType":"uint256"},{"type":"uint256","name":"amountBMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256","name":"amountToken","internalType":"uint256"},{"type":"uint256","name":"amountETH","internalType":"uint256"},{"type":"uint256","name":"liquidity","internalType":"uint256"}],"name":"addLiquidityETH","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amountTokenDesired","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"admin","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"factory","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"}],"name":"getAmountIn","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint256","name":"reserveIn","internalType":"uint256"},{"type":"uint256","name":"reserveOut","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"}],"name":"getAmountOut","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"reserveIn","internalType":"uint256"},{"type":"uint256","name":"reserveOut","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"getAmountsIn","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"getAmountsOut","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"uint256","name":"amountB","internalType":"uint256"}],"name":"quote","inputs":[{"type":"uint256","name":"amountA","internalType":"uint256"},{"type":"uint256","name":"reserveA","internalType":"uint256"},{"type":"uint256","name":"reserveB","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountA","internalType":"uint256"},{"type":"uint256","name":"amountB","internalType":"uint256"}],"name":"removeLiquidity","inputs":[{"type":"address","name":"tokenA","internalType":"address"},{"type":"address","name":"tokenB","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountAMin","internalType":"uint256"},{"type":"uint256","name":"amountBMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountToken","internalType":"uint256"},{"type":"uint256","name":"amountETH","internalType":"uint256"}],"name":"removeLiquidityETH","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountETH","internalType":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountToken","internalType":"uint256"},{"type":"uint256","name":"amountETH","internalType":"uint256"}],"name":"removeLiquidityETHWithPermit","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"bool","name":"approveMax","internalType":"bool"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountETH","internalType":"uint256"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountTokenMin","internalType":"uint256"},{"type":"uint256","name":"amountETHMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"bool","name":"approveMax","internalType":"bool"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"amountA","internalType":"uint256"},{"type":"uint256","name":"amountB","internalType":"uint256"}],"name":"removeLiquidityWithPermit","inputs":[{"type":"address","name":"tokenA","internalType":"address"},{"type":"address","name":"tokenB","internalType":"address"},{"type":"uint256","name":"liquidity","internalType":"uint256"},{"type":"uint256","name":"amountAMin","internalType":"uint256"},{"type":"uint256","name":"amountBMin","internalType":"uint256"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"},{"type":"bool","name":"approveMax","internalType":"bool"},{"type":"uint8","name":"v","internalType":"uint8"},{"type":"bytes32","name":"r","internalType":"bytes32"},{"type":"bytes32","name":"s","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setWhitelist","inputs":[{"type":"address","name":"addr","internalType":"address"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapETHForExactTokens","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapExactETHForTokens","inputs":[{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"payable","outputs":[],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","inputs":[{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapExactTokensForETH","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapExactTokensForTokens","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","inputs":[{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint256","name":"amountOutMin","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapTokensForExactETH","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint256","name":"amountInMax","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256[]","name":"amounts","internalType":"uint256[]"}],"name":"swapTokensForExactTokens","inputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint256","name":"amountInMax","internalType":"uint256"},{"type":"address[]","name":"path","internalType":"address[]"},{"type":"address","name":"to","internalType":"address"},{"type":"uint256","name":"deadline","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferAdmin","inputs":[{"type":"address","name":"newAdmin","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"whitelist","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"receive"}]
              

Contract Creation Code

0x60c060405234801561001057600080fd5b5060405162004d8e38038062004d8e8339818101604052604081101561003557600080fd5b5080516020909101516001600160601b0319606092831b8116608052911b1660a052600180546001600160a01b0319163317905560805160601c60a05160601c614bf762000197600039806101cb5280610e165280610e515280610fb052806111d7528061163152806117b65280611cfb5280611ddf5280611eb95280611fef528061213e52806121c652806125025280612581528061263552806127695280612807528061287b5280612d8e52806130005280613056528061308a52806130fe5280613303528061346552806134ed525080611047528061111e528061129d52806112d6528061147952806116c85280611794528061196c528061208b52806121f8528061242752806128ad5280612aef5280612d135280612d3c5280612d6c5280612edd5280613034528061339f528061351f5280613db95280613dfc52806140ce52806142445280614685528061473e52806147f15250614bf76000f3fe6080604052600436106101bb5760003560e01c80638803dbee116100ec578063c45a01551161008a578063e8e3370011610064578063e8e3370014610c66578063f305d71914610ce6578063f851a44014610d2c578063fb3bdb4114610d41576101f4565b8063c45a015514610b29578063d06ca61f14610b3e578063ded9382a14610bf3576101f4565b8063ad615dec116100c6578063ad615dec146109bf578063af2979eb146109f5578063b6f9de9514610a48578063baa2abde14610acc576101f4565b80638803dbee146108b15780639b19251a14610947578063ad5c46481461098e576101f4565b80635b0d598411610159578063791ac94711610133578063791ac9471461072e5780637ff36ab5146107c4578063854cff2f1461084857806385f8c2591461087b576101f4565b80635b0d5984146105f25780635c11d7951461066557806375829def146106fb576101f4565b80631f00ca74116101955780631f00ca74146103935780632195995c1461044857806338ed1739146104c65780634a25d94a1461055c576101f4565b806302751cec146101f9578063054d50d41461026557806318cbafe5146102ad576101f4565b366101f457336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101f257fe5b005b600080fd5b34801561020557600080fd5b5061024c600480360360c081101561021c57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135610dc5565b6040805192835260208301919091528051918290030190f35b34801561027157600080fd5b5061029b6004803603606081101561028857600080fd5b5080359060208101359060400135610ee3565b60408051918252519081900360200190f35b3480156102b957600080fd5b50610343600480360360a08110156102d057600080fd5b813591602081013591810190606081016040820135600160201b8111156102f657600080fd5b82018360208201111561030857600080fd5b803590602001918460208302840111600160201b8311171561032957600080fd5b91935091506001600160a01b038135169060200135610ef8565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561037f578181015183820152602001610367565b505050509050019250505060405180910390f35b34801561039f57600080fd5b50610343600480360360408110156103b657600080fd5b81359190810190604081016020820135600160201b8111156103d757600080fd5b8201836020820111156103e957600080fd5b803590602001918460208302840111600160201b8311171561040a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611296945050505050565b34801561045457600080fd5b5061024c600480360361016081101561046c57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c08101359060e081013515159060ff61010082013516906101208101359061014001356112cc565b3480156104d257600080fd5b50610343600480360360a08110156104e957600080fd5b813591602081013591810190606081016040820135600160201b81111561050f57600080fd5b82018360208201111561052157600080fd5b803590602001918460208302840111600160201b8311171561054257600080fd5b91935091506001600160a01b0381351690602001356113c6565b34801561056857600080fd5b50610343600480360360a081101561057f57600080fd5b813591602081013591810190606081016040820135600160201b8111156105a557600080fd5b8201836020820111156105b757600080fd5b803590602001918460208302840111600160201b831117156105d857600080fd5b91935091506001600160a01b038135169060200135611579565b3480156105fe57600080fd5b5061029b600480360361014081101561061657600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e0820135169061010081013590610120013561178c565b34801561067157600080fd5b506101f2600480360360a081101561068857600080fd5b813591602081013591810190606081016040820135600160201b8111156106ae57600080fd5b8201836020820111156106c057600080fd5b803590602001918460208302840111600160201b831117156106e157600080fd5b91935091506001600160a01b03813516906020013561189a565b34801561070757600080fd5b506101f26004803603602081101561071e57600080fd5b50356001600160a01b0316611b7f565b34801561073a57600080fd5b506101f2600480360360a081101561075157600080fd5b813591602081013591810190606081016040820135600160201b81111561077757600080fd5b82018360208201111561078957600080fd5b803590602001918460208302840111600160201b831117156107aa57600080fd5b91935091506001600160a01b038135169060200135611c45565b610343600480360360808110156107da57600080fd5b81359190810190604081016020820135600160201b8111156107fb57600080fd5b82018360208201111561080d57600080fd5b803590602001918460208302840111600160201b8311171561082e57600080fd5b91935091506001600160a01b038135169060200135611f3f565b34801561085457600080fd5b506101f26004803603602081101561086b57600080fd5b50356001600160a01b03166122fa565b34801561088757600080fd5b5061029b6004803603606081101561089e57600080fd5b5080359060208101359060400135612367565b3480156108bd57600080fd5b50610343600480360360a08110156108d457600080fd5b813591602081013591810190606081016040820135600160201b8111156108fa57600080fd5b82018360208201111561090c57600080fd5b803590602001918460208302840111600160201b8311171561092d57600080fd5b91935091506001600160a01b038135169060200135612374565b34801561095357600080fd5b5061097a6004803603602081101561096a57600080fd5b50356001600160a01b03166124eb565b604080519115158252519081900360200190f35b34801561099a57600080fd5b506109a3612500565b604080516001600160a01b039092168252519081900360200190f35b3480156109cb57600080fd5b5061029b600480360360608110156109e257600080fd5b5080359060208101359060400135612524565b348015610a0157600080fd5b5061029b600480360360c0811015610a1857600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135612531565b6101f260048036036080811015610a5e57600080fd5b81359190810190604081016020820135600160201b811115610a7f57600080fd5b820183602082011115610a9157600080fd5b803590602001918460208302840111600160201b83111715610ab257600080fd5b91935091506001600160a01b0381351690602001356126bb565b348015610ad857600080fd5b5061024c600480360360e0811015610aef57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c00135612a9d565b348015610b3557600080fd5b506109a3612d11565b348015610b4a57600080fd5b5061034360048036036040811015610b6157600080fd5b81359190810190604081016020820135600160201b811115610b8257600080fd5b820183602082011115610b9457600080fd5b803590602001918460208302840111600160201b83111715610bb557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612d35945050505050565b348015610bff57600080fd5b5061024c6004803603610140811015610c1757600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e08201351690610100810135906101200135612d62565b348015610c7257600080fd5b50610cc86004803603610100811015610c8a57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359160c0820135169060e00135612e76565b60408051938452602084019290925282820152519081900360600190f35b610cc8600480360360c0811015610cfc57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135612fad565b348015610d3857600080fd5b506109a3613244565b61034360048036036080811015610d5757600080fd5b81359190810190604081016020820135600160201b811115610d7857600080fd5b820183602082011115610d8a57600080fd5b803590602001918460208302840111600160201b83111715610dab57600080fd5b91935091506001600160a01b038135169060200135613253565b6000808242811015610e10576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b610e3f897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a612a9d565b9093509150610e4f898685613653565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610eb557600080fd5b505af1158015610ec9573d6000803e3d6000fd5b50505050610ed785836137bd565b50965096945050505050565b6000610ef08484846138b5565b949350505050565b6060610f03336139a3565b1580610f2357503360009081526020819052604090205460ff1615156001145b610f5e5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015610fa6576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001686866000198101818110610fe057fe5b905060200201356001600160a01b03166001600160a01b031614611042576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b6110a07f0000000000000000000000000000000000000000000000000000000000000000898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506139a992505050565b915086826001845103815181106110b357fe5b602002602001015110156110f85760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b6111968686600081811061110857fe5b905060200201356001600160a01b03163361117c7f00000000000000000000000000000000000000000000000000000000000000008a8a600081811061114a57fe5b905060200201356001600160a01b03168b8b600181811061116757fe5b905060200201356001600160a01b0316613aed565b8560008151811061118957fe5b6020026020010151613bad565b6111d582878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613d0a915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d8360018551038151811061121457fe5b60200260200101516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561125257600080fd5b505af1158015611266573d6000803e3d6000fd5b5050505061128b848360018551038151811061127e57fe5b60200260200101516137bd565b509695505050505050565b60606112c37f00000000000000000000000000000000000000000000000000000000000000008484613f47565b90505b92915050565b60008060006112fc7f00000000000000000000000000000000000000000000000000000000000000008f8f613aed565b905060008761130b578c61130f565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b15801561138557600080fd5b505af1158015611399573d6000803e3d6000fd5b505050506113ac8f8f8f8f8f8f8f612a9d565b809450819550505050509b509b9950505050505050505050565b60606113d1336139a3565b15806113f157503360009081526020819052604090205460ff1615156001145b61142c5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015611474576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6114d27f0000000000000000000000000000000000000000000000000000000000000000898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506139a992505050565b915086826001845103815181106114e557fe5b6020026020010151101561152a5760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b61153a8686600081811061110857fe5b61128b82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d0a915050565b6060611584336139a3565b15806115a457503360009081526020819052604090205460ff1615156001145b6115df5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015611627576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686600019810181811061166157fe5b905060200201356001600160a01b03166001600160a01b0316146116c3576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b6117217f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613f4792505050565b9150868260008151811061173157fe5b602002602001015111156110f8576040805162461bcd60e51b815260206004820152601e60248201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604482015290519081900360640190fd5b6000806117da7f00000000000000000000000000000000000000000000000000000000000000008d7f0000000000000000000000000000000000000000000000000000000000000000613aed565b90506000866117e9578b6117ed565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018b905260ff8916608482015260a4810188905260c4810187905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b15801561186357600080fd5b505af1158015611877573d6000803e3d6000fd5b505050506118898d8d8d8d8d8d612531565b9d9c50505050505050505050505050565b6118a3336139a3565b15806118c357503360009081526020819052604090205460ff1615156001145b6118fe5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8042811015611946576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6119bb8585600081811061195657fe5b905060200201356001600160a01b0316336119b57f00000000000000000000000000000000000000000000000000000000000000008989600081811061199857fe5b905060200201356001600160a01b03168a8a600181811061116757fe5b8a613bad565b6000858560001981018181106119cd57fe5b905060200201356001600160a01b03166001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611a2957600080fd5b505afa158015611a3d573d6000803e3d6000fd5b505050506040513d6020811015611a5357600080fd5b50516040805160208881028281018201909352888252929350611a95929091899189918291850190849080828437600092019190915250889250614077915050565b86611b388288886000198101818110611aaa57fe5b905060200201356001600160a01b03166001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611b0657600080fd5b505afa158015611b1a573d6000803e3d6000fd5b505050506040513d6020811015611b3057600080fd5b505190614379565b1015611b755760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b5050505050505050565b6001546001600160a01b03163314611bc85760405162461bcd60e51b815260040180806020018281038252602e815260200180614ace602e913960400191505060405180910390fd5b6001600160a01b038116611c23576040805162461bcd60e51b815260206004820152601960248201527f496e76616c6964206e6577206f776e6572206164647265737300000000000000604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b611c4e336139a3565b1580611c6e57503360009081526020819052604090205460ff1615156001145b611ca95760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8042811015611cf1576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001685856000198101818110611d2b57fe5b905060200201356001600160a01b03166001600160a01b031614611d8d576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b611d9d8585600081811061195657fe5b611ddb858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250614077915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611e4a57600080fd5b505afa158015611e5e573d6000803e3d6000fd5b505050506040513d6020811015611e7457600080fd5b5051905086811015611eb75760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611f1d57600080fd5b505af1158015611f31573d6000803e3d6000fd5b50505050611b7584826137bd565b6060611f4a336139a3565b1580611f6a57503360009081526020819052604090205460ff1615156001145b611fa55760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015611fed576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168686600081811061202457fe5b905060200201356001600160a01b03166001600160a01b031614612086576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b6120e47f0000000000000000000000000000000000000000000000000000000000000000348888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506139a992505050565b915086826001845103815181106120f757fe5b6020026020010151101561213c5760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061217857fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121ab57600080fd5b505af11580156121bf573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6122247f00000000000000000000000000000000000000000000000000000000000000008989600081811061199857fe5b8460008151811061223157fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561227f57600080fd5b505af1158015612293573d6000803e3d6000fd5b505050506040513d60208110156122a957600080fd5b50516122b157fe5b6122f082878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d0a915050565b5095945050505050565b6001546001600160a01b031633146123435760405162461bcd60e51b815260040180806020018281038252602e815260200180614ace602e913960400191505060405180910390fd5b6001600160a01b03166000908152602081905260409020805460ff19166001179055565b6000610ef08484846143c9565b606061237f336139a3565b158061239f57503360009081526020819052604090205460ff1615156001145b6123da5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015612422576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6124807f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613f4792505050565b9150868260008151811061249057fe5b6020026020010151111561152a576040805162461bcd60e51b815260206004820152601e60248201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604482015290519081900360640190fd5b60006020819052908152604090205460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610ef08484846144b7565b6000814281101561257b576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6125aa887f00000000000000000000000000000000000000000000000000000000000000008989893089612a9d565b90508092505061263388858a6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561260257600080fd5b505afa158015612616573d6000803e3d6000fd5b505050506040513d602081101561262c57600080fd5b5051613653565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561269957600080fd5b505af11580156126ad573d6000803e3d6000fd5b5050505061128b84836137bd565b6126c4336139a3565b15806126e457503360009081526020819052604090205460ff1615156001145b61271f5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8042811015612767576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168585600081811061279e57fe5b905060200201356001600160a01b03166001600160a01b031614612800576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b60003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561286057600080fd5b505af1158015612874573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6128d97f00000000000000000000000000000000000000000000000000000000000000008989600081811061199857fe5b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561292057600080fd5b505af1158015612934573d6000803e3d6000fd5b505050506040513d602081101561294a57600080fd5b505161295257fe5b60008686600019810181811061296457fe5b905060200201356001600160a01b03166001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156129c057600080fd5b505afa1580156129d4573d6000803e3d6000fd5b505050506040513d60208110156129ea57600080fd5b50516040805160208981028281018201909352898252929350612a2c9290918a918a918291850190849080828437600092019190915250899250614077915050565b87611b388289896000198101818110612a4157fe5b905060200201356001600160a01b03166001600160a01b03166370a08231896040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611b0657600080fd5b6000808242811015612ae8576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6000612b157f00000000000000000000000000000000000000000000000000000000000000008c8c613aed565b604080516323b872dd60e01b81523360048201526001600160a01b03831660248201819052604482018d9052915192935090916323b872dd916064808201926020929091908290030181600087803b158015612b7057600080fd5b505af1158015612b84573d6000803e3d6000fd5b505050506040513d6020811015612b9a57600080fd5b50506040805163226bf2d160e21b81526001600160a01b03888116600483015282516000938493928616926389afcb44926024808301939282900301818787803b158015612be757600080fd5b505af1158015612bfb573d6000803e3d6000fd5b505050506040513d6040811015612c1157600080fd5b50805160209091015190925090506000612c2b8e8e614589565b509050806001600160a01b03168e6001600160a01b031614612c4e578183612c51565b82825b90975095508a871015612cab576040805162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604482015290519081900360640190fd5b89861015612d00576040805162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604482015290519081900360640190fd5b505050505097509795505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60606112c37f000000000000000000000000000000000000000000000000000000000000000084846139a9565b6000806000612db27f00000000000000000000000000000000000000000000000000000000000000008e7f0000000000000000000000000000000000000000000000000000000000000000613aed565b9050600087612dc1578c612dc5565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b158015612e3b57600080fd5b505af1158015612e4f573d6000803e3d6000fd5b50505050612e618e8e8e8e8e8e610dc5565b909f909e509c50505050505050505050505050565b60008060008342811015612ec3576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b612ed18c8c8c8c8c8c614675565b90945092506000612f037f00000000000000000000000000000000000000000000000000000000000000008e8e613aed565b9050612f118d338388613bad565b612f1d8c338387613bad565b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015612f6c57600080fd5b505af1158015612f80573d6000803e3d6000fd5b505050506040513d6020811015612f9657600080fd5b5051949d939c50939a509198505050505050505050565b60008060008342811015612ffa576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6130288a7f00000000000000000000000000000000000000000000000000000000000000008b348c8c614675565b9094509250600061307a7f00000000000000000000000000000000000000000000000000000000000000008c7f0000000000000000000000000000000000000000000000000000000000000000613aed565b90506130888b338388613bad565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130e357600080fd5b505af11580156130f7573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb82866040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561317357600080fd5b505af1158015613187573d6000803e3d6000fd5b505050506040513d602081101561319d57600080fd5b50516131a557fe5b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b1580156131f457600080fd5b505af1158015613208573d6000803e3d6000fd5b505050506040513d602081101561321e57600080fd5b505192503484101561323657613236338534036137bd565b505096509650969350505050565b6001546001600160a01b031681565b606061325e336139a3565b158061327e57503360009081526020819052604090205460ff1615156001145b6132b95760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015613301576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168686600081811061333857fe5b905060200201356001600160a01b03166001600160a01b03161461339a576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b6133f87f000000000000000000000000000000000000000000000000000000000000000088888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613f4792505050565b9150348260008151811061340857fe5b60200260200101511115613463576040805162461bcd60e51b815260206004820152601e60248201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061349f57fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156134d257600080fd5b505af11580156134e6573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb61354b7f00000000000000000000000000000000000000000000000000000000000000008989600081811061199857fe5b8460008151811061355857fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156135a657600080fd5b505af11580156135ba573d6000803e3d6000fd5b505050506040513d60208110156135d057600080fd5b50516135d857fe5b61361782878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d0a915050565b8160008151811061362457fe5b60200260200101513411156122f0576122f0338360008151811061364457fe5b602002602001015134036137bd565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b602083106136d05780518252601f1990920191602091820191016136b1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613732576040519150601f19603f3d011682016040523d82523d6000602084013e613737565b606091505b5091509150818015613765575080511580613765575080806020019051602081101561376257600080fd5b50515b6137b6576040805162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b5050505050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106138095780518252601f1990920191602091820191016137ea565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461386b576040519150601f19603f3d011682016040523d82523d6000602084013e613870565b606091505b50509050806138b05760405162461bcd60e51b8152600401808060200182810382526023815260200180614b7b6023913960400191505060405180910390fd5b505050565b60008084116138f55760405162461bcd60e51b8152600401808060200182810382526022815260200180614aac6022913960400191505060405180910390fd5b6000831180156139055750600082115b613956576040805162461bcd60e51b815260206004820152601f60248201527f4c6962726172793a20494e53554646494349454e545f4c495155494449545900604482015290519081900360640190fd5b6000613964856103e5614932565b905060006139728285614932565b9050600061398c83613986886103e8614932565b90614995565b905080828161399757fe5b04979650505050505050565b3b151590565b60606002825110156139fa576040805162461bcd60e51b8152602060048201526015602482015274098d2c4e4c2e4f27440929cac82989288bea082a89605b1b604482015290519081900360640190fd5b815167ffffffffffffffff81118015613a1257600080fd5b50604051908082528060200260200182016040528015613a3c578160200160208202803683370190505b5090508281600081518110613a4d57fe5b60200260200101818152505060005b6001835103811015613ae557600080613a9f87868581518110613a7b57fe5b6020026020010151878660010181518110613a9257fe5b60200260200101516149e4565b91509150613ac1848481518110613ab257fe5b602002602001015183836138b5565b848460010181518110613ad057fe5b60209081029190910101525050600101613a5c565b509392505050565b6000806000613afc8585614589565b604080516bffffffffffffffffffffffff19606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501206001600160f81b031960688401529a90941b9093166069840152607d8301989098527f62c6f1e729f434ea3a6205faad8316f45062b0eeaa3935ef181ebc0d3cf298de609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b60208310613c325780518252601f199092019160209182019101613c13565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613c94576040519150601f19603f3d011682016040523d82523d6000602084013e613c99565b606091505b5091509150818015613cc7575080511580613cc75750808060200190516020811015613cc457600080fd5b50515b613d025760405162461bcd60e51b8152600401808060200182810382526024815260200180614b9e6024913960400191505060405180910390fd5b505050505050565b60005b6001835103811015613f4157600080848381518110613d2857fe5b6020026020010151858460010181518110613d3f57fe5b6020026020010151915091506000613d578383614589565b5090506000878560010181518110613d6b57fe5b60200260200101519050600080836001600160a01b0316866001600160a01b031614613d9957826000613d9d565b6000835b91509150600060028a51038810613db45788613df5565b613df57f0000000000000000000000000000000000000000000000000000000000000000878c8b60020181518110613de857fe5b6020026020010151613aed565b9050613e227f00000000000000000000000000000000000000000000000000000000000000008888613aed565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f191660200182016040528015613e5f576020820181803683370190505b506040518563ffffffff1660e01b815260040180858152602001848152602001836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613ec7578181015183820152602001613eaf565b50505050905090810190601f168015613ef45780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015613f1657600080fd5b505af1158015613f2a573d6000803e3d6000fd5b505060019099019850613d0d975050505050505050565b50505050565b6060600282511015613f98576040805162461bcd60e51b8152602060048201526015602482015274098d2c4e4c2e4f27440929cac82989288bea082a89605b1b604482015290519081900360640190fd5b815167ffffffffffffffff81118015613fb057600080fd5b50604051908082528060200260200182016040528015613fda578160200160208202803683370190505b5090508281600183510381518110613fee57fe5b60209081029190910101528151600019015b8015613ae5576000806140308786600186038151811061401c57fe5b6020026020010151878681518110613a9257fe5b9150915061405284848151811061404357fe5b602002602001015183836143c9565b84600185038151811061406157fe5b6020908102919091010152505060001901614000565b60005b60018351038110156138b05760008084838151811061409557fe5b60200260200101518584600101815181106140ac57fe5b60200260200101519150915060006140c48383614589565b50905060006140f47f00000000000000000000000000000000000000000000000000000000000000008585613aed565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561413557600080fd5b505afa158015614149573d6000803e3d6000fd5b505050506040513d606081101561415f57600080fd5b5080516020909101516001600160701b0391821693501690506000806001600160a01b038a811690891614614195578284614198565b83835b915091506141ed828b6001600160a01b03166370a082318a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611b0657600080fd5b95506141fa8683836138b5565b945050505050600080856001600160a01b0316886001600160a01b03161461422457826000614228565b6000835b91509150600060028c51038a1061423f578a614273565b6142737f0000000000000000000000000000000000000000000000000000000000000000898e8d60020181518110613de857fe5b604080516000808252602082019283905263022c0d9f60e01b835260248201878152604483018790526001600160a01b038086166064850152608060848501908152845160a48601819052969750908c169563022c0d9f958a958a958a9591949193919260c486019290918190849084905b838110156142fd5781810151838201526020016142e5565b50505050905090810190601f16801561432a5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561434c57600080fd5b505af1158015614360573d6000803e3d6000fd5b50506001909b019a5061407a9950505050505050505050565b808203828111156112c6576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b60008084116144095760405162461bcd60e51b8152600401808060200182810382526023815260200180614b366023913960400191505060405180910390fd5b6000831180156144195750600082115b61446a576040805162461bcd60e51b815260206004820152601f60248201527f4c6962726172793a20494e53554646494349454e545f4c495155494449545900604482015290519081900360640190fd5b60006144826103e861447c8688614932565b90614932565b905060006144966103e561447c8689614379565b90506144ad60018284816144a657fe5b0490614995565b9695505050505050565b600080841161450d576040805162461bcd60e51b815260206004820152601c60248201527f4c6962726172793a20494e53554646494349454e545f414d4f554e5400000000604482015290519081900360640190fd5b60008311801561451d5750600082115b61456e576040805162461bcd60e51b815260206004820152601f60248201527f4c6962726172793a20494e53554646494349454e545f4c495155494449545900604482015290519081900360640190fd5b826145798584614932565b8161458057fe5b04949350505050565b600080826001600160a01b0316846001600160a01b031614156145f3576040805162461bcd60e51b815260206004820152601c60248201527f4c6962726172793a204944454e544943414c5f41444452455353455300000000604482015290519081900360640190fd5b826001600160a01b0316846001600160a01b031610614613578284614616565b83835b90925090506001600160a01b03821661466e576040805162461bcd60e51b81526020600482015260156024820152744c6962726172793a205a45524f5f4144445245535360581b604482015290519081900360640190fd5b9250929050565b60008060006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a439058a8a6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561470157600080fd5b505afa158015614715573d6000803e3d6000fd5b505050506040513d602081101561472b57600080fd5b50516001600160a01b031614156147e9577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c9c6539689896040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b0316815260200192505050602060405180830381600087803b1580156147bc57600080fd5b505af11580156147d0573d6000803e3d6000fd5b505050506040513d60208110156147e657600080fd5b50505b6000806148177f00000000000000000000000000000000000000000000000000000000000000008b8b6149e4565b91509150816000148015614829575080155b1561483957879350869250614925565b60006148468984846144b7565b90508781116148af57858110156148a4576040805162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604482015290519081900360640190fd5b889450925082614923565b60006148bc8984866144b7565b9050898111156148c857fe5b8781101561491d576040805162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604482015290519081900360640190fd5b94508793505b505b5050965096945050505050565b600081158061494d5750508082028282828161494a57fe5b04145b6112c6576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b808201828110156112c6576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b60008060006149f38585614589565b509050600080614a04888888613aed565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015614a3c57600080fd5b505afa158015614a50573d6000803e3d6000fd5b505050506040513d6060811015614a6657600080fd5b5080516020909101516001600160701b0391821693501690506001600160a01b0387811690841614614a99578082614a9c565b81815b9099909850965050505050505056fe4c6962726172793a20494e53554646494349454e545f494e5055545f414d4f554e544f6e6c792074686520636f6e7472616374206f776e65722063616e2063616c6c20746869732066756e6374696f6e4f6e6c792077616c6c657420616e642077686974656c697374206164647265737365732063616e2063616c6c20746869732066756e6374696f6e4c6962726172793a20494e53554646494349454e545f4f55545055545f414d4f554e54526f757465723a20494e53554646494349454e545f4f55545055545f414d4f554e545472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a2646970667358221220afb9019d8ba77319ddadf426d9f54e4e3e2285e106e5ea248e66733d329453eb64736f6c634300060c0033000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27

Deployed ByteCode

0x6080604052600436106101bb5760003560e01c80638803dbee116100ec578063c45a01551161008a578063e8e3370011610064578063e8e3370014610c66578063f305d71914610ce6578063f851a44014610d2c578063fb3bdb4114610d41576101f4565b8063c45a015514610b29578063d06ca61f14610b3e578063ded9382a14610bf3576101f4565b8063ad615dec116100c6578063ad615dec146109bf578063af2979eb146109f5578063b6f9de9514610a48578063baa2abde14610acc576101f4565b80638803dbee146108b15780639b19251a14610947578063ad5c46481461098e576101f4565b80635b0d598411610159578063791ac94711610133578063791ac9471461072e5780637ff36ab5146107c4578063854cff2f1461084857806385f8c2591461087b576101f4565b80635b0d5984146105f25780635c11d7951461066557806375829def146106fb576101f4565b80631f00ca74116101955780631f00ca74146103935780632195995c1461044857806338ed1739146104c65780634a25d94a1461055c576101f4565b806302751cec146101f9578063054d50d41461026557806318cbafe5146102ad576101f4565b366101f457336001600160a01b037f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2716146101f257fe5b005b600080fd5b34801561020557600080fd5b5061024c600480360360c081101561021c57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135610dc5565b6040805192835260208301919091528051918290030190f35b34801561027157600080fd5b5061029b6004803603606081101561028857600080fd5b5080359060208101359060400135610ee3565b60408051918252519081900360200190f35b3480156102b957600080fd5b50610343600480360360a08110156102d057600080fd5b813591602081013591810190606081016040820135600160201b8111156102f657600080fd5b82018360208201111561030857600080fd5b803590602001918460208302840111600160201b8311171561032957600080fd5b91935091506001600160a01b038135169060200135610ef8565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561037f578181015183820152602001610367565b505050509050019250505060405180910390f35b34801561039f57600080fd5b50610343600480360360408110156103b657600080fd5b81359190810190604081016020820135600160201b8111156103d757600080fd5b8201836020820111156103e957600080fd5b803590602001918460208302840111600160201b8311171561040a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611296945050505050565b34801561045457600080fd5b5061024c600480360361016081101561046c57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c08101359060e081013515159060ff61010082013516906101208101359061014001356112cc565b3480156104d257600080fd5b50610343600480360360a08110156104e957600080fd5b813591602081013591810190606081016040820135600160201b81111561050f57600080fd5b82018360208201111561052157600080fd5b803590602001918460208302840111600160201b8311171561054257600080fd5b91935091506001600160a01b0381351690602001356113c6565b34801561056857600080fd5b50610343600480360360a081101561057f57600080fd5b813591602081013591810190606081016040820135600160201b8111156105a557600080fd5b8201836020820111156105b757600080fd5b803590602001918460208302840111600160201b831117156105d857600080fd5b91935091506001600160a01b038135169060200135611579565b3480156105fe57600080fd5b5061029b600480360361014081101561061657600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e0820135169061010081013590610120013561178c565b34801561067157600080fd5b506101f2600480360360a081101561068857600080fd5b813591602081013591810190606081016040820135600160201b8111156106ae57600080fd5b8201836020820111156106c057600080fd5b803590602001918460208302840111600160201b831117156106e157600080fd5b91935091506001600160a01b03813516906020013561189a565b34801561070757600080fd5b506101f26004803603602081101561071e57600080fd5b50356001600160a01b0316611b7f565b34801561073a57600080fd5b506101f2600480360360a081101561075157600080fd5b813591602081013591810190606081016040820135600160201b81111561077757600080fd5b82018360208201111561078957600080fd5b803590602001918460208302840111600160201b831117156107aa57600080fd5b91935091506001600160a01b038135169060200135611c45565b610343600480360360808110156107da57600080fd5b81359190810190604081016020820135600160201b8111156107fb57600080fd5b82018360208201111561080d57600080fd5b803590602001918460208302840111600160201b8311171561082e57600080fd5b91935091506001600160a01b038135169060200135611f3f565b34801561085457600080fd5b506101f26004803603602081101561086b57600080fd5b50356001600160a01b03166122fa565b34801561088757600080fd5b5061029b6004803603606081101561089e57600080fd5b5080359060208101359060400135612367565b3480156108bd57600080fd5b50610343600480360360a08110156108d457600080fd5b813591602081013591810190606081016040820135600160201b8111156108fa57600080fd5b82018360208201111561090c57600080fd5b803590602001918460208302840111600160201b8311171561092d57600080fd5b91935091506001600160a01b038135169060200135612374565b34801561095357600080fd5b5061097a6004803603602081101561096a57600080fd5b50356001600160a01b03166124eb565b604080519115158252519081900360200190f35b34801561099a57600080fd5b506109a3612500565b604080516001600160a01b039092168252519081900360200190f35b3480156109cb57600080fd5b5061029b600480360360608110156109e257600080fd5b5080359060208101359060400135612524565b348015610a0157600080fd5b5061029b600480360360c0811015610a1857600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135612531565b6101f260048036036080811015610a5e57600080fd5b81359190810190604081016020820135600160201b811115610a7f57600080fd5b820183602082011115610a9157600080fd5b803590602001918460208302840111600160201b83111715610ab257600080fd5b91935091506001600160a01b0381351690602001356126bb565b348015610ad857600080fd5b5061024c600480360360e0811015610aef57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c00135612a9d565b348015610b3557600080fd5b506109a3612d11565b348015610b4a57600080fd5b5061034360048036036040811015610b6157600080fd5b81359190810190604081016020820135600160201b811115610b8257600080fd5b820183602082011115610b9457600080fd5b803590602001918460208302840111600160201b83111715610bb557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612d35945050505050565b348015610bff57600080fd5b5061024c6004803603610140811015610c1757600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e08201351690610100810135906101200135612d62565b348015610c7257600080fd5b50610cc86004803603610100811015610c8a57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359160c0820135169060e00135612e76565b60408051938452602084019290925282820152519081900360600190f35b610cc8600480360360c0811015610cfc57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135612fad565b348015610d3857600080fd5b506109a3613244565b61034360048036036080811015610d5757600080fd5b81359190810190604081016020820135600160201b811115610d7857600080fd5b820183602082011115610d8a57600080fd5b803590602001918460208302840111600160201b83111715610dab57600080fd5b91935091506001600160a01b038135169060200135613253565b6000808242811015610e10576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b610e3f897f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a278a8a8a308a612a9d565b9093509150610e4f898685613653565b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610eb557600080fd5b505af1158015610ec9573d6000803e3d6000fd5b50505050610ed785836137bd565b50965096945050505050565b6000610ef08484846138b5565b949350505050565b6060610f03336139a3565b1580610f2357503360009081526020819052604090205460ff1615156001145b610f5e5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015610fa6576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6001600160a01b037f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a271686866000198101818110610fe057fe5b905060200201356001600160a01b03166001600160a01b031614611042576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b6110a07f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506139a992505050565b915086826001845103815181106110b357fe5b602002602001015110156110f85760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b6111968686600081811061110857fe5b905060200201356001600160a01b03163361117c7f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8a8a600081811061114a57fe5b905060200201356001600160a01b03168b8b600181811061116757fe5b905060200201356001600160a01b0316613aed565b8560008151811061118957fe5b6020026020010151613bad565b6111d582878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613d0a915050565b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316632e1a7d4d8360018551038151811061121457fe5b60200260200101516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561125257600080fd5b505af1158015611266573d6000803e3d6000fd5b5050505061128b848360018551038151811061127e57fe5b60200260200101516137bd565b509695505050505050565b60606112c37f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8484613f47565b90505b92915050565b60008060006112fc7f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8f8f613aed565b905060008761130b578c61130f565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b15801561138557600080fd5b505af1158015611399573d6000803e3d6000fd5b505050506113ac8f8f8f8f8f8f8f612a9d565b809450819550505050509b509b9950505050505050505050565b60606113d1336139a3565b15806113f157503360009081526020819052604090205460ff1615156001145b61142c5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015611474576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6114d27f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506139a992505050565b915086826001845103815181106114e557fe5b6020026020010151101561152a5760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b61153a8686600081811061110857fe5b61128b82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d0a915050565b6060611584336139a3565b15806115a457503360009081526020819052604090205460ff1615156001145b6115df5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015611627576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6001600160a01b037f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27168686600019810181811061166157fe5b905060200201356001600160a01b03166001600160a01b0316146116c3576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b6117217f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca89888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613f4792505050565b9150868260008151811061173157fe5b602002602001015111156110f8576040805162461bcd60e51b815260206004820152601e60248201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604482015290519081900360640190fd5b6000806117da7f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8d7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27613aed565b90506000866117e9578b6117ed565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018b905260ff8916608482015260a4810188905260c4810187905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b15801561186357600080fd5b505af1158015611877573d6000803e3d6000fd5b505050506118898d8d8d8d8d8d612531565b9d9c50505050505050505050505050565b6118a3336139a3565b15806118c357503360009081526020819052604090205460ff1615156001145b6118fe5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8042811015611946576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6119bb8585600081811061195657fe5b905060200201356001600160a01b0316336119b57f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8989600081811061199857fe5b905060200201356001600160a01b03168a8a600181811061116757fe5b8a613bad565b6000858560001981018181106119cd57fe5b905060200201356001600160a01b03166001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611a2957600080fd5b505afa158015611a3d573d6000803e3d6000fd5b505050506040513d6020811015611a5357600080fd5b50516040805160208881028281018201909352888252929350611a95929091899189918291850190849080828437600092019190915250889250614077915050565b86611b388288886000198101818110611aaa57fe5b905060200201356001600160a01b03166001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611b0657600080fd5b505afa158015611b1a573d6000803e3d6000fd5b505050506040513d6020811015611b3057600080fd5b505190614379565b1015611b755760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b5050505050505050565b6001546001600160a01b03163314611bc85760405162461bcd60e51b815260040180806020018281038252602e815260200180614ace602e913960400191505060405180910390fd5b6001600160a01b038116611c23576040805162461bcd60e51b815260206004820152601960248201527f496e76616c6964206e6577206f776e6572206164647265737300000000000000604482015290519081900360640190fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b611c4e336139a3565b1580611c6e57503360009081526020819052604090205460ff1615156001145b611ca95760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8042811015611cf1576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6001600160a01b037f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a271685856000198101818110611d2b57fe5b905060200201356001600160a01b03166001600160a01b031614611d8d576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b611d9d8585600081811061195657fe5b611ddb858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250614077915050565b60007f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611e4a57600080fd5b505afa158015611e5e573d6000803e3d6000fd5b505050506040513d6020811015611e7457600080fd5b5051905086811015611eb75760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611f1d57600080fd5b505af1158015611f31573d6000803e3d6000fd5b50505050611b7584826137bd565b6060611f4a336139a3565b1580611f6a57503360009081526020819052604090205460ff1615156001145b611fa55760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015611fed576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b03168686600081811061202457fe5b905060200201356001600160a01b03166001600160a01b031614612086576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b6120e47f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca348888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506139a992505050565b915086826001845103815181106120f757fe5b6020026020010151101561213c5760405162461bcd60e51b8152600401808060200182810382526022815260200180614b596022913960400191505060405180910390fd5b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b031663d0e30db08360008151811061217857fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156121ab57600080fd5b505af11580156121bf573d6000803e3d6000fd5b50505050507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b031663a9059cbb6122247f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8989600081811061199857fe5b8460008151811061223157fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561227f57600080fd5b505af1158015612293573d6000803e3d6000fd5b505050506040513d60208110156122a957600080fd5b50516122b157fe5b6122f082878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d0a915050565b5095945050505050565b6001546001600160a01b031633146123435760405162461bcd60e51b815260040180806020018281038252602e815260200180614ace602e913960400191505060405180910390fd5b6001600160a01b03166000908152602081905260409020805460ff19166001179055565b6000610ef08484846143c9565b606061237f336139a3565b158061239f57503360009081526020819052604090205460ff1615156001145b6123da5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015612422576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6124807f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca89888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613f4792505050565b9150868260008151811061249057fe5b6020026020010151111561152a576040805162461bcd60e51b815260206004820152601e60248201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604482015290519081900360640190fd5b60006020819052908152604090205460ff1681565b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a2781565b6000610ef08484846144b7565b6000814281101561257b576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6125aa887f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a278989893089612a9d565b90508092505061263388858a6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561260257600080fd5b505afa158015612616573d6000803e3d6000fd5b505050506040513d602081101561262c57600080fd5b5051613653565b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561269957600080fd5b505af11580156126ad573d6000803e3d6000fd5b5050505061128b84836137bd565b6126c4336139a3565b15806126e457503360009081526020819052604090205460ff1615156001145b61271f5760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8042811015612767576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b03168585600081811061279e57fe5b905060200201356001600160a01b03166001600160a01b031614612800576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b60003490507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561286057600080fd5b505af1158015612874573d6000803e3d6000fd5b50505050507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b031663a9059cbb6128d97f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8989600081811061199857fe5b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561292057600080fd5b505af1158015612934573d6000803e3d6000fd5b505050506040513d602081101561294a57600080fd5b505161295257fe5b60008686600019810181811061296457fe5b905060200201356001600160a01b03166001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156129c057600080fd5b505afa1580156129d4573d6000803e3d6000fd5b505050506040513d60208110156129ea57600080fd5b50516040805160208981028281018201909352898252929350612a2c9290918a918a918291850190849080828437600092019190915250899250614077915050565b87611b388289896000198101818110612a4157fe5b905060200201356001600160a01b03166001600160a01b03166370a08231896040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611b0657600080fd5b6000808242811015612ae8576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6000612b157f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8c8c613aed565b604080516323b872dd60e01b81523360048201526001600160a01b03831660248201819052604482018d9052915192935090916323b872dd916064808201926020929091908290030181600087803b158015612b7057600080fd5b505af1158015612b84573d6000803e3d6000fd5b505050506040513d6020811015612b9a57600080fd5b50506040805163226bf2d160e21b81526001600160a01b03888116600483015282516000938493928616926389afcb44926024808301939282900301818787803b158015612be757600080fd5b505af1158015612bfb573d6000803e3d6000fd5b505050506040513d6040811015612c1157600080fd5b50805160209091015190925090506000612c2b8e8e614589565b509050806001600160a01b03168e6001600160a01b031614612c4e578183612c51565b82825b90975095508a871015612cab576040805162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604482015290519081900360640190fd5b89861015612d00576040805162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604482015290519081900360640190fd5b505050505097509795505050505050565b7f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca81565b60606112c37f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca84846139a9565b6000806000612db27f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8e7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27613aed565b9050600087612dc1578c612dc5565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b158015612e3b57600080fd5b505af1158015612e4f573d6000803e3d6000fd5b50505050612e618e8e8e8e8e8e610dc5565b909f909e509c50505050505050505050505050565b60008060008342811015612ec3576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b612ed18c8c8c8c8c8c614675565b90945092506000612f037f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8e8e613aed565b9050612f118d338388613bad565b612f1d8c338387613bad565b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015612f6c57600080fd5b505af1158015612f80573d6000803e3d6000fd5b505050506040513d6020811015612f9657600080fd5b5051949d939c50939a509198505050505050505050565b60008060008342811015612ffa576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b6130288a7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a278b348c8c614675565b9094509250600061307a7f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8c7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a27613aed565b90506130888b338388613bad565b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130e357600080fd5b505af11580156130f7573d6000803e3d6000fd5b50505050507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b031663a9059cbb82866040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561317357600080fd5b505af1158015613187573d6000803e3d6000fd5b505050506040513d602081101561319d57600080fd5b50516131a557fe5b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b1580156131f457600080fd5b505af1158015613208573d6000803e3d6000fd5b505050506040513d602081101561321e57600080fd5b505192503484101561323657613236338534036137bd565b505096509650969350505050565b6001546001600160a01b031681565b606061325e336139a3565b158061327e57503360009081526020819052604090205460ff1615156001145b6132b95760405162461bcd60e51b815260040180806020018281038252603a815260200180614afc603a913960400191505060405180910390fd5b8142811015613301576040805162461bcd60e51b815260206004820152600f60248201526e149bdd5d195c8e8811561412549151608a1b604482015290519081900360640190fd5b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b03168686600081811061333857fe5b905060200201356001600160a01b03166001600160a01b03161461339a576040805162461bcd60e51b81526020600482015260146024820152730a4deeae8cae47440929cac82989288bea082a8960631b604482015290519081900360640190fd5b6133f87f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca88888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613f4792505050565b9150348260008151811061340857fe5b60200260200101511115613463576040805162461bcd60e51b815260206004820152601e60248201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604482015290519081900360640190fd5b7f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b031663d0e30db08360008151811061349f57fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156134d257600080fd5b505af11580156134e6573d6000803e3d6000fd5b50505050507f000000000000000000000000a1077a294dde1b09bb078844df40758a5d0f9a276001600160a01b031663a9059cbb61354b7f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8989600081811061199857fe5b8460008151811061355857fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156135a657600080fd5b505af11580156135ba573d6000803e3d6000fd5b505050506040513d60208110156135d057600080fd5b50516135d857fe5b61361782878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d0a915050565b8160008151811061362457fe5b60200260200101513411156122f0576122f0338360008151811061364457fe5b602002602001015134036137bd565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b602083106136d05780518252601f1990920191602091820191016136b1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613732576040519150601f19603f3d011682016040523d82523d6000602084013e613737565b606091505b5091509150818015613765575080511580613765575080806020019051602081101561376257600080fd5b50515b6137b6576040805162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b5050505050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106138095780518252601f1990920191602091820191016137ea565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d806000811461386b576040519150601f19603f3d011682016040523d82523d6000602084013e613870565b606091505b50509050806138b05760405162461bcd60e51b8152600401808060200182810382526023815260200180614b7b6023913960400191505060405180910390fd5b505050565b60008084116138f55760405162461bcd60e51b8152600401808060200182810382526022815260200180614aac6022913960400191505060405180910390fd5b6000831180156139055750600082115b613956576040805162461bcd60e51b815260206004820152601f60248201527f4c6962726172793a20494e53554646494349454e545f4c495155494449545900604482015290519081900360640190fd5b6000613964856103e5614932565b905060006139728285614932565b9050600061398c83613986886103e8614932565b90614995565b905080828161399757fe5b04979650505050505050565b3b151590565b60606002825110156139fa576040805162461bcd60e51b8152602060048201526015602482015274098d2c4e4c2e4f27440929cac82989288bea082a89605b1b604482015290519081900360640190fd5b815167ffffffffffffffff81118015613a1257600080fd5b50604051908082528060200260200182016040528015613a3c578160200160208202803683370190505b5090508281600081518110613a4d57fe5b60200260200101818152505060005b6001835103811015613ae557600080613a9f87868581518110613a7b57fe5b6020026020010151878660010181518110613a9257fe5b60200260200101516149e4565b91509150613ac1848481518110613ab257fe5b602002602001015183836138b5565b848460010181518110613ad057fe5b60209081029190910101525050600101613a5c565b509392505050565b6000806000613afc8585614589565b604080516bffffffffffffffffffffffff19606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501206001600160f81b031960688401529a90941b9093166069840152607d8301989098527f62c6f1e729f434ea3a6205faad8316f45062b0eeaa3935ef181ebc0d3cf298de609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b60208310613c325780518252601f199092019160209182019101613c13565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613c94576040519150601f19603f3d011682016040523d82523d6000602084013e613c99565b606091505b5091509150818015613cc7575080511580613cc75750808060200190516020811015613cc457600080fd5b50515b613d025760405162461bcd60e51b8152600401808060200182810382526024815260200180614b9e6024913960400191505060405180910390fd5b505050505050565b60005b6001835103811015613f4157600080848381518110613d2857fe5b6020026020010151858460010181518110613d3f57fe5b6020026020010151915091506000613d578383614589565b5090506000878560010181518110613d6b57fe5b60200260200101519050600080836001600160a01b0316866001600160a01b031614613d9957826000613d9d565b6000835b91509150600060028a51038810613db45788613df5565b613df57f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca878c8b60020181518110613de857fe5b6020026020010151613aed565b9050613e227f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8888613aed565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f191660200182016040528015613e5f576020820181803683370190505b506040518563ffffffff1660e01b815260040180858152602001848152602001836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613ec7578181015183820152602001613eaf565b50505050905090810190601f168015613ef45780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015613f1657600080fd5b505af1158015613f2a573d6000803e3d6000fd5b505060019099019850613d0d975050505050505050565b50505050565b6060600282511015613f98576040805162461bcd60e51b8152602060048201526015602482015274098d2c4e4c2e4f27440929cac82989288bea082a89605b1b604482015290519081900360640190fd5b815167ffffffffffffffff81118015613fb057600080fd5b50604051908082528060200260200182016040528015613fda578160200160208202803683370190505b5090508281600183510381518110613fee57fe5b60209081029190910101528151600019015b8015613ae5576000806140308786600186038151811061401c57fe5b6020026020010151878681518110613a9257fe5b9150915061405284848151811061404357fe5b602002602001015183836143c9565b84600185038151811061406157fe5b6020908102919091010152505060001901614000565b60005b60018351038110156138b05760008084838151811061409557fe5b60200260200101518584600101815181106140ac57fe5b60200260200101519150915060006140c48383614589565b50905060006140f47f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8585613aed565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561413557600080fd5b505afa158015614149573d6000803e3d6000fd5b505050506040513d606081101561415f57600080fd5b5080516020909101516001600160701b0391821693501690506000806001600160a01b038a811690891614614195578284614198565b83835b915091506141ed828b6001600160a01b03166370a082318a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611b0657600080fd5b95506141fa8683836138b5565b945050505050600080856001600160a01b0316886001600160a01b03161461422457826000614228565b6000835b91509150600060028c51038a1061423f578a614273565b6142737f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca898e8d60020181518110613de857fe5b604080516000808252602082019283905263022c0d9f60e01b835260248201878152604483018790526001600160a01b038086166064850152608060848501908152845160a48601819052969750908c169563022c0d9f958a958a958a9591949193919260c486019290918190849084905b838110156142fd5781810151838201526020016142e5565b50505050905090810190601f16801561432a5780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b15801561434c57600080fd5b505af1158015614360573d6000803e3d6000fd5b50506001909b019a5061407a9950505050505050505050565b808203828111156112c6576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b60008084116144095760405162461bcd60e51b8152600401808060200182810382526023815260200180614b366023913960400191505060405180910390fd5b6000831180156144195750600082115b61446a576040805162461bcd60e51b815260206004820152601f60248201527f4c6962726172793a20494e53554646494349454e545f4c495155494449545900604482015290519081900360640190fd5b60006144826103e861447c8688614932565b90614932565b905060006144966103e561447c8689614379565b90506144ad60018284816144a657fe5b0490614995565b9695505050505050565b600080841161450d576040805162461bcd60e51b815260206004820152601c60248201527f4c6962726172793a20494e53554646494349454e545f414d4f554e5400000000604482015290519081900360640190fd5b60008311801561451d5750600082115b61456e576040805162461bcd60e51b815260206004820152601f60248201527f4c6962726172793a20494e53554646494349454e545f4c495155494449545900604482015290519081900360640190fd5b826145798584614932565b8161458057fe5b04949350505050565b600080826001600160a01b0316846001600160a01b031614156145f3576040805162461bcd60e51b815260206004820152601c60248201527f4c6962726172793a204944454e544943414c5f41444452455353455300000000604482015290519081900360640190fd5b826001600160a01b0316846001600160a01b031610614613578284614616565b83835b90925090506001600160a01b03821661466e576040805162461bcd60e51b81526020600482015260156024820152744c6962726172793a205a45524f5f4144445245535360581b604482015290519081900360640190fd5b9250929050565b60008060006001600160a01b03167f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca6001600160a01b031663e6a439058a8a6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561470157600080fd5b505afa158015614715573d6000803e3d6000fd5b505050506040513d602081101561472b57600080fd5b50516001600160a01b031614156147e9577f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca6001600160a01b031663c9c6539689896040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b0316815260200192505050602060405180830381600087803b1580156147bc57600080fd5b505af11580156147d0573d6000803e3d6000fd5b505050506040513d60208110156147e657600080fd5b50505b6000806148177f000000000000000000000000e2332e5297b18a21dce0e6ac461e821c353a00ca8b8b6149e4565b91509150816000148015614829575080155b1561483957879350869250614925565b60006148468984846144b7565b90508781116148af57858110156148a4576040805162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604482015290519081900360640190fd5b889450925082614923565b60006148bc8984866144b7565b9050898111156148c857fe5b8781101561491d576040805162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604482015290519081900360640190fd5b94508793505b505b5050965096945050505050565b600081158061494d5750508082028282828161494a57fe5b04145b6112c6576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b808201828110156112c6576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b60008060006149f38585614589565b509050600080614a04888888613aed565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015614a3c57600080fd5b505afa158015614a50573d6000803e3d6000fd5b505050506040513d6060811015614a6657600080fd5b5080516020909101516001600160701b0391821693501690506001600160a01b0387811690841614614a99578082614a9c565b81815b9099909850965050505050505056fe4c6962726172793a20494e53554646494349454e545f494e5055545f414d4f554e544f6e6c792074686520636f6e7472616374206f776e65722063616e2063616c6c20746869732066756e6374696f6e4f6e6c792077616c6c657420616e642077686974656c697374206164647265737365732063616e2063616c6c20746869732066756e6374696f6e4c6962726172793a20494e53554646494349454e545f4f55545055545f414d4f554e54526f757465723a20494e53554646494349454e545f4f55545055545f414d4f554e545472616e7366657248656c7065723a204554485f5452414e534645525f4641494c45445472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544a2646970667358221220afb9019d8ba77319ddadf426d9f54e4e3e2285e106e5ea248e66733d329453eb64736f6c634300060c0033