ETH Price: $1,792.70 (+13.52%)
 

Overview

ETH Balance

Scroll LogoScroll LogoScroll Logo0 ETH

ETH Value

$0.00

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
0x052e0a3c04ef5a8903adedfe3260fb35ab56981cd5f84bab7b08a60ac9f7208d -(pending)2025-04-23 0:50:452 hrs ago1745369445IN
Tokan Exchange: Router
0 ETH(Pending)(Pending)
Remove Liquidity146148022025-04-10 16:26:4912 days ago1744302409IN
Tokan Exchange: Router
0 ETH0.00001570.04058211
Remove Liquidity146148012025-04-10 16:26:4612 days ago1744302406IN
Tokan Exchange: Router
0 ETH0.000020220.04067031
Add Liquidity146147742025-04-10 16:25:2512 days ago1744302325IN
Tokan Exchange: Router
0 ETH0.000023790.04391566
Remove Liquidity146147172025-04-10 16:22:3412 days ago1744302154IN
Tokan Exchange: Router
0 ETH0.000023910.04045875
Remove Liquidity146139672025-04-10 15:45:0412 days ago1744299904IN
Tokan Exchange: Router
0 ETH0.000015570.04146622
Add Liquidity146139532025-04-10 15:44:2212 days ago1744299862IN
Tokan Exchange: Router
0 ETH0.000018380.04157943
Remove Liquidity146069002025-04-10 9:51:4312 days ago1744278703IN
Tokan Exchange: Router
0 ETH0.000006920.03929895
Add Liquidity146068902025-04-10 9:51:1312 days ago1744278673IN
Tokan Exchange: Router
0 ETH0.000006860.0392976
Add Liquidity146068822025-04-10 9:50:4912 days ago1744278649IN
Tokan Exchange: Router
0 ETH0.000007530.03929769
Remove Liquidity146068602025-04-10 9:49:4312 days ago1744278583IN
Tokan Exchange: Router
0 ETH0.000006730.03929771
Remove Liquidity146068532025-04-10 9:49:2212 days ago1744278562IN
Tokan Exchange: Router
0 ETH0.000006920.03929771
Remove Liquidity146068432025-04-10 9:48:5212 days ago1744278532IN
Tokan Exchange: Router
0 ETH0.000006890.03928796
Add Liquidity146068292025-04-10 9:48:1012 days ago1744278490IN
Tokan Exchange: Router
0 ETH0.000006850.03929412
Add Liquidity146068262025-04-10 9:48:0112 days ago1744278481IN
Tokan Exchange: Router
0 ETH0.000006850.03929412
Remove Liquidity146068012025-04-10 9:46:4612 days ago1744278406IN
Tokan Exchange: Router
0 ETH0.000006940.03930263
Add Liquidity146067692025-04-10 9:45:1012 days ago1744278310IN
Tokan Exchange: Router
0 ETH0.000006850.0392945
Remove Liquidity146067002025-04-10 9:41:4312 days ago1744278103IN
Tokan Exchange: Router
0 ETH0.000001260.03932327
Remove Liquidity146066112025-04-10 9:37:1612 days ago1744277836IN
Tokan Exchange: Router
0 ETH0.000001250.03932181
Remove Liquidity146064912025-04-10 9:31:1612 days ago1744277476IN
Tokan Exchange: Router
0 ETH0.000001240.03931817
Add Liquidity146063922025-04-10 9:26:1912 days ago1744277179IN
Tokan Exchange: Router
0 ETH0.000010270.03929878
Remove Liquidity145900472025-04-09 19:49:0413 days ago1744228144IN
Tokan Exchange: Router
0 ETH0.000012920.0398681
Remove Liquidity145898092025-04-09 19:37:1013 days ago1744227430IN
Tokan Exchange: Router
0 ETH0.000004260.04001575
Remove Liquidity145896732025-04-09 19:30:2213 days ago1744227022IN
Tokan Exchange: Router
0 ETH0.000005650.04019257
Remove Liquidity145896252025-04-09 19:27:5813 days ago1744226878IN
Tokan Exchange: Router
0 ETH0.000006270.04025947
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
143478572025-04-01 9:59:2421 days ago1743501564
Tokan Exchange: Router
0.00002116 ETH
143478572025-04-01 9:59:2421 days ago1743501564
Tokan Exchange: Router
0.00002116 ETH
143321522025-03-31 13:29:3622 days ago1743427776
Tokan Exchange: Router
0.0000087 ETH
143321522025-03-31 13:29:3622 days ago1743427776
Tokan Exchange: Router
0.0000087 ETH
143170422025-03-30 17:37:4223 days ago1743356262
Tokan Exchange: Router
0.00009147 ETH
143170422025-03-30 17:37:4223 days ago1743356262
Tokan Exchange: Router
0.00009147 ETH
143167382025-03-30 17:16:0023 days ago1743354960
Tokan Exchange: Router
0.00002648 ETH
143167382025-03-30 17:16:0023 days ago1743354960
Tokan Exchange: Router
0.00002648 ETH
143167292025-03-30 17:15:3123 days ago1743354931
Tokan Exchange: Router
0.0001043 ETH
143167292025-03-30 17:15:3123 days ago1743354931
Tokan Exchange: Router
0.0001043 ETH
143166702025-03-30 17:11:2623 days ago1743354686
Tokan Exchange: Router
0.00015979 ETH
143166702025-03-30 17:11:2623 days ago1743354686
Tokan Exchange: Router
0.00015979 ETH
143164482025-03-30 16:56:1723 days ago1743353777
Tokan Exchange: Router
0.000192 ETH
143164482025-03-30 16:56:1723 days ago1743353777
Tokan Exchange: Router
0.000192 ETH
143158942025-03-30 16:13:1823 days ago1743351198
Tokan Exchange: Router
0.00002439 ETH
143158942025-03-30 16:13:1823 days ago1743351198
Tokan Exchange: Router
0.00002439 ETH
143158842025-03-30 16:12:4323 days ago1743351163
Tokan Exchange: Router
0.00006812 ETH
143158842025-03-30 16:12:4323 days ago1743351163
Tokan Exchange: Router
0.00006812 ETH
143158272025-03-30 16:07:4623 days ago1743350866
Tokan Exchange: Router
0.00002506 ETH
143158272025-03-30 16:07:4623 days ago1743350866
Tokan Exchange: Router
0.00002506 ETH
143158022025-03-30 16:05:3423 days ago1743350734
Tokan Exchange: Router
0.0000205 ETH
143158022025-03-30 16:05:3423 days ago1743350734
Tokan Exchange: Router
0.0000205 ETH
143157792025-03-30 16:03:2723 days ago1743350607
Tokan Exchange: Router
0.00002506 ETH
143157792025-03-30 16:03:2723 days ago1743350607
Tokan Exchange: Router
0.00002506 ETH
143157692025-03-30 16:02:3723 days ago1743350557
Tokan Exchange: Router
0.00001253 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Router

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 200 runs

Other Settings:
shanghai EvmVersion
File 1 of 8 : Router.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/proxy/Clones.sol";

import "./interfaces/IPair.sol";
import "./interfaces/IPairFactory.sol";
import "./interfaces/IRouter.sol";
import "./interfaces/IWETH.sol";

contract Router is IRouter {
    struct route {
        address from;
        address to;
        bool stable;
    }

    address public immutable factory;
    IWETH public immutable weth;
    uint256 internal constant MINIMUM_LIQUIDITY = 10 ** 3;

    // create swap event with sender and amountIn for the referral event reader system
    event Swap(address indexed sender, uint256 amount0In, address _tokenIn, address indexed to);

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

    constructor(address _pairFactory, address _weth) {
        factory = _pairFactory;
        weth = IWETH(_weth);
    }

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

    function sortTokens(address tokenA, address tokenB) public pure returns (address token0, address token1) {
        require(tokenA != tokenB, "Router: IDENTICAL_ADDRESSES");
        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
        require(token0 != address(0), "Router: ZERO_ADDRESS");
    }

    function pairFor(address tokenA, address tokenB, bool stable) public view returns (address pair) {
        pair = IPairFactory(factory).getPair(tokenA, tokenB, stable);
    }

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

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

    // performs chained getAmountOut calculations on any number of pairs
    function getAmountOut(uint256 amountIn, address tokenIn, address tokenOut) external view returns (uint256 amount, bool stable) {
        address pair = pairFor(tokenIn, tokenOut, true);
        uint256 amountStable;
        uint256 amountVolatile;
        if (IPairFactory(factory).isPair(pair)) {
            amountStable = IPair(pair).getAmountOut(amountIn, tokenIn);
        }
        pair = pairFor(tokenIn, tokenOut, false);
        if (IPairFactory(factory).isPair(pair)) {
            amountVolatile = IPair(pair).getAmountOut(amountIn, tokenIn);
        }
        return amountStable > amountVolatile ? (amountStable, true) : (amountVolatile, false);
    }

    // performs chained getAmountOut calculations on any number of pairs
    function getAmountsOut(uint256 amountIn, route[] memory routes) public view returns (uint256[] memory amounts) {
        require(routes.length >= 1, "Router: INVALID_PATH");
        amounts = new uint256[](routes.length + 1);
        amounts[0] = amountIn;
        for (uint256 i = 0; i < routes.length; i++) {
            address pair = pairFor(routes[i].from, routes[i].to, routes[i].stable);
            if (IPairFactory(factory).isPair(pair)) {
                amounts[i + 1] = IPair(pair).getAmountOut(amounts[i], routes[i].from);
            }
        }
    }

    function isPair(address pair) external view returns (bool) {
        return IPairFactory(factory).isPair(pair);
    }

    function quoteAddLiquidity(
        address tokenA,
        address tokenB,
        bool stable,
        uint256 amountADesired,
        uint256 amountBDesired
    ) external view returns (uint256 amountA, uint256 amountB, uint256 liquidity) {
        // create the pair if it doesn't exist yet
        address _pair = IPairFactory(factory).getPair(tokenA, tokenB, stable);
        (uint256 reserveA, uint256 reserveB) = (0, 0);
        uint256 _totalSupply = 0;
        if (_pair != address(0)) {
            _totalSupply = IERC20(_pair).totalSupply();
            (reserveA, reserveB) = getReserves(tokenA, tokenB, stable);
        }
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
            liquidity = Math.sqrt(amountA * amountB) - MINIMUM_LIQUIDITY;
        } else {
            uint256 amountBOptimal = quoteLiquidity(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                (amountA, amountB) = (amountADesired, amountBOptimal);
                liquidity = Math.min((amountA * _totalSupply) / reserveA, (amountB * _totalSupply) / reserveB);
            } else {
                uint256 amountAOptimal = quoteLiquidity(amountBDesired, reserveB, reserveA);
                (amountA, amountB) = (amountAOptimal, amountBDesired);
                liquidity = Math.min((amountA * _totalSupply) / reserveA, (amountB * _totalSupply) / reserveB);
            }
        }
    }

    function quoteRemoveLiquidity(
        address tokenA,
        address tokenB,
        bool stable,
        uint256 liquidity
    ) external view returns (uint256 amountA, uint256 amountB) {
        // create the pair if it doesn't exist yet
        address _pair = IPairFactory(factory).getPair(tokenA, tokenB, stable);

        if (_pair == address(0)) {
            return (0, 0);
        }

        (uint256 reserveA, uint256 reserveB) = getReserves(tokenA, tokenB, stable);
        uint256 _totalSupply = IERC20(_pair).totalSupply();

        amountA = (liquidity * reserveA) / _totalSupply; // using balances ensures pro-rata distribution
        amountB = (liquidity * reserveB) / _totalSupply; // using balances ensures pro-rata distribution
    }

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

    function addLiquidity(
        address tokenA,
        address tokenB,
        bool stable,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256 amountA, uint256 amountB, uint256 liquidity) {
        (amountA, amountB) = _addLiquidity(tokenA, tokenB, stable, amountADesired, amountBDesired, amountAMin, amountBMin);
        address pair = pairFor(tokenA, tokenB, stable);
        _safeTransferFrom(tokenA, msg.sender, pair, amountA);
        _safeTransferFrom(tokenB, msg.sender, pair, amountB);
        liquidity = IPair(pair).mint(to);
    }

    function addLiquidityETH(
        address token,
        bool stable,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) external payable ensure(deadline) returns (uint256 amountToken, uint256 amountETH, uint256 liquidity) {
        (amountToken, amountETH) = _addLiquidity(token, address(weth), stable, amountTokenDesired, msg.value, amountTokenMin, amountETHMin);
        address pair = pairFor(token, address(weth), stable);
        _safeTransferFrom(token, msg.sender, pair, amountToken);
        weth.deposit{value: amountETH}();
        assert(weth.transfer(pair, amountETH));
        liquidity = IPair(pair).mint(to);
        // refund dust eth, if any
        if (msg.value > amountETH) _safeTransferETH(msg.sender, msg.value - amountETH);
    }

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

    function removeLiquidityETH(
        address token,
        bool stable,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    ) public ensure(deadline) returns (uint256 amountToken, uint256 amountETH) {
        (amountToken, amountETH) = removeLiquidity(
            token,
            address(weth),
            stable,
            liquidity,
            amountTokenMin,
            amountETHMin,
            address(this),
            deadline
        );
        _safeTransfer(token, to, amountToken);
        weth.withdraw(amountETH);
        _safeTransferETH(to, amountETH);
    }

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

        (amountA, amountB) = removeLiquidity(tokenA, tokenB, stable, liquidity, amountAMin, amountBMin, to, deadline);
    }

    function removeLiquidityETHWithPermit(
        address token,
        bool stable,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline,
        bool approveMax,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external returns (uint256 amountToken, uint256 amountETH) {
        address pair = pairFor(token, address(weth), stable);
        uint256 value = approveMax ? type(uint256).max : liquidity;
        IPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        (amountToken, amountETH) = removeLiquidityETH(token, stable, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }

    // **** SWAP ****
    // requires the initial amount to have already been sent to the first pair
    function _swap(uint256[] memory amounts, route[] memory routes, address _to) internal virtual {
        for (uint256 i = 0; i < routes.length; i++) {
            (address token0, ) = sortTokens(routes[i].from, routes[i].to);
            uint256 amountOut = amounts[i + 1];
            (uint256 amount0Out, uint256 amount1Out) = routes[i].from == token0 ? (uint256(0), amountOut) : (amountOut, uint256(0));
            address to = i < routes.length - 1 ? pairFor(routes[i + 1].from, routes[i + 1].to, routes[i + 1].stable) : _to;
            IPair(pairFor(routes[i].from, routes[i].to, routes[i].stable)).swap(amount0Out, amount1Out, to, new bytes(0));
        }
        emit Swap(msg.sender, amounts[0], routes[0].from, _to);
    }

    function swapExactTokensForTokensSimple(
        uint256 amountIn,
        uint256 amountOutMin,
        address tokenFrom,
        address tokenTo,
        bool stable,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256[] memory amounts) {
        route[] memory routes = new route[](1);
        routes[0].from = tokenFrom;
        routes[0].to = tokenTo;
        routes[0].stable = stable;
        amounts = getAmountsOut(amountIn, routes);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
        _safeTransferFrom(routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]);
        _swap(amounts, routes, to);
    }

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        route[] calldata routes,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256[] memory amounts) {
        amounts = getAmountsOut(amountIn, routes);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
        _safeTransferFrom(routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]);
        _swap(amounts, routes, to);
    }

    function swapExactETHForTokens(
        uint256 amountOutMin,
        route[] calldata routes,
        address to,
        uint256 deadline
    ) external payable ensure(deadline) returns (uint256[] memory amounts) {
        require(routes[0].from == address(weth), "Router: INVALID_PATH");
        amounts = getAmountsOut(msg.value, routes);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
        weth.deposit{value: amounts[0]}();
        assert(weth.transfer(pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]));
        _swap(amounts, routes, to);
    }

    function swapExactTokensForETH(
        uint256 amountIn,
        uint256 amountOutMin,
        route[] calldata routes,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256[] memory amounts) {
        require(routes[routes.length - 1].to == address(weth), "Router: INVALID_PATH");
        amounts = getAmountsOut(amountIn, routes);
        require(amounts[amounts.length - 1] >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
        _safeTransferFrom(routes[0].from, msg.sender, pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]);
        _swap(amounts, routes, address(this));
        weth.withdraw(amounts[amounts.length - 1]);
        _safeTransferETH(to, amounts[amounts.length - 1]);
    }

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

    function _safeTransfer(address token, address to, uint256 value) internal {
        if (value != 0) {
            require(token.code.length > 0);
            (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value));
            require(success && (data.length == 0 || abi.decode(data, (bool))));
        }
    }

    function _safeTransferFrom(address token, address from, address to, uint256 value) internal {
        if (value != 0) {
            require(token.code.length > 0);
            (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value));
            require(success && (data.length == 0 || abi.decode(data, (bool))));
        }
    }
}

File 2 of 8 : Clones.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)

pragma solidity ^0.8.0;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
 * deploying minimal proxy contracts, also known as "clones".
 *
 * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
 * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
 *
 * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
 * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
 * deterministic method.
 *
 * _Available since v3.4._
 */
library Clones {
    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function clone(address implementation) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
            // of the `implementation` address with the bytecode before the address.
            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
            instance := create(0, 0x09, 0x37)
        }
        require(instance != address(0), "ERC1167: create failed");
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create2 opcode and a `salt` to deterministically deploy
     * the clone. Using the same `implementation` and `salt` multiple time will revert, since
     * the clones cannot be deployed twice at the same address.
     */
    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
            // of the `implementation` address with the bytecode before the address.
            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
            instance := create2(0, 0x09, 0x37, salt)
        }
        require(instance != address(0), "ERC1167: create2 failed");
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(add(ptr, 0x38), deployer)
            mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
            mstore(add(ptr, 0x14), implementation)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
            mstore(add(ptr, 0x58), salt)
            mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
            predicted := keccak256(add(ptr, 0x43), 0x55)
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt
    ) internal view returns (address predicted) {
        return predictDeterministicAddress(implementation, salt, address(this));
    }
}

File 3 of 8 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
}

File 4 of 8 : Math.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
        }
    }
}

File 5 of 8 : IPair.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IPair {

    function metadata() external view returns (uint256 dec0, uint256 dec1, uint256 r0, uint256 r1, bool st, address t0, address t1);

    function claimFees() external returns (uint256, uint256);

    function tokens() external view returns (address, address);

    function token0() external view returns (address);

    function token1() external view returns (address);

    function transferFrom(address src, address dst, uint256 amount) external returns (bool);

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

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

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

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

    function getReserves() external view returns (uint256 _reserve0, uint256 _reserve1, uint256 _blockTimestampLast);

    function getAmountOut(uint256, address) external view returns (uint256);

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

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

    function totalSupply() external view returns (uint256);

    function decimals() external view returns (uint8);

    function claimable0(address _user) external view returns (uint256);

    function claimable1(address _user) external view returns (uint256);

    function stable() external view returns (bool);

    function pairFee() external view returns (uint256);
}

File 6 of 8 : IPairFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IPairFactory {
    function allPairsLength() external view returns (uint256);

    function isPair(address pair) external view returns (bool);

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

    function getPair(address tokenA, address token, bool stable) external view returns (address);

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

    function getFeeAmount(uint256 _amount, address _account, uint256 _fee) external view returns (uint256);

    function stableFee() external view returns (uint256);

    function volatileFee() external view returns (uint256);

    function isPrivileged(address _account) external view returns (bool);
}

File 7 of 8 : IRouter.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IRouter {
    function pairFor(address tokenA, address tokenB, bool stable) external view returns (address pair);
}

File 8 of 8 : IWETH.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IWETH {
    function deposit() external payable;

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

    function withdraw(uint256) external;
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_pairFactory","type":"address"},{"internalType":"address","name":"_weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"address","name":"_tokenIn","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Swap","type":"event"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"stable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"getReserves","outputs":[{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"isPair","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"pairFor","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"}],"name":"quoteAddLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"name":"quoteRemoveLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"sortTokens","outputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct Router.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address","name":"tokenFrom","type":"address"},{"internalType":"address","name":"tokenTo","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSimple","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c060405234801562000010575f80fd5b506040516200370238038062003702833981016040819052620000339162000067565b6001600160a01b039182166080521660a0526200009d565b80516001600160a01b038116811462000062575f80fd5b919050565b5f806040838503121562000079575f80fd5b62000084836200004b565b915062000094602084016200004b565b90509250929050565b60805160a0516135a9620001595f395f818161012e015281816101f6015281816108bd01528181610af501528181610d360152818161136e0152818161147f0152818161150801528181611bdb01528181611c1001528181611c4501528181611cd601528181611e0e0152611e5e01525f81816103ed01528181610bd401528181610e160152818161108401528181611193015281816117ab0152818161190e01528181611ef50152818161255401526125f301526135a95ff3fe60806040526004361061011e575f3560e01c80635e60dab51161009d578063b7e0d4c011610062578063b7e0d4c0146103c9578063c45a0155146103dc578063d7b0e0a51461040f578063e5e31b131461042e578063f41766d81461045d575f80fd5b80635e60dab51461033a57806367ffb66a146103595780639881fcb41461036c57806398a0fb3c1461038b578063a32b1fcd146103aa575f80fd5b8063448725b4116100e3578063448725b41461024f5780634c1ee03e1461026e578063544caa561461028d5780635a47ddc3146102cc5780635e1e632514610306575f80fd5b80630dede6c41461016157806313dcfc591461019a57806318a13086146101c65780633fc8cef3146101e55780634386e63c14610230575f80fd5b3661015d57336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461015b5761015b612ad1565b005b5f80fd5b34801561016c575f80fd5b5061018061017b366004612b09565b61047c565b604080519283526020830191909152015b60405180910390f35b3480156101a5575f80fd5b506101b96101b4366004612b89565b61068b565b6040516101919190612bff565b3480156101d1575f80fd5b506101b96101e0366004612c83565b610890565b3480156101f0575f80fd5b506102187f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610191565b34801561023b575f80fd5b5061018061024a366004612cf1565b610bcf565b34801561025a575f80fd5b50610180610269366004612d54565b610d2d565b348015610279575f80fd5b50610218610288366004612df7565b610dfd565b348015610298575f80fd5b506102ac6102a7366004612e3f565b610e96565b604080516001600160a01b03938416815292909116602083015201610191565b3480156102d7575f80fd5b506102eb6102e6366004612e76565b610f75565b60408051938452602084019290925290820152606001610191565b348015610311575f80fd5b50610325610320366004612eff565b61104f565b60408051928352901515602083015201610191565b348015610345575f80fd5b50610180610354366004612df7565b611296565b6101b9610367366004612f33565b611349565b348015610377575f80fd5b506101b961038636600461304e565b611699565b348015610396575f80fd5b506102eb6103a5366004613105565b611908565b3480156103b5575f80fd5b506101806103c436600461315c565b611aff565b6102eb6103d7366004613211565b611bb1565b3480156103e7575f80fd5b506102187f000000000000000000000000000000000000000000000000000000000000000081565b34801561041a575f80fd5b50610180610429366004613211565b611de5565b348015610439575f80fd5b5061044d610448366004613267565b611ed4565b6040519015158152602001610191565b348015610468575f80fd5b506101b9610477366004612c83565b611f66565b5f8082428110156104a85760405162461bcd60e51b815260040161049f90613282565b60405180910390fd5b5f6104b48c8c8c610dfd565b6040516323b872dd60e01b81523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd906064016020604051808303815f875af1158015610507573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061052b91906132ab565b610533575f80fd5b60405163226bf2d160e21b81526001600160a01b0387811660048301525f9182918416906389afcb449060240160408051808303815f875af115801561057b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061059f91906132c6565b915091505f6105ae8f8f610e96565b509050806001600160a01b03168f6001600160a01b0316146105d15781836105d4565b82825b90975095508a8710156106295760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604482015260640161049f565b898610156106795760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604482015260640161049f565b50505050509850989650505050505050565b606081428110156106ae5760405162461bcd60e51b815260040161049f90613282565b6040805160018082528183019092525f91816020015b604080516060810182525f80825260208083018290529282015282525f199092019101816106c457905050905087815f81518110610704576107046132e8565b60200260200101515f01906001600160a01b031690816001600160a01b03168152505086815f8151811061073a5761073a6132e8565b6020026020010151602001906001600160a01b031690816001600160a01b03168152505085815f81518110610771576107716132e8565b602090810291909101015190151560409091015261078f8a82611699565b92508883600185516107a19190613310565b815181106107b1576107b16132e8565b602002602001015110156107d75760405162461bcd60e51b815260040161049f90613323565b610878815f815181106107ec576107ec6132e8565b60200260200101515f015133610859845f8151811061080d5761080d6132e8565b60200260200101515f0151855f8151811061082a5761082a6132e8565b602002602001015160200151865f81518110610848576108486132e8565b602002602001015160400151610dfd565b865f8151811061086b5761086b6132e8565b6020026020010151612088565b61088383828761217f565b5050979650505050505050565b606081428110156108b35760405162461bcd60e51b815260040161049f90613282565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001686866108ea600182613310565b8181106108f9576108f96132e8565b90506060020160200160208101906109119190613267565b6001600160a01b0316146109375760405162461bcd60e51b815260040161049f90613365565b610992888787808060200260200160405190810160405280939291908181526020015f905b828210156109885761097960608302860136819003810190613393565b8152602001906001019061095c565b5050505050611699565b91508682600184516109a49190613310565b815181106109b4576109b46132e8565b602002602001015110156109da5760405162461bcd60e51b815260040161049f90613323565b610a9786865f8181106109ef576109ef6132e8565b610a059260206060909202019081019150613267565b33610a8589895f818110610a1b57610a1b6132e8565b610a319260206060909202019081019150613267565b8a8a5f818110610a4357610a436132e8565b9050606002016020016020810190610a5b9190613267565b8b8b5f818110610a6d57610a6d6132e8565b905060600201604001602081019061028891906133ad565b855f8151811061086b5761086b6132e8565b610af3828787808060200260200160405190810160405280939291908181526020015f905b82821015610ae857610ad960608302860136819003810190613393565b81526020019060010190610abc565b50505050503061217f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d8360018551610b319190613310565b81518110610b4157610b416132e8565b60200260200101516040518263ffffffff1660e01b8152600401610b6791815260200190565b5f604051808303815f87803b158015610b7e575f80fd5b505af1158015610b90573d5f803e3d5ffd5b50505050610bc4848360018551610ba79190613310565b81518110610bb757610bb76132e8565b6020026020010151612450565b509695505050505050565b5f805f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308888886040518463ffffffff1660e01b8152600401610c22939291906133c8565b602060405180830381865afa158015610c3d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c6191906133ec565b90506001600160a01b038116610c7d575f809250925050610d24565b5f80610c8a898989611296565b915091505f836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ccb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cef9190613407565b905080610cfc848961341e565b610d069190613449565b955080610d13838961341e565b610d1d9190613449565b9450505050505b94509492505050565b5f805f610d5b8e7f00000000000000000000000000000000000000000000000000000000000000008f610dfd565b90505f87610d69578c610d6c565b5f195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90610da7903390309086908f908e908e908e90600401613468565b5f604051808303815f87803b158015610dbe575f80fd5b505af1158015610dd0573d5f803e3d5ffd5b50505050610de38f8f8f8f8f8f8f611de5565b809450819550505050509b509b9950505050505050505050565b6040516306801cc360e41b81525f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636801cc3090610e4f908790879087906004016133c8565b602060405180830381865afa158015610e6a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e8e91906133ec565b949350505050565b5f80826001600160a01b0316846001600160a01b031603610ef95760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a204944454e544943414c5f4144445245535345530000000000604482015260640161049f565b826001600160a01b0316846001600160a01b031610610f19578284610f1c565b83835b90925090506001600160a01b038216610f6e5760405162461bcd60e51b8152602060048201526014602482015273526f757465723a205a45524f5f4144445245535360601b604482015260640161049f565b9250929050565b5f805f8342811015610f995760405162461bcd60e51b815260040161049f90613282565b610fa88d8d8d8d8d8d8d612521565b90945092505f610fb98e8e8e610dfd565b9050610fc78e338388612088565b610fd38d338387612088565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303815f875af1158015611018573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061103c9190613407565b9250505099509950999650505050505050565b5f805f61105e85856001610dfd565b60405163e5e31b1360e01b81526001600160a01b0382811660048301529192505f9182917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156110cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110ef91906132ab565b15611166576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561113f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111639190613407565b91505b61117187875f610dfd565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529194507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156111da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111fe91906132ab565b15611275576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561124e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112729190613407565b90505b80821161128357805f611287565b8160015b94509450505050935093915050565b5f805f6112a38686610e96565b5090505f806112b3888888610dfd565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156112ee573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131291906134a9565b5091509150826001600160a01b0316886001600160a01b03161461133757808261133a565b81815b90999098509650505050505050565b6060814281101561136c5760405162461bcd60e51b815260040161049f90613282565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031686865f8181106113a8576113a86132e8565b6113be9260206060909202019081019150613267565b6001600160a01b0316146113e45760405162461bcd60e51b815260040161049f90613365565b611435348787808060200260200160405190810160405280939291908181526020015f905b828210156109885761142660608302860136819003810190613393565b81526020019060010190611409565b91508682600184516114479190613310565b81518110611457576114576132e8565b6020026020010151101561147d5760405162461bcd60e51b815260040161049f90613323565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0835f815181106114be576114be6132e8565b60200260200101516040518263ffffffff1660e01b81526004015f604051808303818588803b1580156114ef575f80fd5b505af1158015611501573d5f803e3d5ffd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb61159c88885f81811061154a5761154a6132e8565b6115609260206060909202019081019150613267565b89895f818110611572576115726132e8565b905060600201602001602081019061158a9190613267565b8a8a5f818110610a6d57610a6d6132e8565b845f815181106115ae576115ae6132e8565b60200260200101516040518363ffffffff1660e01b81526004016115e79291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af1158015611603573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061162791906132ab565b61163357611633612ad1565b61168f828787808060200260200160405190810160405280939291908181526020015f905b828210156116845761167560608302860136819003810190613393565b81526020019060010190611658565b50505050508661217f565b5095945050505050565b60606001825110156116bd5760405162461bcd60e51b815260040161049f90613365565b81516116ca9060016134d4565b67ffffffffffffffff8111156116e2576116e2612f95565b60405190808252806020026020018201604052801561170b578160200160208202803683370190505b50905082815f81518110611721576117216132e8565b6020026020010181815250505f5b8251811015611901575f61178984838151811061174e5761174e6132e8565b60200260200101515f015185848151811061176b5761176b6132e8565b602002602001015160200151868581518110610848576108486132e8565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156117f2573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061181691906132ab565b156118f857806001600160a01b031663f140a35a84848151811061183c5761183c6132e8565b6020026020010151868581518110611856576118566132e8565b60200260200101515f01516040518363ffffffff1660e01b81526004016118909291909182526001600160a01b0316602082015260400190565b602060405180830381865afa1580156118ab573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118cf9190613407565b836118db8460016134d4565b815181106118eb576118eb6132e8565b6020026020010181815250505b5060010161172f565b5092915050565b5f805f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308a8a8a6040518463ffffffff1660e01b815260040161195c939291906133c8565b602060405180830381865afa158015611977573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199b91906133ec565b90505f80806001600160a01b03841615611a2257836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119eb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a0f9190613407565b9050611a1c8c8c8c611296565b90935091505b82158015611a2e575081155b15611a5f578896508795506103e8611a4e611a49888a61341e565b612792565b611a589190613310565b9450611af0565b5f611a6b8a858561287d565b9050888111611ab357899750955085611aac84611a88848b61341e565b611a929190613449565b84611a9d858b61341e565b611aa79190613449565b61293c565b9550611aee565b5f611abf8a858761287d565b9850899750889050611aea85611ad5858461341e565b611adf9190613449565b85611a9d868c61341e565b9650505b505b50505050955095509592505050565b5f805f611b0d8f8f8f610dfd565b90505f87611b1b578c611b1e565b5f195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90611b59903390309086908f908e908e908e90600401613468565b5f604051808303815f87803b158015611b70575f80fd5b505af1158015611b82573d5f803e3d5ffd5b5050505050611b978f8f8f8f8f8f8f8f61047c565b8093508194505050509c509c9a5050505050505050505050565b5f805f8342811015611bd55760405162461bcd60e51b815260040161049f90613282565b611c048b7f00000000000000000000000000000000000000000000000000000000000000008c8c348d8d612521565b90945092505f611c358c7f00000000000000000000000000000000000000000000000000000000000000008d610dfd565b9050611c438c338388612088565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004015f604051808303818588803b158015611c9c575f80fd5b505af1158015611cae573d5f803e3d5ffd5b505060405163a9059cbb60e01b81526001600160a01b038581166004830152602482018990527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303815f875af1158015611d20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d4491906132ab565b611d5057611d50612ad1565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303815f875af1158015611d95573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611db99190613407565b925083341115611dd657611dd633611dd18634613310565b612450565b50509750975097945050505050565b5f808242811015611e085760405162461bcd60e51b815260040161049f90613282565b611e388a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b61047c565b9093509150611e488a8685612951565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015611ea7575f80fd5b505af1158015611eb9573d5f803e3d5ffd5b50505050611ec78583612450565b5097509795505050505050565b60405163e5e31b1360e01b81526001600160a01b0382811660048301525f917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015611f3c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f6091906132ab565b92915050565b60608142811015611f895760405162461bcd60e51b815260040161049f90613282565b611fda888787808060200260200160405190810160405280939291908181526020015f905b8282101561098857611fcb60608302860136819003810190613393565b81526020019060010190611fae565b9150868260018451611fec9190613310565b81518110611ffc57611ffc6132e8565b602002602001015110156120225760405162461bcd60e51b815260040161049f90613323565b61203786865f8181106109ef576109ef6132e8565b610bc4828787808060200260200160405190810160405280939291908181526020015f905b828210156116845761207960608302860136819003810190613393565b8152602001906001019061205c565b8015612179575f846001600160a01b03163b116120a3575f80fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291515f928392908816916121069190613509565b5f604051808303815f865af19150503d805f811461213f576040519150601f19603f3d011682016040523d82523d5f602084013e612144565b606091505b509150915081801561216e57508051158061216e57508080602001905181019061216e91906132ab565b612176575f80fd5b50505b50505050565b5f5b82518110156123b6575f6121ce8483815181106121a0576121a06132e8565b60200260200101515f01518584815181106121bd576121bd6132e8565b602002602001015160200151610e96565b5090505f856121de8460016134d4565b815181106121ee576121ee6132e8565b602002602001015190505f80836001600160a01b0316878681518110612216576122166132e8565b60200260200101515f01516001600160a01b03161461223657825f612239565b5f835b915091505f6001885161224c9190613310565b861061225857866122ca565b6122ca886122678860016134d4565b81518110612277576122776132e8565b60200260200101515f01518988600161229091906134d4565b815181106122a0576122a06132e8565b6020026020010151602001518a8960016122ba91906134d4565b81518110610848576108486132e8565b905061231c8887815181106122e1576122e16132e8565b60200260200101515f01518988815181106122fe576122fe6132e8565b6020026020010151602001518a8981518110610848576108486132e8565b6001600160a01b031663022c0d9f8484845f6040519080825280601f01601f191660200182016040528015612358576020820181803683370190505b506040518563ffffffff1660e01b81526004016123789493929190613524565b5f604051808303815f87803b15801561238f575f80fd5b505af11580156123a1573d5f803e3d5ffd5b50506001909701965061218195505050505050565b50806001600160a01b0316336001600160a01b03167fff3715fa8f2d4d791dd7a610a545050b8c6fe3a62b0f6c38f2f96a00598fe483855f815181106123fe576123fe6132e8565b6020026020010151855f81518110612418576124186132e8565b60200260200101515f01516040516124439291909182526001600160a01b0316602082015260400190565b60405180910390a3505050565b801561251d57604080515f808252602082019092526001600160a01b03841690839060405161247f9190613509565b5f6040518083038185875af1925050503d805f81146124b9576040519150601f19603f3d011682016040523d82523d5f602084013e6124be565b606091505b505090508061251b5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b606482015260840161049f565b505b5050565b5f808386101561252f575f80fd5b8285101561253b575f80fd5b6040516306801cc360e41b81525f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636801cc309061258d908d908d908d906004016133c8565b602060405180830381865afa1580156125a8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125cc91906133ec565b90506001600160a01b03811661266f576040516320b7f73960e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906382dfdce49061262c908d908d908d906004016133c8565b6020604051808303815f875af1158015612648573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061266c91906133ec565b90505b5f8061267c8c8c8c611296565b91509150815f14801561268d575080155b1561269d57889450879350612783565b5f6126a98a848461287d565b905088811161270d57868110156127025760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604482015260640161049f565b899550935083612781565b5f6127198a848661287d565b90508a81111561272b5761272b612ad1565b8881101561277b5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604482015260640161049f565b95508894505b505b50505097509795505050505050565b5f815f036127a157505f919050565b5f60016127ad84612a3e565b901c6001901b905060018184816127c6576127c6613435565b048201901c905060018184816127de576127de613435565b048201901c905060018184816127f6576127f6613435565b048201901c9050600181848161280e5761280e613435565b048201901c9050600181848161282657612826613435565b048201901c9050600181848161283e5761283e613435565b048201901c9050600181848161285657612856613435565b048201901c90506128768182858161287057612870613435565b0461293c565b9392505050565b5f8084116128cd5760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a20494e53554646494349454e545f414d4f554e540000000000604482015260640161049f565b5f831180156128db57505f82115b6129275760405162461bcd60e51b815260206004820152601e60248201527f526f757465723a20494e53554646494349454e545f4c49515549444954590000604482015260640161049f565b82612932838661341e565b610e8e9190613449565b5f81831061294a5781612876565b5090919050565b801561251b575f836001600160a01b03163b1161296c575f80fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291515f928392908716916129c79190613509565b5f604051808303815f865af19150503d805f8114612a00576040519150601f19603f3d011682016040523d82523d5f602084013e612a05565b606091505b5091509150818015612a2f575080511580612a2f575080806020019051810190612a2f91906132ab565b612a37575f80fd5b5050505050565b5f80608083901c15612a5257608092831c92015b604083901c15612a6457604092831c92015b602083901c15612a7657602092831c92015b601083901c15612a8857601092831c92015b600883901c15612a9a57600892831c92015b600483901c15612aac57600492831c92015b600283901c15612abe57600292831c92015b600183901c15611f605760010192915050565b634e487b7160e01b5f52600160045260245ffd5b6001600160a01b0381168114612af9575f80fd5b50565b8015158114612af9575f80fd5b5f805f805f805f80610100898b031215612b21575f80fd5b8835612b2c81612ae5565b97506020890135612b3c81612ae5565b96506040890135612b4c81612afc565b9550606089013594506080890135935060a0890135925060c0890135612b7181612ae5565b8092505060e089013590509295985092959890939650565b5f805f805f805f60e0888a031215612b9f575f80fd5b87359650602088013595506040880135612bb881612ae5565b94506060880135612bc881612ae5565b93506080880135612bd881612afc565b925060a0880135612be881612ae5565b8092505060c0880135905092959891949750929550565b602080825282518282018190525f9190848201906040850190845b81811015612c3657835183529284019291840191600101612c1a565b50909695505050505050565b5f8083601f840112612c52575f80fd5b50813567ffffffffffffffff811115612c69575f80fd5b602083019150836020606083028501011115610f6e575f80fd5b5f805f805f8060a08789031215612c98575f80fd5b8635955060208701359450604087013567ffffffffffffffff811115612cbc575f80fd5b612cc889828a01612c42565b9095509350506060870135612cdc81612ae5565b80925050608087013590509295509295509295565b5f805f8060808587031215612d04575f80fd5b8435612d0f81612ae5565b93506020850135612d1f81612ae5565b92506040850135612d2f81612afc565b9396929550929360600135925050565b803560ff81168114612d4f575f80fd5b919050565b5f805f805f805f805f805f6101608c8e031215612d6f575f80fd5b8b35612d7a81612ae5565b9a5060208c0135612d8a81612afc565b995060408c0135985060608c0135975060808c0135965060a08c0135612daf81612ae5565b955060c08c0135945060e08c0135612dc681612afc565b9350612dd56101008d01612d3f565b92506101208c013591506101408c013590509295989b509295989b9093969950565b5f805f60608486031215612e09575f80fd5b8335612e1481612ae5565b92506020840135612e2481612ae5565b91506040840135612e3481612afc565b809150509250925092565b5f8060408385031215612e50575f80fd5b8235612e5b81612ae5565b91506020830135612e6b81612ae5565b809150509250929050565b5f805f805f805f805f6101208a8c031215612e8f575f80fd5b8935612e9a81612ae5565b985060208a0135612eaa81612ae5565b975060408a0135612eba81612afc565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135612ee681612ae5565b809250506101008a013590509295985092959850929598565b5f805f60608486031215612f11575f80fd5b833592506020840135612f2381612ae5565b91506040840135612e3481612ae5565b5f805f805f60808688031215612f47575f80fd5b85359450602086013567ffffffffffffffff811115612f64575f80fd5b612f7088828901612c42565b9095509350506040860135612f8481612ae5565b949793965091946060013592915050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612fd257612fd2612f95565b604052919050565b5f60608284031215612fea575f80fd5b6040516060810181811067ffffffffffffffff8211171561300d5761300d612f95565b604052905080823561301e81612ae5565b8152602083013561302e81612ae5565b6020820152604083013561304181612afc565b6040919091015292915050565b5f806040838503121561305f575f80fd5b8235915060208084013567ffffffffffffffff8082111561307e575f80fd5b818601915086601f830112613091575f80fd5b8135818111156130a3576130a3612f95565b6130b1848260051b01612fa9565b818152848101925060609182028401850191898311156130cf575f80fd5b938501935b828510156130f5576130e68a86612fda565b845293840193928501926130d4565b5080955050505050509250929050565b5f805f805f60a08688031215613119575f80fd5b853561312481612ae5565b9450602086013561313481612ae5565b9350604086013561314481612afc565b94979396509394606081013594506080013592915050565b5f805f805f805f805f805f806101808d8f031215613178575f80fd5b8c3561318381612ae5565b9b5060208d013561319381612ae5565b9a5060408d01356131a381612afc565b995060608d0135985060808d0135975060a08d0135965060c08d01356131c881612ae5565b955060e08d013594506101008d01356131e081612afc565b93506131ef6101208e01612d3f565b92506101408d013591506101608d013590509295989b509295989b509295989b565b5f805f805f805f60e0888a031215613227575f80fd5b873561323281612ae5565b9650602088013561324281612afc565b955060408801359450606088013593506080880135925060a0880135612be881612ae5565b5f60208284031215613277575f80fd5b813561287681612ae5565b6020808252600f908201526e149bdd5d195c8e8811561412549151608a1b604082015260600190565b5f602082840312156132bb575f80fd5b815161287681612afc565b5f80604083850312156132d7575f80fd5b505080516020909101519092909150565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115611f6057611f606132fc565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f55604082015261139560f21b606082015260800190565b6020808252601490820152730a4deeae8cae47440929cac82989288bea082a8960631b604082015260600190565b5f606082840312156133a3575f80fd5b6128768383612fda565b5f602082840312156133bd575f80fd5b813561287681612afc565b6001600160a01b039384168152919092166020820152901515604082015260600190565b5f602082840312156133fc575f80fd5b815161287681612ae5565b5f60208284031215613417575f80fd5b5051919050565b8082028115828204841417611f6057611f606132fc565b634e487b7160e01b5f52601260045260245ffd5b5f8261346357634e487b7160e01b5f52601260045260245ffd5b500490565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b5f805f606084860312156134bb575f80fd5b8351925060208401519150604084015190509250925092565b80820180821115611f6057611f606132fc565b5f5b838110156135015781810151838201526020016134e9565b50505f910152565b5f825161351a8184602087016134e7565b9190910192915050565b84815283602082015260018060a01b0383166040820152608060608201525f825180608084015261355c8160a08501602087016134e7565b601f01601f19169190910160a0019594505050505056fea264697066735822122012a7307636313be7081ef4dfd74d57dc61a7328f586daa4b5cf7ffce07070eab64736f6c6343000817003300000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50240000000000000000000000005300000000000000000000000000000000000004

Deployed Bytecode

0x60806040526004361061011e575f3560e01c80635e60dab51161009d578063b7e0d4c011610062578063b7e0d4c0146103c9578063c45a0155146103dc578063d7b0e0a51461040f578063e5e31b131461042e578063f41766d81461045d575f80fd5b80635e60dab51461033a57806367ffb66a146103595780639881fcb41461036c57806398a0fb3c1461038b578063a32b1fcd146103aa575f80fd5b8063448725b4116100e3578063448725b41461024f5780634c1ee03e1461026e578063544caa561461028d5780635a47ddc3146102cc5780635e1e632514610306575f80fd5b80630dede6c41461016157806313dcfc591461019a57806318a13086146101c65780633fc8cef3146101e55780634386e63c14610230575f80fd5b3661015d57336001600160a01b037f0000000000000000000000005300000000000000000000000000000000000004161461015b5761015b612ad1565b005b5f80fd5b34801561016c575f80fd5b5061018061017b366004612b09565b61047c565b604080519283526020830191909152015b60405180910390f35b3480156101a5575f80fd5b506101b96101b4366004612b89565b61068b565b6040516101919190612bff565b3480156101d1575f80fd5b506101b96101e0366004612c83565b610890565b3480156101f0575f80fd5b506102187f000000000000000000000000530000000000000000000000000000000000000481565b6040516001600160a01b039091168152602001610191565b34801561023b575f80fd5b5061018061024a366004612cf1565b610bcf565b34801561025a575f80fd5b50610180610269366004612d54565b610d2d565b348015610279575f80fd5b50610218610288366004612df7565b610dfd565b348015610298575f80fd5b506102ac6102a7366004612e3f565b610e96565b604080516001600160a01b03938416815292909116602083015201610191565b3480156102d7575f80fd5b506102eb6102e6366004612e76565b610f75565b60408051938452602084019290925290820152606001610191565b348015610311575f80fd5b50610325610320366004612eff565b61104f565b60408051928352901515602083015201610191565b348015610345575f80fd5b50610180610354366004612df7565b611296565b6101b9610367366004612f33565b611349565b348015610377575f80fd5b506101b961038636600461304e565b611699565b348015610396575f80fd5b506102eb6103a5366004613105565b611908565b3480156103b5575f80fd5b506101806103c436600461315c565b611aff565b6102eb6103d7366004613211565b611bb1565b3480156103e7575f80fd5b506102187f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c502481565b34801561041a575f80fd5b50610180610429366004613211565b611de5565b348015610439575f80fd5b5061044d610448366004613267565b611ed4565b6040519015158152602001610191565b348015610468575f80fd5b506101b9610477366004612c83565b611f66565b5f8082428110156104a85760405162461bcd60e51b815260040161049f90613282565b60405180910390fd5b5f6104b48c8c8c610dfd565b6040516323b872dd60e01b81523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd906064016020604051808303815f875af1158015610507573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061052b91906132ab565b610533575f80fd5b60405163226bf2d160e21b81526001600160a01b0387811660048301525f9182918416906389afcb449060240160408051808303815f875af115801561057b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061059f91906132c6565b915091505f6105ae8f8f610e96565b509050806001600160a01b03168f6001600160a01b0316146105d15781836105d4565b82825b90975095508a8710156106295760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604482015260640161049f565b898610156106795760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604482015260640161049f565b50505050509850989650505050505050565b606081428110156106ae5760405162461bcd60e51b815260040161049f90613282565b6040805160018082528183019092525f91816020015b604080516060810182525f80825260208083018290529282015282525f199092019101816106c457905050905087815f81518110610704576107046132e8565b60200260200101515f01906001600160a01b031690816001600160a01b03168152505086815f8151811061073a5761073a6132e8565b6020026020010151602001906001600160a01b031690816001600160a01b03168152505085815f81518110610771576107716132e8565b602090810291909101015190151560409091015261078f8a82611699565b92508883600185516107a19190613310565b815181106107b1576107b16132e8565b602002602001015110156107d75760405162461bcd60e51b815260040161049f90613323565b610878815f815181106107ec576107ec6132e8565b60200260200101515f015133610859845f8151811061080d5761080d6132e8565b60200260200101515f0151855f8151811061082a5761082a6132e8565b602002602001015160200151865f81518110610848576108486132e8565b602002602001015160400151610dfd565b865f8151811061086b5761086b6132e8565b6020026020010151612088565b61088383828761217f565b5050979650505050505050565b606081428110156108b35760405162461bcd60e51b815260040161049f90613282565b6001600160a01b037f00000000000000000000000053000000000000000000000000000000000000041686866108ea600182613310565b8181106108f9576108f96132e8565b90506060020160200160208101906109119190613267565b6001600160a01b0316146109375760405162461bcd60e51b815260040161049f90613365565b610992888787808060200260200160405190810160405280939291908181526020015f905b828210156109885761097960608302860136819003810190613393565b8152602001906001019061095c565b5050505050611699565b91508682600184516109a49190613310565b815181106109b4576109b46132e8565b602002602001015110156109da5760405162461bcd60e51b815260040161049f90613323565b610a9786865f8181106109ef576109ef6132e8565b610a059260206060909202019081019150613267565b33610a8589895f818110610a1b57610a1b6132e8565b610a319260206060909202019081019150613267565b8a8a5f818110610a4357610a436132e8565b9050606002016020016020810190610a5b9190613267565b8b8b5f818110610a6d57610a6d6132e8565b905060600201604001602081019061028891906133ad565b855f8151811061086b5761086b6132e8565b610af3828787808060200260200160405190810160405280939291908181526020015f905b82821015610ae857610ad960608302860136819003810190613393565b81526020019060010190610abc565b50505050503061217f565b7f00000000000000000000000053000000000000000000000000000000000000046001600160a01b0316632e1a7d4d8360018551610b319190613310565b81518110610b4157610b416132e8565b60200260200101516040518263ffffffff1660e01b8152600401610b6791815260200190565b5f604051808303815f87803b158015610b7e575f80fd5b505af1158015610b90573d5f803e3d5ffd5b50505050610bc4848360018551610ba79190613310565b81518110610bb757610bb76132e8565b6020026020010151612450565b509695505050505050565b5f805f7f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50246001600160a01b0316636801cc308888886040518463ffffffff1660e01b8152600401610c22939291906133c8565b602060405180830381865afa158015610c3d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c6191906133ec565b90506001600160a01b038116610c7d575f809250925050610d24565b5f80610c8a898989611296565b915091505f836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ccb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cef9190613407565b905080610cfc848961341e565b610d069190613449565b955080610d13838961341e565b610d1d9190613449565b9450505050505b94509492505050565b5f805f610d5b8e7f00000000000000000000000053000000000000000000000000000000000000048f610dfd565b90505f87610d69578c610d6c565b5f195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90610da7903390309086908f908e908e908e90600401613468565b5f604051808303815f87803b158015610dbe575f80fd5b505af1158015610dd0573d5f803e3d5ffd5b50505050610de38f8f8f8f8f8f8f611de5565b809450819550505050509b509b9950505050505050505050565b6040516306801cc360e41b81525f906001600160a01b037f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50241690636801cc3090610e4f908790879087906004016133c8565b602060405180830381865afa158015610e6a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e8e91906133ec565b949350505050565b5f80826001600160a01b0316846001600160a01b031603610ef95760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a204944454e544943414c5f4144445245535345530000000000604482015260640161049f565b826001600160a01b0316846001600160a01b031610610f19578284610f1c565b83835b90925090506001600160a01b038216610f6e5760405162461bcd60e51b8152602060048201526014602482015273526f757465723a205a45524f5f4144445245535360601b604482015260640161049f565b9250929050565b5f805f8342811015610f995760405162461bcd60e51b815260040161049f90613282565b610fa88d8d8d8d8d8d8d612521565b90945092505f610fb98e8e8e610dfd565b9050610fc78e338388612088565b610fd38d338387612088565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303815f875af1158015611018573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061103c9190613407565b9250505099509950999650505050505050565b5f805f61105e85856001610dfd565b60405163e5e31b1360e01b81526001600160a01b0382811660048301529192505f9182917f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50249091169063e5e31b1390602401602060405180830381865afa1580156110cb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110ef91906132ab565b15611166576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561113f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111639190613407565b91505b61117187875f610dfd565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529194507f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50249091169063e5e31b1390602401602060405180830381865afa1580156111da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111fe91906132ab565b15611275576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561124e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112729190613407565b90505b80821161128357805f611287565b8160015b94509450505050935093915050565b5f805f6112a38686610e96565b5090505f806112b3888888610dfd565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156112ee573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131291906134a9565b5091509150826001600160a01b0316886001600160a01b03161461133757808261133a565b81815b90999098509650505050505050565b6060814281101561136c5760405162461bcd60e51b815260040161049f90613282565b7f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031686865f8181106113a8576113a86132e8565b6113be9260206060909202019081019150613267565b6001600160a01b0316146113e45760405162461bcd60e51b815260040161049f90613365565b611435348787808060200260200160405190810160405280939291908181526020015f905b828210156109885761142660608302860136819003810190613393565b81526020019060010190611409565b91508682600184516114479190613310565b81518110611457576114576132e8565b6020026020010151101561147d5760405162461bcd60e51b815260040161049f90613323565b7f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031663d0e30db0835f815181106114be576114be6132e8565b60200260200101516040518263ffffffff1660e01b81526004015f604051808303818588803b1580156114ef575f80fd5b505af1158015611501573d5f803e3d5ffd5b50505050507f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031663a9059cbb61159c88885f81811061154a5761154a6132e8565b6115609260206060909202019081019150613267565b89895f818110611572576115726132e8565b905060600201602001602081019061158a9190613267565b8a8a5f818110610a6d57610a6d6132e8565b845f815181106115ae576115ae6132e8565b60200260200101516040518363ffffffff1660e01b81526004016115e79291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af1158015611603573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061162791906132ab565b61163357611633612ad1565b61168f828787808060200260200160405190810160405280939291908181526020015f905b828210156116845761167560608302860136819003810190613393565b81526020019060010190611658565b50505050508661217f565b5095945050505050565b60606001825110156116bd5760405162461bcd60e51b815260040161049f90613365565b81516116ca9060016134d4565b67ffffffffffffffff8111156116e2576116e2612f95565b60405190808252806020026020018201604052801561170b578160200160208202803683370190505b50905082815f81518110611721576117216132e8565b6020026020010181815250505f5b8251811015611901575f61178984838151811061174e5761174e6132e8565b60200260200101515f015185848151811061176b5761176b6132e8565b602002602001015160200151868581518110610848576108486132e8565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50249091169063e5e31b1390602401602060405180830381865afa1580156117f2573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061181691906132ab565b156118f857806001600160a01b031663f140a35a84848151811061183c5761183c6132e8565b6020026020010151868581518110611856576118566132e8565b60200260200101515f01516040518363ffffffff1660e01b81526004016118909291909182526001600160a01b0316602082015260400190565b602060405180830381865afa1580156118ab573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118cf9190613407565b836118db8460016134d4565b815181106118eb576118eb6132e8565b6020026020010181815250505b5060010161172f565b5092915050565b5f805f807f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50246001600160a01b0316636801cc308a8a8a6040518463ffffffff1660e01b815260040161195c939291906133c8565b602060405180830381865afa158015611977573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061199b91906133ec565b90505f80806001600160a01b03841615611a2257836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119eb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a0f9190613407565b9050611a1c8c8c8c611296565b90935091505b82158015611a2e575081155b15611a5f578896508795506103e8611a4e611a49888a61341e565b612792565b611a589190613310565b9450611af0565b5f611a6b8a858561287d565b9050888111611ab357899750955085611aac84611a88848b61341e565b611a929190613449565b84611a9d858b61341e565b611aa79190613449565b61293c565b9550611aee565b5f611abf8a858761287d565b9850899750889050611aea85611ad5858461341e565b611adf9190613449565b85611a9d868c61341e565b9650505b505b50505050955095509592505050565b5f805f611b0d8f8f8f610dfd565b90505f87611b1b578c611b1e565b5f195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90611b59903390309086908f908e908e908e90600401613468565b5f604051808303815f87803b158015611b70575f80fd5b505af1158015611b82573d5f803e3d5ffd5b5050505050611b978f8f8f8f8f8f8f8f61047c565b8093508194505050509c509c9a5050505050505050505050565b5f805f8342811015611bd55760405162461bcd60e51b815260040161049f90613282565b611c048b7f00000000000000000000000053000000000000000000000000000000000000048c8c348d8d612521565b90945092505f611c358c7f00000000000000000000000053000000000000000000000000000000000000048d610dfd565b9050611c438c338388612088565b7f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004015f604051808303818588803b158015611c9c575f80fd5b505af1158015611cae573d5f803e3d5ffd5b505060405163a9059cbb60e01b81526001600160a01b038581166004830152602482018990527f000000000000000000000000530000000000000000000000000000000000000416935063a9059cbb925060440190506020604051808303815f875af1158015611d20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611d4491906132ab565b611d5057611d50612ad1565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303815f875af1158015611d95573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611db99190613407565b925083341115611dd657611dd633611dd18634613310565b612450565b50509750975097945050505050565b5f808242811015611e085760405162461bcd60e51b815260040161049f90613282565b611e388a7f00000000000000000000000053000000000000000000000000000000000000048b8b8b8b308b61047c565b9093509150611e488a8685612951565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000053000000000000000000000000000000000000046001600160a01b031690632e1a7d4d906024015f604051808303815f87803b158015611ea7575f80fd5b505af1158015611eb9573d5f803e3d5ffd5b50505050611ec78583612450565b5097509795505050505050565b60405163e5e31b1360e01b81526001600160a01b0382811660048301525f917f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50249091169063e5e31b1390602401602060405180830381865afa158015611f3c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f6091906132ab565b92915050565b60608142811015611f895760405162461bcd60e51b815260040161049f90613282565b611fda888787808060200260200160405190810160405280939291908181526020015f905b8282101561098857611fcb60608302860136819003810190613393565b81526020019060010190611fae565b9150868260018451611fec9190613310565b81518110611ffc57611ffc6132e8565b602002602001015110156120225760405162461bcd60e51b815260040161049f90613323565b61203786865f8181106109ef576109ef6132e8565b610bc4828787808060200260200160405190810160405280939291908181526020015f905b828210156116845761207960608302860136819003810190613393565b8152602001906001019061205c565b8015612179575f846001600160a01b03163b116120a3575f80fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291515f928392908816916121069190613509565b5f604051808303815f865af19150503d805f811461213f576040519150601f19603f3d011682016040523d82523d5f602084013e612144565b606091505b509150915081801561216e57508051158061216e57508080602001905181019061216e91906132ab565b612176575f80fd5b50505b50505050565b5f5b82518110156123b6575f6121ce8483815181106121a0576121a06132e8565b60200260200101515f01518584815181106121bd576121bd6132e8565b602002602001015160200151610e96565b5090505f856121de8460016134d4565b815181106121ee576121ee6132e8565b602002602001015190505f80836001600160a01b0316878681518110612216576122166132e8565b60200260200101515f01516001600160a01b03161461223657825f612239565b5f835b915091505f6001885161224c9190613310565b861061225857866122ca565b6122ca886122678860016134d4565b81518110612277576122776132e8565b60200260200101515f01518988600161229091906134d4565b815181106122a0576122a06132e8565b6020026020010151602001518a8960016122ba91906134d4565b81518110610848576108486132e8565b905061231c8887815181106122e1576122e16132e8565b60200260200101515f01518988815181106122fe576122fe6132e8565b6020026020010151602001518a8981518110610848576108486132e8565b6001600160a01b031663022c0d9f8484845f6040519080825280601f01601f191660200182016040528015612358576020820181803683370190505b506040518563ffffffff1660e01b81526004016123789493929190613524565b5f604051808303815f87803b15801561238f575f80fd5b505af11580156123a1573d5f803e3d5ffd5b50506001909701965061218195505050505050565b50806001600160a01b0316336001600160a01b03167fff3715fa8f2d4d791dd7a610a545050b8c6fe3a62b0f6c38f2f96a00598fe483855f815181106123fe576123fe6132e8565b6020026020010151855f81518110612418576124186132e8565b60200260200101515f01516040516124439291909182526001600160a01b0316602082015260400190565b60405180910390a3505050565b801561251d57604080515f808252602082019092526001600160a01b03841690839060405161247f9190613509565b5f6040518083038185875af1925050503d805f81146124b9576040519150601f19603f3d011682016040523d82523d5f602084013e6124be565b606091505b505090508061251b5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b606482015260840161049f565b505b5050565b5f808386101561252f575f80fd5b8285101561253b575f80fd5b6040516306801cc360e41b81525f906001600160a01b037f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50241690636801cc309061258d908d908d908d906004016133c8565b602060405180830381865afa1580156125a8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125cc91906133ec565b90506001600160a01b03811661266f576040516320b7f73960e21b81526001600160a01b037f00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c502416906382dfdce49061262c908d908d908d906004016133c8565b6020604051808303815f875af1158015612648573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061266c91906133ec565b90505b5f8061267c8c8c8c611296565b91509150815f14801561268d575080155b1561269d57889450879350612783565b5f6126a98a848461287d565b905088811161270d57868110156127025760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604482015260640161049f565b899550935083612781565b5f6127198a848661287d565b90508a81111561272b5761272b612ad1565b8881101561277b5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604482015260640161049f565b95508894505b505b50505097509795505050505050565b5f815f036127a157505f919050565b5f60016127ad84612a3e565b901c6001901b905060018184816127c6576127c6613435565b048201901c905060018184816127de576127de613435565b048201901c905060018184816127f6576127f6613435565b048201901c9050600181848161280e5761280e613435565b048201901c9050600181848161282657612826613435565b048201901c9050600181848161283e5761283e613435565b048201901c9050600181848161285657612856613435565b048201901c90506128768182858161287057612870613435565b0461293c565b9392505050565b5f8084116128cd5760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a20494e53554646494349454e545f414d4f554e540000000000604482015260640161049f565b5f831180156128db57505f82115b6129275760405162461bcd60e51b815260206004820152601e60248201527f526f757465723a20494e53554646494349454e545f4c49515549444954590000604482015260640161049f565b82612932838661341e565b610e8e9190613449565b5f81831061294a5781612876565b5090919050565b801561251b575f836001600160a01b03163b1161296c575f80fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291515f928392908716916129c79190613509565b5f604051808303815f865af19150503d805f8114612a00576040519150601f19603f3d011682016040523d82523d5f602084013e612a05565b606091505b5091509150818015612a2f575080511580612a2f575080806020019051810190612a2f91906132ab565b612a37575f80fd5b5050505050565b5f80608083901c15612a5257608092831c92015b604083901c15612a6457604092831c92015b602083901c15612a7657602092831c92015b601083901c15612a8857601092831c92015b600883901c15612a9a57600892831c92015b600483901c15612aac57600492831c92015b600283901c15612abe57600292831c92015b600183901c15611f605760010192915050565b634e487b7160e01b5f52600160045260245ffd5b6001600160a01b0381168114612af9575f80fd5b50565b8015158114612af9575f80fd5b5f805f805f805f80610100898b031215612b21575f80fd5b8835612b2c81612ae5565b97506020890135612b3c81612ae5565b96506040890135612b4c81612afc565b9550606089013594506080890135935060a0890135925060c0890135612b7181612ae5565b8092505060e089013590509295985092959890939650565b5f805f805f805f60e0888a031215612b9f575f80fd5b87359650602088013595506040880135612bb881612ae5565b94506060880135612bc881612ae5565b93506080880135612bd881612afc565b925060a0880135612be881612ae5565b8092505060c0880135905092959891949750929550565b602080825282518282018190525f9190848201906040850190845b81811015612c3657835183529284019291840191600101612c1a565b50909695505050505050565b5f8083601f840112612c52575f80fd5b50813567ffffffffffffffff811115612c69575f80fd5b602083019150836020606083028501011115610f6e575f80fd5b5f805f805f8060a08789031215612c98575f80fd5b8635955060208701359450604087013567ffffffffffffffff811115612cbc575f80fd5b612cc889828a01612c42565b9095509350506060870135612cdc81612ae5565b80925050608087013590509295509295509295565b5f805f8060808587031215612d04575f80fd5b8435612d0f81612ae5565b93506020850135612d1f81612ae5565b92506040850135612d2f81612afc565b9396929550929360600135925050565b803560ff81168114612d4f575f80fd5b919050565b5f805f805f805f805f805f6101608c8e031215612d6f575f80fd5b8b35612d7a81612ae5565b9a5060208c0135612d8a81612afc565b995060408c0135985060608c0135975060808c0135965060a08c0135612daf81612ae5565b955060c08c0135945060e08c0135612dc681612afc565b9350612dd56101008d01612d3f565b92506101208c013591506101408c013590509295989b509295989b9093969950565b5f805f60608486031215612e09575f80fd5b8335612e1481612ae5565b92506020840135612e2481612ae5565b91506040840135612e3481612afc565b809150509250925092565b5f8060408385031215612e50575f80fd5b8235612e5b81612ae5565b91506020830135612e6b81612ae5565b809150509250929050565b5f805f805f805f805f6101208a8c031215612e8f575f80fd5b8935612e9a81612ae5565b985060208a0135612eaa81612ae5565b975060408a0135612eba81612afc565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135612ee681612ae5565b809250506101008a013590509295985092959850929598565b5f805f60608486031215612f11575f80fd5b833592506020840135612f2381612ae5565b91506040840135612e3481612ae5565b5f805f805f60808688031215612f47575f80fd5b85359450602086013567ffffffffffffffff811115612f64575f80fd5b612f7088828901612c42565b9095509350506040860135612f8481612ae5565b949793965091946060013592915050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612fd257612fd2612f95565b604052919050565b5f60608284031215612fea575f80fd5b6040516060810181811067ffffffffffffffff8211171561300d5761300d612f95565b604052905080823561301e81612ae5565b8152602083013561302e81612ae5565b6020820152604083013561304181612afc565b6040919091015292915050565b5f806040838503121561305f575f80fd5b8235915060208084013567ffffffffffffffff8082111561307e575f80fd5b818601915086601f830112613091575f80fd5b8135818111156130a3576130a3612f95565b6130b1848260051b01612fa9565b818152848101925060609182028401850191898311156130cf575f80fd5b938501935b828510156130f5576130e68a86612fda565b845293840193928501926130d4565b5080955050505050509250929050565b5f805f805f60a08688031215613119575f80fd5b853561312481612ae5565b9450602086013561313481612ae5565b9350604086013561314481612afc565b94979396509394606081013594506080013592915050565b5f805f805f805f805f805f806101808d8f031215613178575f80fd5b8c3561318381612ae5565b9b5060208d013561319381612ae5565b9a5060408d01356131a381612afc565b995060608d0135985060808d0135975060a08d0135965060c08d01356131c881612ae5565b955060e08d013594506101008d01356131e081612afc565b93506131ef6101208e01612d3f565b92506101408d013591506101608d013590509295989b509295989b509295989b565b5f805f805f805f60e0888a031215613227575f80fd5b873561323281612ae5565b9650602088013561324281612afc565b955060408801359450606088013593506080880135925060a0880135612be881612ae5565b5f60208284031215613277575f80fd5b813561287681612ae5565b6020808252600f908201526e149bdd5d195c8e8811561412549151608a1b604082015260600190565b5f602082840312156132bb575f80fd5b815161287681612afc565b5f80604083850312156132d7575f80fd5b505080516020909101519092909150565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b81810381811115611f6057611f606132fc565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f55604082015261139560f21b606082015260800190565b6020808252601490820152730a4deeae8cae47440929cac82989288bea082a8960631b604082015260600190565b5f606082840312156133a3575f80fd5b6128768383612fda565b5f602082840312156133bd575f80fd5b813561287681612afc565b6001600160a01b039384168152919092166020820152901515604082015260600190565b5f602082840312156133fc575f80fd5b815161287681612ae5565b5f60208284031215613417575f80fd5b5051919050565b8082028115828204841417611f6057611f606132fc565b634e487b7160e01b5f52601260045260245ffd5b5f8261346357634e487b7160e01b5f52601260045260245ffd5b500490565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b5f805f606084860312156134bb575f80fd5b8351925060208401519150604084015190509250925092565b80820180821115611f6057611f606132fc565b5f5b838110156135015781810151838201526020016134e9565b50505f910152565b5f825161351a8184602087016134e7565b9190910192915050565b84815283602082015260018060a01b0383166040820152608060608201525f825180608084015261355c8160a08501602087016134e7565b601f01601f19169190910160a0019594505050505056fea264697066735822122012a7307636313be7081ef4dfd74d57dc61a7328f586daa4b5cf7ffce07070eab64736f6c63430008170033

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

00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c50240000000000000000000000005300000000000000000000000000000000000004

-----Decoded View---------------
Arg [0] : _pairFactory (address): 0x92aF10c685D2CF4CD845388C5f45aC5dc97C5024
Arg [1] : _weth (address): 0x5300000000000000000000000000000000000004

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000092af10c685d2cf4cd845388c5f45ac5dc97c5024
Arg [1] : 0000000000000000000000005300000000000000000000000000000000000004


Block Transaction Gas Used Reward
view all blocks sequenced

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

Validator Index Block Amount
View All Withdrawals

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

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