Address Details
contract

0x8701fBbDb98c9598Aa4beBE82AEe457B9aE6dc80

Contract Name
PancakeRouter01
Creator
0x2bcef4–a00bc1 at 0xd73ff2–e9fabc
Balance
0 CELO ( )
Locked CELO Balance
0.00 CELO
Voting CELO Balance
0.00 CELO
Pending Unlocked Gold
0.00 CELO
Tokens
Fetching tokens...
Transactions
9 Transactions
Transfers
0 Transfers
Gas Used
5,771,713
Last Balance Update
7683741
This contract has been verified via Sourcify. View contract in Sourcify repository
Contract name:
PancakeRouter01




Optimization enabled
true
Compiler version
v0.6.6+commit.6c089d02




Optimization runs
200
EVM Version
istanbul




Verified at
2023-02-06T00:34:20.997481Z

contracts/PancakeRouter.sol

pragma solidity =0.6.6;


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

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

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

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

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

// SPDX-License-Identifier: GPL-3.0-or-later
// 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::safeApprove: 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::safeTransfer: 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::transferFrom: transferFrom failed'
        );
    }

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

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

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

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

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

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

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

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

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

    function initialize(address, address) external;
}

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
library SafeMath {
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x, 'ds-math-add-overflow');
    }

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

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

library PancakeLibrary {
    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, "PancakeLibrary: IDENTICAL_ADDRESSES");
        (token0, token1) = tokenA < tokenB
            ? (tokenA, tokenB)
            : (tokenB, tokenA);
        require(token0 != address(0), "PancakeLibrary: 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"d448cceaaa67bd95c8e223ea7b9d9c2fcb281345e9954872d965bc6f51882f0d"
                    )
                )
            )
        );
    }

    // 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);
        pairFor(factory, tokenA, tokenB);
        (uint256 reserve0, uint256 reserve1, ) = IPancakePair(
            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, "PancakeLibrary: INSUFFICIENT_AMOUNT");
        require(
            reserveA > 0 && reserveB > 0,
            "PancakeLibrary: 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, "PancakeLibrary: INSUFFICIENT_INPUT_AMOUNT");
        require(
            reserveIn > 0 && reserveOut > 0,
            "PancakeLibrary: INSUFFICIENT_LIQUIDITY"
        );
        uint256 amountInWithFee = amountIn.mul(998);
        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, "PancakeLibrary: INSUFFICIENT_OUTPUT_AMOUNT");
        require(
            reserveIn > 0 && reserveOut > 0,
            "PancakeLibrary: INSUFFICIENT_LIQUIDITY"
        );
        uint256 numerator = reserveIn.mul(amountOut).mul(1000);
        uint256 denominator = reserveOut.sub(amountOut).mul(998);
        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, "PancakeLibrary: 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, "PancakeLibrary: 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);
        }
    }
}

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

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

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

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint 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 (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

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

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

contract PancakeRouter01 is IPancakeRouter01 {
    address public immutable override factory;
    address public immutable override WETH;

    modifier ensure(uint deadline) {
        require(deadline >= block.timestamp, 'PancakeRouter: EXPIRED');
        _;
    }

    constructor(address _factory, address _WETH) public {
        factory = _factory;
        WETH = _WETH;
    }

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

    // **** ADD LIQUIDITY ****
    function _addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin
    ) private returns (uint amountA, uint amountB) {
        // create the pair if it doesn't exist yet
        if (IPancakeFactory(factory).getPair(tokenA, tokenB) == address(0)) {
            IPancakeFactory(factory).createPair(tokenA, tokenB);
        }
        (uint reserveA, uint reserveB) = PancakeLibrary.getReserves(factory, tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint amountBOptimal = PancakeLibrary.quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                require(amountBOptimal >= amountBMin, 'PancakeRouter: INSUFFICIENT_B_AMOUNT');
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint amountAOptimal = PancakeLibrary.quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                require(amountAOptimal >= amountAMin, 'PancakeRouter: INSUFFICIENT_A_AMOUNT');
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }
    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
        (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
        liquidity = IPancakePair(pair).mint(to);
    }
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
        (amountToken, amountETH) = _addLiquidity(
            token,
            WETH,
            amountTokenDesired,
            msg.value,
            amountTokenMin,
            amountETHMin
        );
        address pair = PancakeLibrary.pairFor(factory, token, WETH);
        TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
        IWETH(WETH).deposit{value: amountETH}();
        assert(IWETH(WETH).transfer(pair, amountETH));
        liquidity = IPancakePair(pair).mint(to);
        if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH); // refund dust eth, if any
    }

    // **** REMOVE LIQUIDITY ****
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) public override ensure(deadline) returns (uint amountA, uint amountB) {
        address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB);
        IPancakePair(pair).transferFrom(msg.sender, pair, liquidity); // send liquidity to pair
        (uint amount0, uint amount1) = IPancakePair(pair).burn(to);
        (address token0,) = PancakeLibrary.sortTokens(tokenA, tokenB);
        (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
        require(amountA >= amountAMin, 'PancakeRouter: INSUFFICIENT_A_AMOUNT');
        require(amountB >= amountBMin, 'PancakeRouter: INSUFFICIENT_B_AMOUNT');
    }
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) public override ensure(deadline) returns (uint amountToken, uint 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,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external override returns (uint amountA, uint amountB) {
        address pair = PancakeLibrary.pairFor(factory, tokenA, tokenB);
        uint value = approveMax ? uint(-1) : liquidity;
        IPancakePair(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,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external override returns (uint amountToken, uint amountETH) {
        address pair = PancakeLibrary.pairFor(factory, token, WETH);
        uint value = approveMax ? uint(-1) : liquidity;
        IPancakePair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }

    // **** SWAP ****
    // requires the initial amount to have already been sent to the first pair
    function _swap(uint[] memory amounts, address[] memory path, address _to) private {
        for (uint i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = PancakeLibrary.sortTokens(input, output);
            uint amountOut = amounts[i + 1];
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0));
            address to = i < path.length - 2 ? PancakeLibrary.pairFor(factory, output, path[i + 2]) : _to;
            IPancakePair(PancakeLibrary.pairFor(factory, input, output)).swap(amount0Out, amount1Out, to, new bytes(0));
        }
    }
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external override ensure(deadline) returns (uint[] memory amounts) {
        amounts = PancakeLibrary.getAmountsOut(factory, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        TransferHelper.safeTransferFrom(path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]);
        _swap(amounts, path, to);
    }
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external override ensure(deadline) returns (uint[] memory amounts) {
        amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= amountInMax, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT');
        TransferHelper.safeTransferFrom(path[0], msg.sender, PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]);
        _swap(amounts, path, to);
    }
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        override
        payable
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[0] == WETH, 'PancakeRouter: INVALID_PATH');
        amounts = PancakeLibrary.getAmountsOut(factory, msg.value, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
        _swap(amounts, path, to);
    }
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        override
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[path.length - 1] == WETH, 'PancakeRouter: INVALID_PATH');
        amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= amountInMax, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT');
        TransferHelper.safeTransferFrom(path[0], msg.sender, PancakeLibrary.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(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        override
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[path.length - 1] == WETH, 'PancakeRouter: INVALID_PATH');
        amounts = PancakeLibrary.getAmountsOut(factory, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        TransferHelper.safeTransferFrom(path[0], msg.sender, PancakeLibrary.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(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        override
        payable
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[0] == WETH, 'PancakeRouter: INVALID_PATH');
        amounts = PancakeLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= msg.value, 'PancakeRouter: EXCESSIVE_INPUT_AMOUNT');
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(IWETH(WETH).transfer(PancakeLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
        _swap(amounts, path, to);
        if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]); // refund dust eth, if any
    }

    function quote(uint amountA, uint reserveA, uint reserveB) public pure override returns (uint amountB) {
        return PancakeLibrary.quote(amountA, reserveA, reserveB);
    }

    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) public pure override returns (uint amountOut) {
        return PancakeLibrary.getAmountOut(amountIn, reserveIn, reserveOut);
    }

    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public pure override returns (uint amountIn) {
        return PancakeLibrary.getAmountOut(amountOut, reserveIn, reserveOut);
    }

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

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

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","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":"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":"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":"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":"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":"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":[{"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":[{"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":"receive","stateMutability":"payable"}]
              

Contract Creation Code

0x60c060405234801561001057600080fd5b506040516136433803806136438339818101604052604081101561003357600080fd5b5080516020909101516001600160601b0319606092831b8116608052911b1660a05260805160601c60a05160601c61350761013c600039806101285280610a015280610a3c5280610b335280610d5152806110db528061125f52806113a5528061142d528061168252806119725280611be55280611c3b5280611c6f5280611ce35280611e835280611fc6528061204e525080610bc15280610c985280610e175280610e505280610f8b528061116952806112f2528061145f52806115d252806116ff52806118f7528061192052806119505280611abd5280611c195280611f165280612080528061291152806129545280612d9b5280612e495280612ec952506135076000f3fe6080604052600436106101185760003560e01c80638803dbee116100a0578063d06ca61f11610064578063d06ca61f14610742578063ded9382a146107f7578063e8e337001461086a578063f305d719146108ea578063fb3bdb411461093057610151565b80638803dbee146105d3578063ad5c464814610669578063ad615dec1461069a578063baa2abde146106d0578063c45a01551461072d57610151565b80632195995c116100e75780632195995c146103a557806338ed1739146104235780634a25d94a146104b95780637ff36ab51461054f57806385f8c259146101c257610151565b806302751cec14610156578063054d50d4146101c257806318cbafe51461020a5780631f00ca74146102f057610151565b3661015157336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461014f57fe5b005b600080fd5b34801561016257600080fd5b506101a9600480360360c081101561017957600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a001356109b4565b6040805192835260208301919091528051918290030190f35b3480156101ce57600080fd5b506101f8600480360360608110156101e557600080fd5b5080359060208101359060400135610ace565b60408051918252519081900360200190f35b34801561021657600080fd5b506102a0600480360360a081101561022d57600080fd5b813591602081013591810190606081016040820135600160201b81111561025357600080fd5b82018360208201111561026557600080fd5b803590602001918460208302840111600160201b8311171561028657600080fd5b91935091506001600160a01b038135169060200135610ae3565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102dc5781810151838201526020016102c4565b505050509050019250505060405180910390f35b3480156102fc57600080fd5b506102a06004803603604081101561031357600080fd5b81359190810190604081016020820135600160201b81111561033457600080fd5b82018360208201111561034657600080fd5b803590602001918460208302840111600160201b8311171561036757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610e10945050505050565b3480156103b157600080fd5b506101a960048036036101608110156103c957600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c08101359060e081013515159060ff6101008201351690610120810135906101400135610e46565b34801561042f57600080fd5b506102a0600480360360a081101561044657600080fd5b813591602081013591810190606081016040820135600160201b81111561046c57600080fd5b82018360208201111561047e57600080fd5b803590602001918460208302840111600160201b8311171561049f57600080fd5b91935091506001600160a01b038135169060200135610f40565b3480156104c557600080fd5b506102a0600480360360a08110156104dc57600080fd5b813591602081013591810190606081016040820135600160201b81111561050257600080fd5b82018360208201111561051457600080fd5b803590602001918460208302840111600160201b8311171561053557600080fd5b91935091506001600160a01b03813516906020013561108b565b6102a06004803603608081101561056557600080fd5b81359190810190604081016020820135600160201b81111561058657600080fd5b82018360208201111561059857600080fd5b803590602001918460208302840111600160201b831117156105b957600080fd5b91935091506001600160a01b038135169060200135611217565b3480156105df57600080fd5b506102a0600480360360a08110156105f657600080fd5b813591602081013591810190606081016040820135600160201b81111561061c57600080fd5b82018360208201111561062e57600080fd5b803590602001918460208302840111600160201b8311171561064f57600080fd5b91935091506001600160a01b038135169060200135611587565b34801561067557600080fd5b5061067e611680565b604080516001600160a01b039092168252519081900360200190f35b3480156106a657600080fd5b506101f8600480360360608110156106bd57600080fd5b50803590602081013590604001356116a4565b3480156106dc57600080fd5b506101a9600480360360e08110156106f357600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c001356116b1565b34801561073957600080fd5b5061067e6118f5565b34801561074e57600080fd5b506102a06004803603604081101561076557600080fd5b81359190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460208302840111600160201b831117156107b957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611919945050505050565b34801561080357600080fd5b506101a9600480360361014081101561081b57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e08201351690610100810135906101200135611946565b34801561087657600080fd5b506108cc600480360361010081101561088e57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359160c0820135169060e00135611a5a565b60408051938452602084019290925282820152519081900360600190f35b6108cc600480360360c081101561090057600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135611b96565b6102a06004803603608081101561094657600080fd5b81359190810190604081016020820135600160201b81111561096757600080fd5b82018360208201111561097957600080fd5b803590602001918460208302840111600160201b8311171561099a57600080fd5b91935091506001600160a01b038135169060200135611e3b565b60008082428110156109fb576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b610a2a897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a6116b1565b9093509150610a3a8986856121bd565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610aa057600080fd5b505af1158015610ab4573d6000803e3d6000fd5b50505050610ac28583612311565b50965096945050505050565b6000610adb848484612409565b949350505050565b60608142811015610b29576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001686866000198101818110610b6357fe5b905060200201356001600160a01b03166001600160a01b031614610bbc576040805162461bcd60e51b815260206004820152601b60248201526000805160206133cf833981519152604482015290519081900360640190fd5b610c1a7f0000000000000000000000000000000000000000000000000000000000000000898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506124f992505050565b91508682600184510381518110610c2d57fe5b60200260200101511015610c725760405162461bcd60e51b81526004018080602001828103825260298152602001806133836029913960400191505060405180910390fd5b610d1086866000818110610c8257fe5b905060200201356001600160a01b031633610cf67f00000000000000000000000000000000000000000000000000000000000000008a8a6000818110610cc457fe5b905060200201356001600160a01b03168b8b6001818110610ce157fe5b905060200201356001600160a01b0316612645565b85600081518110610d0357fe5b6020026020010151612705565b610d4f82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250612862915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d83600185510381518110610d8e57fe5b60200260200101516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610dcc57600080fd5b505af1158015610de0573d6000803e3d6000fd5b50505050610e058483600185510381518110610df857fe5b6020026020010151612311565b509695505050505050565b6060610e3d7f00000000000000000000000000000000000000000000000000000000000000008484612aa8565b90505b92915050565b6000806000610e767f00000000000000000000000000000000000000000000000000000000000000008f8f612645565b9050600087610e85578c610e89565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b158015610eff57600080fd5b505af1158015610f13573d6000803e3d6000fd5b50505050610f268f8f8f8f8f8f8f6116b1565b809450819550505050509b509b9950505050505050505050565b60608142811015610f86576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b610fe47f0000000000000000000000000000000000000000000000000000000000000000898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506124f992505050565b91508682600184510381518110610ff757fe5b6020026020010151101561103c5760405162461bcd60e51b81526004018080602001828103825260298152602001806133836029913960400191505060405180910390fd5b61104c86866000818110610c8257fe5b610e0582878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612862915050565b606081428110156110d1576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686600019810181811061110b57fe5b905060200201356001600160a01b03166001600160a01b031614611164576040805162461bcd60e51b815260206004820152601b60248201526000805160206133cf833981519152604482015290519081900360640190fd5b6111c27f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612aa892505050565b915086826000815181106111d257fe5b60200260200101511115610c725760405162461bcd60e51b81526004018080602001828103825260258152602001806134636025913960400191505060405180910390fd5b6060814281101561125d576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168686600081811061129457fe5b905060200201356001600160a01b03166001600160a01b0316146112ed576040805162461bcd60e51b815260206004820152601b60248201526000805160206133cf833981519152604482015290519081900360640190fd5b61134b7f0000000000000000000000000000000000000000000000000000000000000000348888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506124f992505050565b9150868260018451038151811061135e57fe5b602002602001015110156113a35760405162461bcd60e51b81526004018080602001828103825260298152602001806133836029913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0836000815181106113df57fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6114a87f00000000000000000000000000000000000000000000000000000000000000008989600081811061148b57fe5b905060200201356001600160a01b03168a8a6001818110610ce157fe5b846000815181106114b557fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561150c57600080fd5b505af1158015611520573d6000803e3d6000fd5b505050506040513d602081101561153657600080fd5b505161153e57fe5b61157d82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612862915050565b5095945050505050565b606081428110156115cd576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b61162b7f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612aa892505050565b9150868260008151811061163b57fe5b6020026020010151111561103c5760405162461bcd60e51b81526004018080602001828103825260258152602001806134636025913960400191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b6000610adb848484612be0565b60008082428110156116f8576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b60006117257f00000000000000000000000000000000000000000000000000000000000000008c8c612645565b604080516323b872dd60e01b81523360048201526001600160a01b03831660248201819052604482018d9052915192935090916323b872dd916064808201926020929091908290030181600087803b15801561178057600080fd5b505af1158015611794573d6000803e3d6000fd5b505050506040513d60208110156117aa57600080fd5b50506040805163226bf2d160e21b81526001600160a01b03888116600483015282516000938493928616926389afcb44926024808301939282900301818787803b1580156117f757600080fd5b505af115801561180b573d6000803e3d6000fd5b505050506040513d604081101561182157600080fd5b5080516020909101519092509050600061183b8e8e612c8c565b509050806001600160a01b03168e6001600160a01b03161461185e578183611861565b82825b90975095508a8710156118a55760405162461bcd60e51b81526004018080602001828103825260248152602001806133ef6024913960400191505060405180910390fd5b898610156118e45760405162461bcd60e51b81526004018080602001828103825260248152602001806134ae6024913960400191505060405180910390fd5b505050505097509795505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6060610e3d7f000000000000000000000000000000000000000000000000000000000000000084846124f9565b60008060006119967f00000000000000000000000000000000000000000000000000000000000000008e7f0000000000000000000000000000000000000000000000000000000000000000612645565b90506000876119a5578c6119a9565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b158015611a1f57600080fd5b505af1158015611a33573d6000803e3d6000fd5b50505050611a458e8e8e8e8e8e6109b4565b909f909e509c50505050505050505050505050565b60008060008342811015611aa3576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b611ab18c8c8c8c8c8c612d6a565b90945092506000611ae37f00000000000000000000000000000000000000000000000000000000000000008e8e612645565b9050611af18d338388612705565b611afd8c338387612705565b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611b5557600080fd5b505af1158015611b69573d6000803e3d6000fd5b505050506040513d6020811015611b7f57600080fd5b5051949d939c50939a509198505050505050505050565b60008060008342811015611bdf576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b611c0d8a7f00000000000000000000000000000000000000000000000000000000000000008b348c8c612d6a565b90945092506000611c5f7f00000000000000000000000000000000000000000000000000000000000000008c7f0000000000000000000000000000000000000000000000000000000000000000612645565b9050611c6d8b338388612705565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015611cc857600080fd5b505af1158015611cdc573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb82866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611d6157600080fd5b505af1158015611d75573d6000803e3d6000fd5b505050506040513d6020811015611d8b57600080fd5b5051611d9357fe5b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611deb57600080fd5b505af1158015611dff573d6000803e3d6000fd5b505050506040513d6020811015611e1557600080fd5b5051925034841015611e2d57611e2d33853403612311565b505096509650969350505050565b60608142811015611e81576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031686866000818110611eb857fe5b905060200201356001600160a01b03166001600160a01b031614611f11576040805162461bcd60e51b815260206004820152601b60248201526000805160206133cf833981519152604482015290519081900360640190fd5b611f6f7f000000000000000000000000000000000000000000000000000000000000000088888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612aa892505050565b91503482600081518110611f7f57fe5b60200260200101511115611fc45760405162461bcd60e51b81526004018080602001828103825260258152602001806134636025913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061200057fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561203357600080fd5b505af1158015612047573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6120ac7f00000000000000000000000000000000000000000000000000000000000000008989600081811061148b57fe5b846000815181106120b957fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561211057600080fd5b505af1158015612124573d6000803e3d6000fd5b505050506040513d602081101561213a57600080fd5b505161214257fe5b61218182878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612862915050565b8160008151811061218e57fe5b602002602001015134111561157d5761157d33836000815181106121ae57fe5b60200260200101513403612311565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b6020831061223a5780518252601f19909201916020918201910161221b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461229c576040519150601f19603f3d011682016040523d82523d6000602084013e6122a1565b606091505b50915091508180156122cf5750805115806122cf57508080602001905160208110156122cc57600080fd5b50515b61230a5760405162461bcd60e51b815260040180806020018281038252602d815260200180613436602d913960400191505060405180910390fd5b5050505050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b6020831061235d5780518252601f19909201916020918201910161233e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146123bf576040519150601f19603f3d011682016040523d82523d6000602084013e6123c4565b606091505b50509050806124045760405162461bcd60e51b815260040180806020018281038252603481526020018061332f6034913960400191505060405180910390fd5b505050565b60008084116124495760405162461bcd60e51b81526004018080602001828103825260298152602001806132ab6029913960400191505060405180910390fd5b6000831180156124595750600082115b6124945760405162461bcd60e51b81526004018080602001828103825260268152602001806134886026913960400191505060405180910390fd5b60006124a8856103e663ffffffff612fde16565b905060006124bc828563ffffffff612fde16565b905060006124e2836124d6886103e863ffffffff612fde16565b9063ffffffff61304116565b90508082816124ed57fe5b04979650505050505050565b6060600282511015612552576040805162461bcd60e51b815260206004820152601c60248201527f50616e63616b654c6962726172793a20494e56414c49445f5041544800000000604482015290519081900360640190fd5b815167ffffffffffffffff8111801561256a57600080fd5b50604051908082528060200260200182016040528015612594578160200160208202803683370190505b50905082816000815181106125a557fe5b60200260200101818152505060005b600183510381101561263d576000806125f7878685815181106125d357fe5b60200260200101518786600101815181106125ea57fe5b6020026020010151613090565b9150915061261984848151811061260a57fe5b60200260200101518383612409565b84846001018151811061262857fe5b602090810291909101015250506001016125b4565b509392505050565b60008060006126548585612c8c565b604080516bffffffffffffffffffffffff19606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501206001600160f81b031960688401529a90941b9093166069840152607d8301989098527fd448cceaaa67bd95c8e223ea7b9d9c2fcb281345e9954872d965bc6f51882f0d609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b6020831061278a5780518252601f19909201916020918201910161276b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146127ec576040519150601f19603f3d011682016040523d82523d6000602084013e6127f1565b606091505b509150915081801561281f57508051158061281f575080806020019051602081101561281c57600080fd5b50515b61285a5760405162461bcd60e51b81526004018080602001828103825260318152602001806132fe6031913960400191505060405180910390fd5b505050505050565b60005b6001835103811015612aa25760008084838151811061288057fe5b602002602001015185846001018151811061289757fe5b60200260200101519150915060006128af8383612c8c565b50905060008785600101815181106128c357fe5b60200260200101519050600080836001600160a01b0316866001600160a01b0316146128f1578260006128f5565b6000835b91509150600060028a5103881061290c578861294d565b61294d7f0000000000000000000000000000000000000000000000000000000000000000878c8b6002018151811061294057fe5b6020026020010151612645565b905061297a7f00000000000000000000000000000000000000000000000000000000000000008888612645565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f1916602001820160405280156129b7576020820181803683370190505b506040518563ffffffff1660e01b815260040180858152602001848152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612a28578181015183820152602001612a10565b50505050905090810190601f168015612a555780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015612a7757600080fd5b505af1158015612a8b573d6000803e3d6000fd5b505060019099019850612865975050505050505050565b50505050565b6060600282511015612b01576040805162461bcd60e51b815260206004820152601c60248201527f50616e63616b654c6962726172793a20494e56414c49445f5041544800000000604482015290519081900360640190fd5b815167ffffffffffffffff81118015612b1957600080fd5b50604051908082528060200260200182016040528015612b43578160200160208202803683370190505b5090508281600183510381518110612b5757fe5b60209081029190910101528151600019015b801561263d57600080612b9987866001860381518110612b8557fe5b60200260200101518786815181106125ea57fe5b91509150612bbb848481518110612bac57fe5b6020026020010151838361316a565b846001850381518110612bca57fe5b6020908102919091010152505060001901612b69565b6000808411612c205760405162461bcd60e51b81526004018080602001828103825260238152602001806134136023913960400191505060405180910390fd5b600083118015612c305750600082115b612c6b5760405162461bcd60e51b81526004018080602001828103825260268152602001806134886026913960400191505060405180910390fd5b82612c7c858463ffffffff612fde16565b81612c8357fe5b04949350505050565b600080826001600160a01b0316846001600160a01b03161415612ce05760405162461bcd60e51b81526004018080602001828103825260238152602001806133ac6023913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b031610612d00578284612d03565b83835b90925090506001600160a01b038216612d63576040805162461bcd60e51b815260206004820152601c60248201527f50616e63616b654c6962726172793a205a45524f5f4144445245535300000000604482015290519081900360640190fd5b9250929050565b6040805163e6a4390560e01b81526001600160a01b03888116600483015287811660248301529151600092839283927f00000000000000000000000000000000000000000000000000000000000000009092169163e6a4390591604480820192602092909190829003018186803b158015612de457600080fd5b505afa158015612df8573d6000803e3d6000fd5b505050506040513d6020811015612e0e57600080fd5b50516001600160a01b03161415612ec157604080516364e329cb60e11b81526001600160a01b038a81166004830152898116602483015291517f00000000000000000000000000000000000000000000000000000000000000009092169163c9c65396916044808201926020929091908290030181600087803b158015612e9457600080fd5b505af1158015612ea8573d6000803e3d6000fd5b505050506040513d6020811015612ebe57600080fd5b50505b600080612eef7f00000000000000000000000000000000000000000000000000000000000000008b8b613090565b91509150816000148015612f01575080155b15612f1157879350869250612fd1565b6000612f1e898484612be0565b9050878111612f715785811015612f665760405162461bcd60e51b81526004018080602001828103825260248152602001806134ae6024913960400191505060405180910390fd5b889450925082612fcf565b6000612f7e898486612be0565b905089811115612f8a57fe5b87811015612fc95760405162461bcd60e51b81526004018080602001828103825260248152602001806133ef6024913960400191505060405180910390fd5b94508793505b505b5050965096945050505050565b6000811580612ff957505080820282828281612ff657fe5b04145b610e40576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b80820182811015610e40576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b600080600061309f8585612c8c565b5090506130ad868686612645565b506000806130bc888888612645565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156130f457600080fd5b505afa158015613108573d6000803e3d6000fd5b505050506040513d606081101561311e57600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506001600160a01b038781169084161461315857808261315b565b81815b90999098509650505050505050565b60008084116131aa5760405162461bcd60e51b815260040180806020018281038252602a8152602001806132d4602a913960400191505060405180910390fd5b6000831180156131ba5750600082115b6131f55760405162461bcd60e51b81526004018080602001828103825260268152602001806134886026913960400191505060405180910390fd5b60006132196103e861320d868863ffffffff612fde16565b9063ffffffff612fde16565b905060006132336103e661320d868963ffffffff61325a16565b9050613250600182848161324357fe5b049063ffffffff61304116565b9695505050505050565b80820382811115610e40576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fdfe50616e63616b654c6962726172793a20494e53554646494349454e545f494e5055545f414d4f554e5450616e63616b654c6962726172793a20494e53554646494349454e545f4f55545055545f414d4f554e545472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472616e7366657246726f6d206661696c65645472616e7366657248656c7065723a3a736166655472616e736665724554483a20455448207472616e73666572206661696c656450616e63616b65526f757465723a20455850495245440000000000000000000050616e63616b65526f757465723a20494e53554646494349454e545f4f55545055545f414d4f554e5450616e63616b654c6962726172793a204944454e544943414c5f41444452455353455350616e63616b65526f757465723a20494e56414c49445f50415448000000000050616e63616b65526f757465723a20494e53554646494349454e545f415f414d4f554e5450616e63616b654c6962726172793a20494e53554646494349454e545f414d4f554e545472616e7366657248656c7065723a3a736166655472616e736665723a207472616e73666572206661696c656450616e63616b65526f757465723a204558434553534956455f494e5055545f414d4f554e5450616e63616b654c6962726172793a20494e53554646494349454e545f4c495155494449545950616e63616b65526f757465723a20494e53554646494349454e545f425f414d4f554e54a26469706673582212206a0cde0aded7caa13bf75ce0385df856bf83a3d5f2e29abae51711db573b63a364736f6c63430006060033000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c9

Deployed ByteCode

0x6080604052600436106101185760003560e01c80638803dbee116100a0578063d06ca61f11610064578063d06ca61f14610742578063ded9382a146107f7578063e8e337001461086a578063f305d719146108ea578063fb3bdb411461093057610151565b80638803dbee146105d3578063ad5c464814610669578063ad615dec1461069a578063baa2abde146106d0578063c45a01551461072d57610151565b80632195995c116100e75780632195995c146103a557806338ed1739146104235780634a25d94a146104b95780637ff36ab51461054f57806385f8c259146101c257610151565b806302751cec14610156578063054d50d4146101c257806318cbafe51461020a5780631f00ca74146102f057610151565b3661015157336001600160a01b037f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c9161461014f57fe5b005b600080fd5b34801561016257600080fd5b506101a9600480360360c081101561017957600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a001356109b4565b6040805192835260208301919091528051918290030190f35b3480156101ce57600080fd5b506101f8600480360360608110156101e557600080fd5b5080359060208101359060400135610ace565b60408051918252519081900360200190f35b34801561021657600080fd5b506102a0600480360360a081101561022d57600080fd5b813591602081013591810190606081016040820135600160201b81111561025357600080fd5b82018360208201111561026557600080fd5b803590602001918460208302840111600160201b8311171561028657600080fd5b91935091506001600160a01b038135169060200135610ae3565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156102dc5781810151838201526020016102c4565b505050509050019250505060405180910390f35b3480156102fc57600080fd5b506102a06004803603604081101561031357600080fd5b81359190810190604081016020820135600160201b81111561033457600080fd5b82018360208201111561034657600080fd5b803590602001918460208302840111600160201b8311171561036757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610e10945050505050565b3480156103b157600080fd5b506101a960048036036101608110156103c957600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c08101359060e081013515159060ff6101008201351690610120810135906101400135610e46565b34801561042f57600080fd5b506102a0600480360360a081101561044657600080fd5b813591602081013591810190606081016040820135600160201b81111561046c57600080fd5b82018360208201111561047e57600080fd5b803590602001918460208302840111600160201b8311171561049f57600080fd5b91935091506001600160a01b038135169060200135610f40565b3480156104c557600080fd5b506102a0600480360360a08110156104dc57600080fd5b813591602081013591810190606081016040820135600160201b81111561050257600080fd5b82018360208201111561051457600080fd5b803590602001918460208302840111600160201b8311171561053557600080fd5b91935091506001600160a01b03813516906020013561108b565b6102a06004803603608081101561056557600080fd5b81359190810190604081016020820135600160201b81111561058657600080fd5b82018360208201111561059857600080fd5b803590602001918460208302840111600160201b831117156105b957600080fd5b91935091506001600160a01b038135169060200135611217565b3480156105df57600080fd5b506102a0600480360360a08110156105f657600080fd5b813591602081013591810190606081016040820135600160201b81111561061c57600080fd5b82018360208201111561062e57600080fd5b803590602001918460208302840111600160201b8311171561064f57600080fd5b91935091506001600160a01b038135169060200135611587565b34801561067557600080fd5b5061067e611680565b604080516001600160a01b039092168252519081900360200190f35b3480156106a657600080fd5b506101f8600480360360608110156106bd57600080fd5b50803590602081013590604001356116a4565b3480156106dc57600080fd5b506101a9600480360360e08110156106f357600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c001356116b1565b34801561073957600080fd5b5061067e6118f5565b34801561074e57600080fd5b506102a06004803603604081101561076557600080fd5b81359190810190604081016020820135600160201b81111561078657600080fd5b82018360208201111561079857600080fd5b803590602001918460208302840111600160201b831117156107b957600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611919945050505050565b34801561080357600080fd5b506101a9600480360361014081101561081b57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e08201351690610100810135906101200135611946565b34801561087657600080fd5b506108cc600480360361010081101561088e57600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359160c0820135169060e00135611a5a565b60408051938452602084019290925282820152519081900360600190f35b6108cc600480360360c081101561090057600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135611b96565b6102a06004803603608081101561094657600080fd5b81359190810190604081016020820135600160201b81111561096757600080fd5b82018360208201111561097957600080fd5b803590602001918460208302840111600160201b8311171561099a57600080fd5b91935091506001600160a01b038135169060200135611e3b565b60008082428110156109fb576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b610a2a897f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c98a8a8a308a6116b1565b9093509150610a3a8986856121bd565b7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610aa057600080fd5b505af1158015610ab4573d6000803e3d6000fd5b50505050610ac28583612311565b50965096945050505050565b6000610adb848484612409565b949350505050565b60608142811015610b29576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b6001600160a01b037f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c91686866000198101818110610b6357fe5b905060200201356001600160a01b03166001600160a01b031614610bbc576040805162461bcd60e51b815260206004820152601b60248201526000805160206133cf833981519152604482015290519081900360640190fd5b610c1a7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506124f992505050565b91508682600184510381518110610c2d57fe5b60200260200101511015610c725760405162461bcd60e51b81526004018080602001828103825260298152602001806133836029913960400191505060405180910390fd5b610d1086866000818110610c8257fe5b905060200201356001600160a01b031633610cf67f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8a8a6000818110610cc457fe5b905060200201356001600160a01b03168b8b6001818110610ce157fe5b905060200201356001600160a01b0316612645565b85600081518110610d0357fe5b6020026020010151612705565b610d4f82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250612862915050565b7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b0316632e1a7d4d83600185510381518110610d8e57fe5b60200260200101516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610dcc57600080fd5b505af1158015610de0573d6000803e3d6000fd5b50505050610e058483600185510381518110610df857fe5b6020026020010151612311565b509695505050505050565b6060610e3d7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8484612aa8565b90505b92915050565b6000806000610e767f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8f8f612645565b9050600087610e85578c610e89565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b158015610eff57600080fd5b505af1158015610f13573d6000803e3d6000fd5b50505050610f268f8f8f8f8f8f8f6116b1565b809450819550505050509b509b9950505050505050505050565b60608142811015610f86576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b610fe47f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506124f992505050565b91508682600184510381518110610ff757fe5b6020026020010151101561103c5760405162461bcd60e51b81526004018080602001828103825260298152602001806133836029913960400191505060405180910390fd5b61104c86866000818110610c8257fe5b610e0582878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612862915050565b606081428110156110d1576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b6001600160a01b037f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c9168686600019810181811061110b57fe5b905060200201356001600160a01b03166001600160a01b031614611164576040805162461bcd60e51b815260206004820152601b60248201526000805160206133cf833981519152604482015290519081900360640190fd5b6111c27f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f89888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612aa892505050565b915086826000815181106111d257fe5b60200260200101511115610c725760405162461bcd60e51b81526004018080602001828103825260258152602001806134636025913960400191505060405180910390fd5b6060814281101561125d576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b03168686600081811061129457fe5b905060200201356001600160a01b03166001600160a01b0316146112ed576040805162461bcd60e51b815260206004820152601b60248201526000805160206133cf833981519152604482015290519081900360640190fd5b61134b7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f348888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506124f992505050565b9150868260018451038151811061135e57fe5b602002602001015110156113a35760405162461bcd60e51b81526004018080602001828103825260298152602001806133836029913960400191505060405180910390fd5b7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b031663d0e30db0836000815181106113df57fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561141257600080fd5b505af1158015611426573d6000803e3d6000fd5b50505050507f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b031663a9059cbb6114a87f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8989600081811061148b57fe5b905060200201356001600160a01b03168a8a6001818110610ce157fe5b846000815181106114b557fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561150c57600080fd5b505af1158015611520573d6000803e3d6000fd5b505050506040513d602081101561153657600080fd5b505161153e57fe5b61157d82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612862915050565b5095945050505050565b606081428110156115cd576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b61162b7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f89888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612aa892505050565b9150868260008151811061163b57fe5b6020026020010151111561103c5760405162461bcd60e51b81526004018080602001828103825260258152602001806134636025913960400191505060405180910390fd5b7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c981565b6000610adb848484612be0565b60008082428110156116f8576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b60006117257f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8c8c612645565b604080516323b872dd60e01b81523360048201526001600160a01b03831660248201819052604482018d9052915192935090916323b872dd916064808201926020929091908290030181600087803b15801561178057600080fd5b505af1158015611794573d6000803e3d6000fd5b505050506040513d60208110156117aa57600080fd5b50506040805163226bf2d160e21b81526001600160a01b03888116600483015282516000938493928616926389afcb44926024808301939282900301818787803b1580156117f757600080fd5b505af115801561180b573d6000803e3d6000fd5b505050506040513d604081101561182157600080fd5b5080516020909101519092509050600061183b8e8e612c8c565b509050806001600160a01b03168e6001600160a01b03161461185e578183611861565b82825b90975095508a8710156118a55760405162461bcd60e51b81526004018080602001828103825260248152602001806133ef6024913960400191505060405180910390fd5b898610156118e45760405162461bcd60e51b81526004018080602001828103825260248152602001806134ae6024913960400191505060405180910390fd5b505050505097509795505050505050565b7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f81565b6060610e3d7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f84846124f9565b60008060006119967f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8e7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c9612645565b90506000876119a5578c6119a9565b6000195b6040805163d505accf60e01b815233600482015230602482015260448101839052606481018c905260ff8a16608482015260a4810189905260c4810188905290519192506001600160a01b0384169163d505accf9160e48082019260009290919082900301818387803b158015611a1f57600080fd5b505af1158015611a33573d6000803e3d6000fd5b50505050611a458e8e8e8e8e8e6109b4565b909f909e509c50505050505050505050505050565b60008060008342811015611aa3576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b611ab18c8c8c8c8c8c612d6a565b90945092506000611ae37f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8e8e612645565b9050611af18d338388612705565b611afd8c338387612705565b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611b5557600080fd5b505af1158015611b69573d6000803e3d6000fd5b505050506040513d6020811015611b7f57600080fd5b5051949d939c50939a509198505050505050505050565b60008060008342811015611bdf576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b611c0d8a7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c98b348c8c612d6a565b90945092506000611c5f7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8c7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c9612645565b9050611c6d8b338388612705565b7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015611cc857600080fd5b505af1158015611cdc573d6000803e3d6000fd5b50505050507f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b031663a9059cbb82866040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015611d6157600080fd5b505af1158015611d75573d6000803e3d6000fd5b505050506040513d6020811015611d8b57600080fd5b5051611d9357fe5b806001600160a01b0316636a627842886040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b03168152602001915050602060405180830381600087803b158015611deb57600080fd5b505af1158015611dff573d6000803e3d6000fd5b505050506040513d6020811015611e1557600080fd5b5051925034841015611e2d57611e2d33853403612311565b505096509650969350505050565b60608142811015611e81576040805162461bcd60e51b81526020600482015260166024820152600080516020613363833981519152604482015290519081900360640190fd5b7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b031686866000818110611eb857fe5b905060200201356001600160a01b03166001600160a01b031614611f11576040805162461bcd60e51b815260206004820152601b60248201526000805160206133cf833981519152604482015290519081900360640190fd5b611f6f7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f88888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612aa892505050565b91503482600081518110611f7f57fe5b60200260200101511115611fc45760405162461bcd60e51b81526004018080602001828103825260258152602001806134636025913960400191505060405180910390fd5b7f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b031663d0e30db08360008151811061200057fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561203357600080fd5b505af1158015612047573d6000803e3d6000fd5b50505050507f000000000000000000000000f194afdf50b03e69bd7d057c1aa9e10c9954e4c96001600160a01b031663a9059cbb6120ac7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8989600081811061148b57fe5b846000815181106120b957fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561211057600080fd5b505af1158015612124573d6000803e3d6000fd5b505050506040513d602081101561213a57600080fd5b505161214257fe5b61218182878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250612862915050565b8160008151811061218e57fe5b602002602001015134111561157d5761157d33836000815181106121ae57fe5b60200260200101513403612311565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b178152925182516000946060949389169392918291908083835b6020831061223a5780518252601f19909201916020918201910161221b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461229c576040519150601f19603f3d011682016040523d82523d6000602084013e6122a1565b606091505b50915091508180156122cf5750805115806122cf57508080602001905160208110156122cc57600080fd5b50515b61230a5760405162461bcd60e51b815260040180806020018281038252602d815260200180613436602d913960400191505060405180910390fd5b5050505050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b6020831061235d5780518252601f19909201916020918201910161233e565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146123bf576040519150601f19603f3d011682016040523d82523d6000602084013e6123c4565b606091505b50509050806124045760405162461bcd60e51b815260040180806020018281038252603481526020018061332f6034913960400191505060405180910390fd5b505050565b60008084116124495760405162461bcd60e51b81526004018080602001828103825260298152602001806132ab6029913960400191505060405180910390fd5b6000831180156124595750600082115b6124945760405162461bcd60e51b81526004018080602001828103825260268152602001806134886026913960400191505060405180910390fd5b60006124a8856103e663ffffffff612fde16565b905060006124bc828563ffffffff612fde16565b905060006124e2836124d6886103e863ffffffff612fde16565b9063ffffffff61304116565b90508082816124ed57fe5b04979650505050505050565b6060600282511015612552576040805162461bcd60e51b815260206004820152601c60248201527f50616e63616b654c6962726172793a20494e56414c49445f5041544800000000604482015290519081900360640190fd5b815167ffffffffffffffff8111801561256a57600080fd5b50604051908082528060200260200182016040528015612594578160200160208202803683370190505b50905082816000815181106125a557fe5b60200260200101818152505060005b600183510381101561263d576000806125f7878685815181106125d357fe5b60200260200101518786600101815181106125ea57fe5b6020026020010151613090565b9150915061261984848151811061260a57fe5b60200260200101518383612409565b84846001018151811061262857fe5b602090810291909101015250506001016125b4565b509392505050565b60008060006126548585612c8c565b604080516bffffffffffffffffffffffff19606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501206001600160f81b031960688401529a90941b9093166069840152607d8301989098527fd448cceaaa67bd95c8e223ea7b9d9c2fcb281345e9954872d965bc6f51882f0d609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17815292518251600094606094938a169392918291908083835b6020831061278a5780518252601f19909201916020918201910161276b565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146127ec576040519150601f19603f3d011682016040523d82523d6000602084013e6127f1565b606091505b509150915081801561281f57508051158061281f575080806020019051602081101561281c57600080fd5b50515b61285a5760405162461bcd60e51b81526004018080602001828103825260318152602001806132fe6031913960400191505060405180910390fd5b505050505050565b60005b6001835103811015612aa25760008084838151811061288057fe5b602002602001015185846001018151811061289757fe5b60200260200101519150915060006128af8383612c8c565b50905060008785600101815181106128c357fe5b60200260200101519050600080836001600160a01b0316866001600160a01b0316146128f1578260006128f5565b6000835b91509150600060028a5103881061290c578861294d565b61294d7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f878c8b6002018151811061294057fe5b6020026020010151612645565b905061297a7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8888612645565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f1916602001820160405280156129b7576020820181803683370190505b506040518563ffffffff1660e01b815260040180858152602001848152602001836001600160a01b03166001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015612a28578181015183820152602001612a10565b50505050905090810190601f168015612a555780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015612a7757600080fd5b505af1158015612a8b573d6000803e3d6000fd5b505060019099019850612865975050505050505050565b50505050565b6060600282511015612b01576040805162461bcd60e51b815260206004820152601c60248201527f50616e63616b654c6962726172793a20494e56414c49445f5041544800000000604482015290519081900360640190fd5b815167ffffffffffffffff81118015612b1957600080fd5b50604051908082528060200260200182016040528015612b43578160200160208202803683370190505b5090508281600183510381518110612b5757fe5b60209081029190910101528151600019015b801561263d57600080612b9987866001860381518110612b8557fe5b60200260200101518786815181106125ea57fe5b91509150612bbb848481518110612bac57fe5b6020026020010151838361316a565b846001850381518110612bca57fe5b6020908102919091010152505060001901612b69565b6000808411612c205760405162461bcd60e51b81526004018080602001828103825260238152602001806134136023913960400191505060405180910390fd5b600083118015612c305750600082115b612c6b5760405162461bcd60e51b81526004018080602001828103825260268152602001806134886026913960400191505060405180910390fd5b82612c7c858463ffffffff612fde16565b81612c8357fe5b04949350505050565b600080826001600160a01b0316846001600160a01b03161415612ce05760405162461bcd60e51b81526004018080602001828103825260238152602001806133ac6023913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b031610612d00578284612d03565b83835b90925090506001600160a01b038216612d63576040805162461bcd60e51b815260206004820152601c60248201527f50616e63616b654c6962726172793a205a45524f5f4144445245535300000000604482015290519081900360640190fd5b9250929050565b6040805163e6a4390560e01b81526001600160a01b03888116600483015287811660248301529151600092839283927f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f9092169163e6a4390591604480820192602092909190829003018186803b158015612de457600080fd5b505afa158015612df8573d6000803e3d6000fd5b505050506040513d6020811015612e0e57600080fd5b50516001600160a01b03161415612ec157604080516364e329cb60e11b81526001600160a01b038a81166004830152898116602483015291517f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f9092169163c9c65396916044808201926020929091908290030181600087803b158015612e9457600080fd5b505af1158015612ea8573d6000803e3d6000fd5b505050506040513d6020811015612ebe57600080fd5b50505b600080612eef7f000000000000000000000000d8b138566f0ca771b9fedf6f714e284e6155334f8b8b613090565b91509150816000148015612f01575080155b15612f1157879350869250612fd1565b6000612f1e898484612be0565b9050878111612f715785811015612f665760405162461bcd60e51b81526004018080602001828103825260248152602001806134ae6024913960400191505060405180910390fd5b889450925082612fcf565b6000612f7e898486612be0565b905089811115612f8a57fe5b87811015612fc95760405162461bcd60e51b81526004018080602001828103825260248152602001806133ef6024913960400191505060405180910390fd5b94508793505b505b5050965096945050505050565b6000811580612ff957505080820282828281612ff657fe5b04145b610e40576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b80820182811015610e40576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b600080600061309f8585612c8c565b5090506130ad868686612645565b506000806130bc888888612645565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156130f457600080fd5b505afa158015613108573d6000803e3d6000fd5b505050506040513d606081101561311e57600080fd5b5080516020909101516dffffffffffffffffffffffffffff91821693501690506001600160a01b038781169084161461315857808261315b565b81815b90999098509650505050505050565b60008084116131aa5760405162461bcd60e51b815260040180806020018281038252602a8152602001806132d4602a913960400191505060405180910390fd5b6000831180156131ba5750600082115b6131f55760405162461bcd60e51b81526004018080602001828103825260268152602001806134886026913960400191505060405180910390fd5b60006132196103e861320d868863ffffffff612fde16565b9063ffffffff612fde16565b905060006132336103e661320d868963ffffffff61325a16565b9050613250600182848161324357fe5b049063ffffffff61304116565b9695505050505050565b80820382811115610e40576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fdfe50616e63616b654c6962726172793a20494e53554646494349454e545f494e5055545f414d4f554e5450616e63616b654c6962726172793a20494e53554646494349454e545f4f55545055545f414d4f554e545472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472616e7366657246726f6d206661696c65645472616e7366657248656c7065723a3a736166655472616e736665724554483a20455448207472616e73666572206661696c656450616e63616b65526f757465723a20455850495245440000000000000000000050616e63616b65526f757465723a20494e53554646494349454e545f4f55545055545f414d4f554e5450616e63616b654c6962726172793a204944454e544943414c5f41444452455353455350616e63616b65526f757465723a20494e56414c49445f50415448000000000050616e63616b65526f757465723a20494e53554646494349454e545f415f414d4f554e5450616e63616b654c6962726172793a20494e53554646494349454e545f414d4f554e545472616e7366657248656c7065723a3a736166655472616e736665723a207472616e73666572206661696c656450616e63616b65526f757465723a204558434553534956455f494e5055545f414d4f554e5450616e63616b654c6962726172793a20494e53554646494349454e545f4c495155494449545950616e63616b65526f757465723a20494e53554646494349454e545f425f414d4f554e54a26469706673582212206a0cde0aded7caa13bf75ce0385df856bf83a3d5f2e29abae51711db573b63a364736f6c63430006060033