ETH Price: $2,273.86 (-6.27%)
Gas: 0.05 GWei

Contract

0xA663c287b2f374878C07B7ac55C1BC927669425a

Overview

ETH Balance

Scroll LogoScroll LogoScroll Logo0 ETH

ETH Value

$0.00

Multichain Info

1 address found via
Transaction Hash
Method
Block
From
To
0x8ef8822d69cbed0caf80f299372a7e194355f39148caf3b3c6b8f842c469eca9 -(pending)2024-09-09 11:39:166 days ago1725881956IN
0xA663c287...27669425a
0.004 ETH(Pending)(Pending)
0x1dd27bbe56d17832d705d1af1c02dc62eefd6e6c050d3a95893f3f7c238683e7 -(pending)2024-09-09 11:39:166 days ago1725881956IN
0xA663c287...27669425a
0.002 ETH(Pending)(Pending)
Add Liquidity ET...93279532024-09-16 2:11:0722 secs ago1726452667IN
0xA663c287...27669425a
0.05312995 ETH0.000025710.08848934
Swap Exact ETH F...93277892024-09-16 2:02:558 mins ago1726452175IN
0xA663c287...27669425a
0.013 ETH0.000018290.0488269
Swap Exact Token...93277802024-09-16 2:02:289 mins ago1726452148IN
0xA663c287...27669425a
0 ETH0.000010810.04846923
Add Liquidity93277602024-09-16 2:01:2810 mins ago1726452088IN
0xA663c287...27669425a
0 ETH0.000010750.06
Swap Exact Token...93277552024-09-16 2:01:1310 mins ago1726452073IN
0xA663c287...27669425a
0 ETH0.000011840.06
Swap Exact Token...93277522024-09-16 2:01:0410 mins ago1726452064IN
0xA663c287...27669425a
0 ETH0.000019090.06
Add Liquidity93277432024-09-16 2:00:3710 mins ago1726452037IN
0xA663c287...27669425a
0 ETH0.000011320.06
Swap Exact Token...93277412024-09-16 2:00:3110 mins ago1726452031IN
0xA663c287...27669425a
0 ETH0.000009930.05
Swap Exact Token...93277382024-09-16 2:00:2211 mins ago1726452022IN
0xA663c287...27669425a
0 ETH0.000015950.05
Swap Exact Token...93277002024-09-16 1:58:2813 mins ago1726451908IN
0xA663c287...27669425a
0 ETH0.000016020.06
Swap Exact Token...93276902024-09-16 1:57:5813 mins ago1726451878IN
0xA663c287...27669425a
0 ETH0.000022190.06
Swap Exact Token...93276672024-09-16 1:56:4914 mins ago1726451809IN
0xA663c287...27669425a
0 ETH0.000019040.05175742
Swap Exact Token...93276572024-09-16 1:56:1915 mins ago1726451779IN
0xA663c287...27669425a
0 ETH0.000013580.06503424
Swap Exact Token...93276562024-09-16 1:56:1615 mins ago1726451776IN
0xA663c287...27669425a
0 ETH0.000013670.06543624
Swap Exact ETH F...93276522024-09-16 1:56:0415 mins ago1726451764IN
0xA663c287...27669425a
0.014 ETH0.000010630.05027363
Swap Exact Token...93276442024-09-16 1:55:4115 mins ago1726451741IN
0xA663c287...27669425a
0 ETH0.000013460.06434203
Swap Exact Token...93276312024-09-16 1:55:0216 mins ago1726451702IN
0xA663c287...27669425a
0 ETH0.000027180.08
Swap Exact Token...93276132024-09-16 1:54:0817 mins ago1726451648IN
0xA663c287...27669425a
0 ETH0.000014980.07
Remove Liquidity93276082024-09-16 1:53:5317 mins ago1726451633IN
0xA663c287...27669425a
0 ETH0.000013340.07
Swap Exact Token...93275352024-09-16 1:50:1721 mins ago1726451417IN
0xA663c287...27669425a
0 ETH0.000005050.06630419
Swap Exact Token...93275332024-09-16 1:50:1221 mins ago1726451412IN
0xA663c287...27669425a
0 ETH0.000013580.06630419
Swap Exact Token...93275322024-09-16 1:50:1021 mins ago1726451410IN
0xA663c287...27669425a
0 ETH0.000003970.06630419
Swap Exact Token...93275292024-09-16 1:50:0421 mins ago1726451404IN
0xA663c287...27669425a
0 ETH0.000013650.06668773
View all transactions

Latest 25 internal transactions (View All)

Parent Transaction Hash Block From To
93279532024-09-16 2:11:0722 secs ago1726452667
0xA663c287...27669425a
0.05312995 ETH
93277892024-09-16 2:02:558 mins ago1726452175
0xA663c287...27669425a
0.013 ETH
93277802024-09-16 2:02:289 mins ago1726452148
0xA663c287...27669425a
0.01166971 ETH
93277802024-09-16 2:02:289 mins ago1726452148
0xA663c287...27669425a
0.01166971 ETH
93276902024-09-16 1:57:5813 mins ago1726451878
0xA663c287...27669425a
0.00043828 ETH
93276902024-09-16 1:57:5813 mins ago1726451878
0xA663c287...27669425a
0.00043828 ETH
93276672024-09-16 1:56:4914 mins ago1726451809
0xA663c287...27669425a
0.01391465 ETH
93276672024-09-16 1:56:4914 mins ago1726451809
0xA663c287...27669425a
0.01391465 ETH
93276522024-09-16 1:56:0415 mins ago1726451764
0xA663c287...27669425a
0.014 ETH
93271612024-09-16 1:32:0139 mins ago1726450321
0xA663c287...27669425a
0.01695878 ETH
93271612024-09-16 1:32:0139 mins ago1726450321
0xA663c287...27669425a
0.01695878 ETH
93271472024-09-16 1:31:1940 mins ago1726450279
0xA663c287...27669425a
0.01702 ETH
93270402024-09-16 1:25:5745 mins ago1726449957
0xA663c287...27669425a
0.00068404 ETH
93270402024-09-16 1:25:5745 mins ago1726449957
0xA663c287...27669425a
0.00068404 ETH
93262452024-09-16 0:46:471 hr ago1726447607
0xA663c287...27669425a
0.02102737 ETH
93262452024-09-16 0:46:471 hr ago1726447607
0xA663c287...27669425a
0.02102737 ETH
93262142024-09-16 0:45:191 hr ago1726447519
0xA663c287...27669425a
0.00000944 ETH
93261932024-09-16 0:44:161 hr ago1726447456
0xA663c287...27669425a
0.00000944 ETH
93259152024-09-16 0:30:241 hr ago1726446624
0xA663c287...27669425a
0.11733531 ETH
93256152024-09-16 0:15:281 hr ago1726445728
0xA663c287...27669425a
0.02435948 ETH
93256152024-09-16 0:15:281 hr ago1726445728
0xA663c287...27669425a
0.02435948 ETH
93250992024-09-15 23:49:382 hrs ago1726444178
0xA663c287...27669425a
0.00313699 ETH
93250902024-09-15 23:49:112 hrs ago1726444151
0xA663c287...27669425a
0.00352907 ETH
93250902024-09-15 23:49:112 hrs ago1726444151
0xA663c287...27669425a
0.00352907 ETH
93250392024-09-15 23:46:422 hrs ago1726444002
0xA663c287...27669425a
0.01208041 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

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