MNT Price: $0.89 (+1.56%)

Contract

0xE856d35f554A6656d70cCf1B11D4Ae7cEE24F473
 

Overview

MNT Balance

Mantle Mainnet Network LogoMantle Mainnet Network LogoMantle Mainnet Network Logo0 MNT

MNT Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Swap Exact Token...775504872025-03-29 6:54:46301 days ago1743231286IN
0xE856d35f...cEE24F473
0 MNT0.010393170.02
Swap Exact Token...775462632025-03-29 4:33:58301 days ago1743222838IN
0xE856d35f...cEE24F473
0 MNT0.01036610.02
Remove Liquidity775458192025-03-29 4:19:10301 days ago1743221950IN
0xE856d35f...cEE24F473
0 MNT0.010232470.02
Remove Liquidity775406822025-03-29 1:27:56301 days ago1743211676IN
0xE856d35f...cEE24F473
0 MNT0.015534390.03
Swap Exact Token...775169522025-03-28 12:16:56302 days ago1743164216IN
0xE856d35f...cEE24F473
0 MNT0.016763710.03
Swap Exact Token...774128982025-03-26 2:28:28304 days ago1742956108IN
0xE856d35f...cEE24F473
0 MNT0.01159460.02
Remove Liquidity774123162025-03-26 2:09:04304 days ago1742954944IN
0xE856d35f...cEE24F473
0 MNT0.018127130.02
Swap Exact Token...773265082025-03-24 2:28:48306 days ago1742783328IN
0xE856d35f...cEE24F473
0 MNT0.011560830.02
Swap Exact Token...772387232025-03-22 1:42:38308 days ago1742607758IN
0xE856d35f...cEE24F473
0 MNT0.011938340.02
Remove Liquidity771159122025-03-19 5:28:56311 days ago1742362136IN
0xE856d35f...cEE24F473
0 MNT0.01196380.02
Swap Exact Token...770845372025-03-18 12:03:06312 days ago1742299386IN
0xE856d35f...cEE24F473
0 MNT0.010270120.02
Remove Liquidity770844582025-03-18 12:00:28312 days ago1742299228IN
0xE856d35f...cEE24F473
0 MNT0.010872850.02
Swap Exact Token...770393632025-03-17 10:57:18313 days ago1742209038IN
0xE856d35f...cEE24F473
0 MNT0.011259410.02
Remove Liquidity770392722025-03-17 10:54:16313 days ago1742208856IN
0xE856d35f...cEE24F473
0 MNT0.010798250.02
Remove Liquidity770228842025-03-17 1:48:00313 days ago1742176080IN
0xE856d35f...cEE24F473
0 MNT0.011217550.02
Swap Exact Token...768465272025-03-12 23:49:26317 days ago1741823366IN
0xE856d35f...cEE24F473
0 MNT0.01239710.02
Swap Exact Token...768464922025-03-12 23:48:16317 days ago1741823296IN
0xE856d35f...cEE24F473
0 MNT0.013079560.02
Remove Liquidity768464182025-03-12 23:45:48317 days ago1741823148IN
0xE856d35f...cEE24F473
0 MNT0.011123740.02
Swap Exact Token...768362292025-03-12 18:06:10317 days ago1741802770IN
0xE856d35f...cEE24F473
0 MNT0.017869350.03
Swap Exact Token...768275322025-03-12 13:16:16318 days ago1741785376IN
0xE856d35f...cEE24F473
0 MNT0.018592550.03
Swap Exact Token...767609372025-03-11 0:16:26319 days ago1741652186IN
0xE856d35f...cEE24F473
0 MNT0.00343940.02
Swap Exact Token...767608072025-03-11 0:12:06319 days ago1741651926IN
0xE856d35f...cEE24F473
0 MNT0.014049730.02
Remove Liquidity766690212025-03-08 21:12:34321 days ago1741468354IN
0xE856d35f...cEE24F473
0 MNT0.015894290.02
Swap Exact Token...765668922025-03-06 12:28:16324 days ago1741264096IN
0xE856d35f...cEE24F473
0 MNT0.022663120.03
Swap Exact Token...765565412025-03-06 6:43:14324 days ago1741243394IN
0xE856d35f...cEE24F473
0 MNT0.018771660.025
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
773265082025-03-24 2:28:48306 days ago1742783328
0xE856d35f...cEE24F473
8.5803995 MNT
773265082025-03-24 2:28:48306 days ago1742783328
0xE856d35f...cEE24F473
8.5803995 MNT
770393632025-03-17 10:57:18313 days ago1742209038
0xE856d35f...cEE24F473
1.93240484 MNT
770393632025-03-17 10:57:18313 days ago1742209038
0xE856d35f...cEE24F473
1.93240484 MNT
768465272025-03-12 23:49:26317 days ago1741823366
0xE856d35f...cEE24F473
0.20706718 MNT
768465272025-03-12 23:49:26317 days ago1741823366
0xE856d35f...cEE24F473
0.20706718 MNT
768464922025-03-12 23:48:16317 days ago1741823296
0xE856d35f...cEE24F473
0.20799269 MNT
768464922025-03-12 23:48:16317 days ago1741823296
0xE856d35f...cEE24F473
0.20799269 MNT
768275322025-03-12 13:16:16318 days ago1741785376
0xE856d35f...cEE24F473
2.90543829 MNT
768275322025-03-12 13:16:16318 days ago1741785376
0xE856d35f...cEE24F473
2.90543829 MNT
765668922025-03-06 12:28:16324 days ago1741264096
0xE856d35f...cEE24F473
11.9047655 MNT
765668922025-03-06 12:28:16324 days ago1741264096
0xE856d35f...cEE24F473
11.9047655 MNT
765565412025-03-06 6:43:14324 days ago1741243394
0xE856d35f...cEE24F473
0.09190931 MNT
765565412025-03-06 6:43:14324 days ago1741243394
0xE856d35f...cEE24F473
0.09190931 MNT
765550982025-03-06 5:55:08324 days ago1741240508
0xE856d35f...cEE24F473
0.88276189 MNT
765550982025-03-06 5:55:08324 days ago1741240508
0xE856d35f...cEE24F473
0.88276189 MNT
764881522025-03-04 16:43:36325 days ago1741106616
0xE856d35f...cEE24F473
0.0958715 MNT
764881522025-03-04 16:43:36325 days ago1741106616
0xE856d35f...cEE24F473
0.0958715 MNT
764124802025-03-02 22:41:12327 days ago1740955272
0xE856d35f...cEE24F473
0.41000571 MNT
764124802025-03-02 22:41:12327 days ago1740955272
0xE856d35f...cEE24F473
0.41000571 MNT
764030002025-03-02 17:25:12327 days ago1740936312
0xE856d35f...cEE24F473
1.56813326 MNT
764030002025-03-02 17:25:12327 days ago1740936312
0xE856d35f...cEE24F473
1.56813326 MNT
764019252025-03-02 16:49:22327 days ago1740934162
0xE856d35f...cEE24F473
1.1169671 MNT
764019252025-03-02 16:49:22327 days ago1740934162
0xE856d35f...cEE24F473
1.1169671 MNT
764016182025-03-02 16:39:08327 days ago1740933548
0xE856d35f...cEE24F473
20.12805821 MNT
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x4531786B...815FD410c
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Router

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import "contracts/libraries/Math.sol";
import "contracts/interfaces/IERC20.sol";
import "contracts/interfaces/IPair.sol";
import "contracts/interfaces/IPairFactory.sol";
import "contracts/interfaces/IRouter.sol";
import "contracts/interfaces/IWETH.sol";

contract Router is IRouter {
  address public immutable factory;
  IWETH public immutable weth;
  uint internal constant MINIMUM_LIQUIDITY = 10 ** 3;
  bytes32 immutable pairCodeHash;

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

  constructor(address _factory, address _weth) {
    factory = _factory;
    pairCodeHash = IPairFactory(_factory).pairCodeHash();
    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");
  }

  // calculates the CREATE2 address for a pair without making any external calls
  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(
    uint amountA,
    uint reserveA,
    uint reserveB
  ) internal pure returns (uint 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 (uint reserveA, uint reserveB) {
    (address token0, ) = sortTokens(tokenA, tokenB);
    (uint reserve0, uint 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(
    uint amountIn,
    address tokenIn,
    address tokenOut
  ) external view returns (uint amount, bool stable) {
    address pair = pairFor(tokenIn, tokenOut, true);
    uint amountStable;
    uint 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(
    uint amountIn,
    route[] memory routes
  ) public view returns (uint[] memory amounts) {
    require(routes.length >= 1, "Router: INVALID_PATH");
    amounts = new uint[](routes.length + 1);
    amounts[0] = amountIn;
    for (uint 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,
    uint amountADesired,
    uint amountBDesired
  ) external view returns (uint amountA, uint amountB, uint liquidity) {
    // create the pair if it doesn't exist yet
    address _pair = IPairFactory(factory).getPair(tokenA, tokenB, stable);
    (uint reserveA, uint reserveB) = (0, 0);
    uint _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 {
      uint amountBOptimal = quoteLiquidity(amountADesired, reserveA, reserveB);
      if (amountBOptimal <= amountBDesired) {
        (amountA, amountB) = (amountADesired, amountBOptimal);
        liquidity = Math.min(
          (amountA * _totalSupply) / reserveA,
          (amountB * _totalSupply) / reserveB
        );
      } else {
        uint 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,
    uint liquidity
  ) external view returns (uint amountA, uint 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);
    }

    (uint reserveA, uint reserveB) = getReserves(tokenA, tokenB, stable);
    uint _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,
    uint amountADesired,
    uint amountBDesired,
    uint amountAMin,
    uint amountBMin
  ) internal returns (uint amountA, uint 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);
    }
    (uint reserveA, uint reserveB) = getReserves(tokenA, tokenB, stable);
    if (reserveA == 0 && reserveB == 0) {
      (amountA, amountB) = (amountADesired, amountBDesired);
    } else {
      uint amountBOptimal = quoteLiquidity(amountADesired, reserveA, reserveB);
      if (amountBOptimal <= amountBDesired) {
        require(amountBOptimal >= amountBMin, "Router: INSUFFICIENT_B_AMOUNT");
        (amountA, amountB) = (amountADesired, amountBOptimal);
      } else {
        uint 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,
    uint amountADesired,
    uint amountBDesired,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  )
    external
    ensure(deadline)
    returns (uint amountA, uint amountB, uint 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,
    uint amountTokenDesired,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  )
    external
    payable
    ensure(deadline)
    returns (uint amountToken, uint amountETH, uint 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,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  ) public ensure(deadline) returns (uint amountA, uint amountB) {
    address pair = pairFor(tokenA, tokenB, stable);
    require(IPair(pair).transferFrom(msg.sender, pair, liquidity)); // send liquidity to pair
    (uint amount0, uint 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,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) public ensure(deadline) returns (uint amountToken, uint 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,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline,
    bool approveMax,
    // uint8 v,
    // bytes32 r,
    // bytes32 s
    bytes calldata signature
  ) external returns (uint amountA, uint amountB) {
    address pair = pairFor(tokenA, tokenB, stable);
    {
      uint value = approveMax ? type(uint).max : liquidity;
      IPair(pair).permit(
        msg.sender,
        address(this),
        value,
        deadline,
        // v,
        // r,
        // s,
        signature
      );
    }

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

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

  // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens)****
  function removeLiquidityETHSupportingFeeOnTransferTokens(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) public ensure(deadline) returns (uint amountToken, uint amountETH) {
    (amountToken, amountETH) = removeLiquidity(
      token,
      address(weth),
      stable,
      liquidity,
      amountTokenMin,
      amountETHMin,
      address(this),
      deadline
    );
    _safeTransfer(token, to, IERC20(token).balanceOf(address(this)));
    weth.withdraw(amountETH);
    _safeTransferETH(to, amountETH);
  }

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

  // **** SWAP ****
  // requires the initial amount to have already been sent to the first pair
  function _swap(
    uint[] memory amounts,
    route[] memory routes,
    address _to
  ) internal virtual {
    for (uint i = 0; i < routes.length; i++) {
      (address token0, ) = sortTokens(routes[i].from, routes[i].to);
      uint amountOut = amounts[i + 1];
      (uint amount0Out, uint amount1Out) = routes[i].from == token0
        ? (uint(0), amountOut)
        : (amountOut, uint(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)
      );
    }
  }

  function swapExactTokensForTokensSimple(
    uint amountIn,
    uint amountOutMin,
    address tokenFrom,
    address tokenTo,
    bool stable,
    address to,
    uint deadline
  ) external ensure(deadline) returns (uint[] 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(
    uint amountIn,
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external ensure(deadline) returns (uint[] 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(
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external payable ensure(deadline) returns (uint[] 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(
    uint amountIn,
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external ensure(deadline) returns (uint[] 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]);
  }

  // **** SWAP (supporting fee-on-transfer tokens) ****
  function _swapSupportingFeeOnTransferTokens(
    route[] memory routes,
    address _to
  ) internal virtual {
    for (uint i; i < routes.length; i++) {
      (address input, address output) = (routes[i].from, routes[i].to);
      (address token0, ) = sortTokens(input, output);
      IPair pair = IPair(
        pairFor(routes[i].from, routes[i].to, routes[i].stable)
      );
      uint amountInput;
      uint amountOutput;
      {
        // scope to avoid stack too deep errors
        (uint reserve0, uint reserve1, ) = pair.getReserves();
        uint reserveInput = input == token0 ? reserve0 : reserve1;
        amountInput = IERC20(input).balanceOf(address(pair)) - reserveInput;
        //(amountOutput,) = getAmountOut(amountInput, input, output, stable);
        amountOutput = pair.getAmountOut(amountInput, input);
      }
      (uint amount0Out, uint amount1Out) = input == token0
        ? (uint(0), amountOutput)
        : (amountOutput, uint(0));
      address to = i < routes.length - 1
        ? pairFor(routes[i + 1].from, routes[i + 1].to, routes[i + 1].stable)
        : _to;
      pair.swap(amount0Out, amount1Out, to, new bytes(0));
    }
  }

  function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external ensure(deadline) {
    _safeTransferFrom(
      routes[0].from,
      msg.sender,
      pairFor(routes[0].from, routes[0].to, routes[0].stable),
      amountIn
    );
    uint balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf(to);
    _swapSupportingFeeOnTransferTokens(routes, to);
    require(
      IERC20(routes[routes.length - 1].to).balanceOf(to) - balanceBefore >=
        amountOutMin,
      "Router: INSUFFICIENT_OUTPUT_AMOUNT"
    );
  }

  function swapExactETHForTokensSupportingFeeOnTransferTokens(
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external payable ensure(deadline) {
    require(routes[0].from == address(weth), "Router: INVALID_PATH");
    uint amountIn = msg.value;
    weth.deposit{ value: amountIn }();
    assert(
      weth.transfer(
        pairFor(routes[0].from, routes[0].to, routes[0].stable),
        amountIn
      )
    );
    uint balanceBefore = IERC20(routes[routes.length - 1].to).balanceOf(to);
    _swapSupportingFeeOnTransferTokens(routes, to);
    require(
      IERC20(routes[routes.length - 1].to).balanceOf(to) - balanceBefore >=
        amountOutMin,
      "Router: INSUFFICIENT_OUTPUT_AMOUNT"
    );
  }

  function swapExactTokensForETHSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external ensure(deadline) {
    require(
      routes[routes.length - 1].to == address(weth),
      "Router: INVALID_PATH"
    );
    _safeTransferFrom(
      routes[0].from,
      msg.sender,
      pairFor(routes[0].from, routes[0].to, routes[0].stable),
      amountIn
    );
    _swapSupportingFeeOnTransferTokens(routes, address(this));
    uint amountOut = IERC20(address(weth)).balanceOf(address(this));
    require(amountOut >= amountOutMin, "Router: INSUFFICIENT_OUTPUT_AMOUNT");
    weth.withdraw(amountOut);
    _safeTransferETH(to, amountOut);
  }

  function UNSAFE_swapExactTokensForTokens(
    uint[] memory amounts,
    route[] calldata routes,
    address to,
    uint deadline
  ) external ensure(deadline) returns (uint[] memory) {
    _safeTransferFrom(
      routes[0].from,
      msg.sender,
      pairFor(routes[0].from, routes[0].to, routes[0].stable),
      amounts[0]
    );
    _swap(amounts, routes, to);
    return amounts;
  }

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

  function _safeTransfer(address token, address to, uint256 value) internal {
    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 {
    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))));
  }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

interface IERC20 {
  function totalSupply() external view returns (uint256);

  function transfer(address recipient, uint amount) external returns (bool);

  function decimals() external view returns (uint8);

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

  function balanceOf(address) external view returns (uint);

  function transferFrom(
    address sender,
    address recipient,
    uint amount
  ) external returns (bool);

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

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

  event Transfer(address indexed from, address indexed to, uint value);
  event Approval(address indexed owner, address indexed spender, uint value);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

interface IPair {
  function metadata()
    external
    view
    returns (
      uint dec0,
      uint dec1,
      uint r0,
      uint r1,
      bool st,
      address t0,
      address t1
    );

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

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

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

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

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

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

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

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

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

  function current(
    address tokenIn,
    uint amountIn
  ) external view returns (uint amountOut);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

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

  function getPairByIndex(uint idx) external view returns (address);

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

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

  function pairCodeHash() external pure returns (bytes32);

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

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

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

interface IRouter {
  struct route {
    address from;
    address to;
    bool stable;
  }

  function sortTokens(
    address tokenA,
    address tokenB
  ) external view returns (address token0, address token1);

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

  function getReserves(
    address tokenA,
    address tokenB,
    bool stable
  ) external view returns (uint reserveA, uint reserveB);

  function getAmountOut(
    uint amountIn,
    address tokenIn,
    address tokenOut
  ) external view returns (uint amount, bool stable);

  function getAmountsOut(
    uint amountIn,
    route[] memory routes
  ) external view returns (uint[] memory amounts);

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

  function quoteAddLiquidity(
    address tokenA,
    address tokenB,
    bool stable,
    uint amountADesired,
    uint amountBDesired
  ) external view returns (uint amountA, uint amountB, uint liquidity);

  function quoteRemoveLiquidity(
    address tokenA,
    address tokenB,
    bool stable,
    uint liquidity
  ) external view returns (uint amountA, uint amountB);

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

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

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

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

  function removeLiquidityWithPermit(
    address tokenA,
    address tokenB,
    bool stable,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline,
    bool approveMax,
    bytes calldata signature
  ) external returns (uint amountA, uint amountB);

  function removeLiquidityETHWithPermit(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline,
    bool approveMax,
    bytes calldata signature
  ) external returns (uint amountToken, uint amountETH);

  function removeLiquidityETHSupportingFeeOnTransferTokens(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) external returns (uint amountToken, uint amountETH);

  function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline,
    bool approveMax,
    bytes calldata signature
  ) external returns (uint amountToken, uint amountETH);

  function swapExactTokensForTokensSimple(
    uint amountIn,
    uint amountOutMin,
    address tokenFrom,
    address tokenTo,
    bool stable,
    address to,
    uint deadline
  ) external returns (uint[] memory amounts);

  function swapExactTokensForTokens(
    uint amountIn,
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external returns (uint[] memory amounts);

  function swapExactETHForTokens(
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external payable returns (uint[] memory amounts);

  function swapExactTokensForETH(
    uint amountIn,
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external returns (uint[] memory amounts);

  function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external;

  function swapExactETHForTokensSupportingFeeOnTransferTokens(
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external payable;

  function swapExactTokensForETHSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    route[] calldata routes,
    address to,
    uint deadline
  ) external;

  function UNSAFE_swapExactTokensForTokens(
    uint[] memory amounts,
    route[] calldata routes,
    address to,
    uint deadline
  ) external returns (uint[] memory);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

interface IWETH {
  function deposit() external payable;

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

  function withdraw(uint256) external;

  function balanceOf(address) external view returns (uint);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

library Math {
  function max(uint a, uint b) internal pure returns (uint) {
    return a >= b ? a : b;
  }

  function min(uint a, uint b) internal pure returns (uint) {
    return a < b ? a : b;
  }

  function sqrt(uint y) internal pure returns (uint z) {
    if (y > 3) {
      z = y;
      uint x = y / 2 + 1;
      while (x < z) {
        z = x;
        x = (y / x + x) / 2;
      }
    } else if (y != 0) {
      z = 1;
    }
  }

  function cbrt(uint256 n) internal pure returns (uint256) {
    unchecked {
      uint256 x = 0;
      for (uint256 y = 1 << 255; y > 0; y >>= 3) {
        x <<= 1;
        uint256 z = 3 * x * (x + 1) + 1;
        if (n / y >= z) {
          n -= y * z;
          x += 1;
        }
      }
      return x;
    }
  }

  function sub(uint x, uint y) internal pure returns (uint z) {
    require((z = x - y) <= x, "Math: Sub-underflow");
  }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_weth","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct IRouter.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"UNSAFE_swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"","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":"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 IRouter.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"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","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":"bytes","name":"signature","type":"bytes"}],"name":"removeLiquidityETHWithPermit","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":"bytes","name":"signature","type":"bytes"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","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":"bytes","name":"signature","type":"bytes"}],"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 IRouter.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":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct IRouter.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"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 IRouter.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 IRouter.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"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 IRouter.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":[{"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 IRouter.route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

0x60e06040523480156200001157600080fd5b506040516200476e3803806200476e8339810160408190526200003491620000d8565b6001600160a01b038216608081905260408051631355724960e31b81529051639aab9248916004808201926020929091908290030181865afa1580156200007f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a5919062000110565b60c0526001600160a01b031660a052506200012a565b80516001600160a01b0381168114620000d357600080fd5b919050565b60008060408385031215620000ec57600080fd5b620000f783620000bb565b91506200010760208401620000bb565b90509250929050565b6000602082840312156200012357600080fd5b5051919050565b60805160a05160c0516145456200022960003960005050600081816101950152818161028201528181610a0301528181610c4201528181610d2c015281816114e7015281816115fa0152818161168801528181611b5901528181611bd701528181611c4b01528181611e9c01528181611fa00152818161204b015281816126060152818161263c015281816126710152818161270601528181612845015281816128950152818161291b0152612bb10152600081816104d701528181610dfa01528181610f74015281816111ee015281816113020152818161226e015281816123e2015281816129ef015281816130a7015261314801526145456000f3fe6080604052600436106101855760003560e01c80637301e3c8116100d1578063b7e0d4c01161008a578063d9dce3aa11610064578063d9dce3aa14610519578063e5e31b1314610539578063f41766d814610569578063fe411f141461058957600080fd5b8063b7e0d4c0146104b2578063c45a0155146104c5578063d7b0e0a5146104f957600080fd5b80637301e3c8146103ff57806376c727511461041f5780637af728c81461043257806384808c29146104525780639881fcb41461047257806398a0fb3c1461049257600080fd5b80634c1ee03e1161013e5780635e1e6325116101185780635e1e6325146103775780635e60dab5146103ac57806367ffb66a146103cc5780636cc1ae13146103df57600080fd5b80634c1ee03e146102dc578063544caa56146102fc5780635a47ddc31461033c57600080fd5b80630dede6c4146101c957806313dcfc591461020357806318a13086146102305780632a6ca10f146102505780633fc8cef3146102705780634386e63c146102bc57600080fd5b366101c457336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101c2576101c2613898565b005b600080fd5b3480156101d557600080fd5b506101e96101e43660046138df565b6105a9565b604080519283526020830191909152015b60405180910390f35b34801561020f57600080fd5b5061022361021e366004613964565b6107c3565b6040516101fa91906139df565b34801561023c57600080fd5b5061022361024b366004613a68565b6109d6565b34801561025c57600080fd5b506101e961026b366004613b1d565b610d21565b34801561027c57600080fd5b506102a47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101fa565b3480156102c857600080fd5b506101e96102d7366004613bd6565b610df3565b3480156102e857600080fd5b506102a46102f7366004613c27565b610f5a565b34801561030857600080fd5b5061031c610317366004613c72565b610ff6565b604080516001600160a01b039384168152929091166020830152016101fa565b34801561034857600080fd5b5061035c610357366004613cab565b6110d6565b604080519384526020840192909252908201526060016101fa565b34801561038357600080fd5b50610397610392366004613d3a565b6111b6565b604080519283529015156020830152016101fa565b3480156103b857600080fd5b506101e96103c7366004613c27565b61140a565b6102236103da366004613d71565b6114c2565b3480156103eb57600080fd5b506101c26103fa366004613a68565b611821565b34801561040b57600080fd5b5061022361041a366004613e43565b611a60565b6101c261042d366004613d71565b611b36565b34801561043e57600080fd5b506101c261044d366004613a68565b611e71565b34801561045e57600080fd5b506101e961046d366004613f0f565b6120b9565b34801561047e57600080fd5b5061022361048d366004614052565b612158565b34801561049e57600080fd5b5061035c6104ad3660046140f8565b6123da565b61035c6104c0366004614153565b6125da565b3480156104d157600080fd5b506102a47f000000000000000000000000000000000000000000000000000000000000000081565b34801561050557600080fd5b506101e9610514366004614153565b61281b565b34801561052557600080fd5b506101e9610534366004613b1d565b612910565b34801561054557600080fd5b506105596105543660046141ae565b6129cd565b60405190151581526020016101fa565b34801561057557600080fd5b50610223610584366004613a68565b612a62565b34801561059557600080fd5b506101e96105a4366004614153565b612b87565b60008082428110156105d65760405162461bcd60e51b81526004016105cd906141cb565b60405180910390fd5b60006105e38c8c8c610f5a565b6040516323b872dd60e01b81523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af1158015610639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065d91906141f4565b61066657600080fd5b60405163226bf2d160e21b81526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af11580156106b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d69190614211565b9150915060006106e68f8f610ff6565b509050806001600160a01b03168f6001600160a01b03161461070957818361070c565b82825b90975095508a8710156107615760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e5400000060448201526064016105cd565b898610156107b15760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e5400000060448201526064016105cd565b50505050509850989650505050505050565b606081428110156107e65760405162461bcd60e51b81526004016105cd906141cb565b604080516001808252818301909252600091816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816107fd579050509050878160008151811061084057610840614235565b6020026020010151600001906001600160a01b031690816001600160a01b031681525050868160008151811061087857610878614235565b6020026020010151602001906001600160a01b031690816001600160a01b03168152505085816000815181106108b0576108b0614235565b60209081029190910101519015156040909101526108ce8a82612158565b92508883600185516108e09190614261565b815181106108f0576108f0614235565b602002602001015110156109165760405162461bcd60e51b81526004016105cd90614278565b6109be8160008151811061092c5761092c614235565b6020026020010151600001513361099e8460008151811061094f5761094f614235565b6020026020010151600001518560008151811061096e5761096e614235565b6020026020010151602001518660008151811061098d5761098d614235565b602002602001015160400151610f5a565b866000815181106109b1576109b1614235565b6020026020010151612c55565b6109c9838287612d4d565b5050979650505050505050565b606081428110156109f95760405162461bcd60e51b81526004016105cd906141cb565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686610a30600182614261565b818110610a3f57610a3f614235565b9050606002016020016020810190610a5791906141ae565b6001600160a01b031614610a7d5760405162461bcd60e51b81526004016105cd906142ba565b610ad9888787808060200260200160405190810160405280939291908181526020016000905b82821015610acf57610ac0606083028601368190038101906142e8565b81526020019060010190610aa3565b5050505050612158565b9150868260018451610aeb9190614261565b81518110610afb57610afb614235565b60200260200101511015610b215760405162461bcd60e51b81526004016105cd90614278565b610be386866000818110610b3757610b37614235565b610b4d92602060609092020190810191506141ae565b33610bd089896000818110610b6457610b64614235565b610b7a92602060609092020190810191506141ae565b8a8a6000818110610b8d57610b8d614235565b9050606002016020016020810190610ba591906141ae565b8b8b6000818110610bb857610bb8614235565b90506060020160400160208101906102f79190614304565b856000815181106109b1576109b1614235565b610c40828787808060200260200160405190810160405280939291908181526020016000905b82821015610c3557610c26606083028601368190038101906142e8565b81526020019060010190610c09565b505050505030612d4d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d8360018551610c7e9190614261565b81518110610c8e57610c8e614235565b60200260200101516040518263ffffffff1660e01b8152600401610cb491815260200190565b600060405180830381600087803b158015610cce57600080fd5b505af1158015610ce2573d6000803e3d6000fd5b50505050610d16848360018551610cf99190614261565b81518110610d0957610d09614235565b6020026020010151612fa2565b509695505050505050565b6000806000610d518d7f00000000000000000000000000000000000000000000000000000000000000008e610f5a565b9050600086610d60578b610d64565b6000195b604051639fd5a6cf60e01b81529091506001600160a01b03831690639fd5a6cf90610d9d903390309086908e908d908d90600401614321565b600060405180830381600087803b158015610db757600080fd5b505af1158015610dcb573d6000803e3d6000fd5b50505050610dde8e8e8e8e8e8e8e61281b565b909f909e509c50505050505050505050505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308888886040518463ffffffff1660e01b8152600401610e489392919061437d565b602060405180830381865afa158015610e65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8991906143a1565b90506001600160a01b038116610ea6576000809250925050610f51565b600080610eb489898961140a565b915091506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ef8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1c91906143be565b905080610f2984896143d7565b610f3391906143f6565b955080610f4083896143d7565b610f4a91906143f6565b9450505050505b94509492505050565b6040516306801cc360e41b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636801cc3090610fad9087908790879060040161437d565b602060405180830381865afa158015610fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fee91906143a1565b949350505050565b600080826001600160a01b0316846001600160a01b03160361105a5760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a204944454e544943414c5f414444524553534553000000000060448201526064016105cd565b826001600160a01b0316846001600160a01b03161061107a57828461107d565b83835b90925090506001600160a01b0382166110cf5760405162461bcd60e51b8152602060048201526014602482015273526f757465723a205a45524f5f4144445245535360601b60448201526064016105cd565b9250929050565b600080600083428110156110fc5760405162461bcd60e51b81526004016105cd906141cb565b61110b8d8d8d8d8d8d8d613070565b9094509250600061111d8e8e8e610f5a565b905061112b8e338388612c55565b6111378d338387612c55565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af115801561117f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a391906143be565b9250505099509950999650505050505050565b60008060006111c785856001610f5a565b60405163e5e31b1360e01b81526001600160a01b03828116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015611237573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125b91906141f4565b156112d4576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa1580156112ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d191906143be565b91505b6112e087876000610f5a565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529194507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa15801561134b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136f91906141f4565b156113e8576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa1580156113c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e591906143be565b90505b8082116113f7578060006113fb565b8160015b94509450505050935093915050565b60008060006114198686610ff6565b50905060008061142a888888610f5a565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148b9190614418565b5091509150826001600160a01b0316886001600160a01b0316146114b05780826114b3565b81815b90999098509650505050505050565b606081428110156114e55760405162461bcd60e51b81526004016105cd906141cb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168686600081811061152257611522614235565b61153892602060609092020190810191506141ae565b6001600160a01b03161461155e5760405162461bcd60e51b81526004016105cd906142ba565b6115b0348787808060200260200160405190810160405280939291908181526020016000905b82821015610acf576115a1606083028601368190038101906142e8565b81526020019060010190611584565b91508682600184516115c29190614261565b815181106115d2576115d2614235565b602002602001015110156115f85760405162461bcd60e51b81526004016105cd90614278565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061163a5761163a614235565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561166d57600080fd5b505af1158015611681573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb61171f888860008181106116cb576116cb614235565b6116e192602060609092020190810191506141ae565b898960008181106116f4576116f4614235565b905060600201602001602081019061170c91906141ae565b8a8a6000818110610bb857610bb8614235565b8460008151811061173257611732614235565b60200260200101516040518363ffffffff1660e01b815260040161176b9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af115801561178a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ae91906141f4565b6117ba576117ba613898565b611817828787808060200260200160405190810160405280939291908181526020016000905b8282101561180c576117fd606083028601368190038101906142e8565b815260200190600101906117e0565b505050505086612d4d565b5095945050505050565b80428110156118425760405162461bcd60e51b81526004016105cd906141cb565b61188b8585600081811061185857611858614235565b61186e92602060609092020190810191506141ae565b33611885888860008181106116cb576116cb614235565b8a612c55565b6000858561189a600182614261565b8181106118a9576118a9614235565b90506060020160200160208101906118c191906141ae565b6040516370a0823160e01b81526001600160a01b03868116600483015291909116906370a0823190602401602060405180830381865afa158015611909573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192d91906143be565b905061198b8686808060200260200160405190810160405280939291908181526020016000905b8282101561198057611971606083028601368190038101906142e8565b81526020019060010190611954565b5050505050856132ee565b8681878761199a600182614261565b8181106119a9576119a9614235565b90506060020160200160208101906119c191906141ae565b6040516370a0823160e01b81526001600160a01b03888116600483015291909116906370a08231906024015b602060405180830381865afa158015611a0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2e91906143be565b611a389190614261565b1015611a565760405162461bcd60e51b81526004016105cd90614278565b5050505050505050565b60608142811015611a835760405162461bcd60e51b81526004016105cd906141cb565b611ad986866000818110611a9957611a99614235565b611aaf92602060609092020190810191506141ae565b33611ac689896000818110610b6457610b64614235565b8a6000815181106109b1576109b1614235565b611b2b878787808060200260200160405190810160405280939291908181526020016000905b8282101561180c57611b1c606083028601368190038101906142e8565b81526020019060010190611aff565b509495945050505050565b8042811015611b575760405162461bcd60e51b81526004016105cd906141cb565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685856000818110611b9457611b94614235565b611baa92602060609092020190810191506141ae565b6001600160a01b031614611bd05760405162461bcd60e51b81526004016105cd906142ba565b60003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c3057600080fd5b505af1158015611c44573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb611c8e888860008181106116cb576116cb614235565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015611cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cff91906141f4565b611d0b57611d0b613898565b60008686611d1a600182614261565b818110611d2957611d29614235565b9050606002016020016020810190611d4191906141ae565b6040516370a0823160e01b81526001600160a01b03878116600483015291909116906370a0823190602401602060405180830381865afa158015611d89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dad91906143be565b9050611e0b8787808060200260200160405190810160405280939291908181526020016000905b82821015611e0057611df1606083028601368190038101906142e8565b81526020019060010190611dd4565b5050505050866132ee565b87818888611e1a600182614261565b818110611e2957611e29614235565b9050606002016020016020810190611e4191906141ae565b6040516370a0823160e01b81526001600160a01b03898116600483015291909116906370a08231906024016119ed565b8042811015611e925760405162461bcd60e51b81526004016105cd906141cb565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585611ec9600182614261565b818110611ed857611ed8614235565b9050606002016020016020810190611ef091906141ae565b6001600160a01b031614611f165760405162461bcd60e51b81526004016105cd906142ba565b611f2c8585600081811061185857611858614235565b611f888585808060200260200160405190810160405280939291908181526020016000905b82821015611f7d57611f6e606083028601368190038101906142e8565b81526020019060010190611f51565b5050505050306132ee565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611fef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201391906143be565b9050868110156120355760405162461bcd60e51b81526004016105cd90614278565b604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561209757600080fd5b505af11580156120ab573d6000803e3d6000fd5b50505050611a568482612fa2565b60008060006120c98e8e8e610f5a565b90506000866120d8578b6120dc565b6000195b604051639fd5a6cf60e01b81529091506001600160a01b03831690639fd5a6cf90612115903390309086908e908d908d90600401614321565b600060405180830381600087803b15801561212f57600080fd5b505af1158015612143573d6000803e3d6000fd5b5050505050610dde8e8e8e8e8e8e8e8e6105a9565b606060018251101561217c5760405162461bcd60e51b81526004016105cd906142ba565b8151612189906001614446565b67ffffffffffffffff8111156121a1576121a1613dd8565b6040519080825280602002602001820160405280156121ca578160200160208202803683370190505b50905082816000815181106121e1576121e1614235565b60200260200101818152505060005b82518110156123d357600061224c84838151811061221057612210614235565b60200260200101516000015185848151811061222e5761222e614235565b60200260200101516020015186858151811061098d5761098d614235565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa1580156122b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122db91906141f4565b156123c057806001600160a01b031663f140a35a84848151811061230157612301614235565b602002602001015186858151811061231b5761231b614235565b6020026020010151600001516040518363ffffffff1660e01b81526004016123569291909182526001600160a01b0316602082015260400190565b602060405180830381865afa158015612373573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239791906143be565b836123a3846001614446565b815181106123b3576123b3614235565b6020026020010181815250505b50806123cb8161445e565b9150506121f0565b5092915050565b6000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308a8a8a6040518463ffffffff1660e01b81526004016124309392919061437d565b602060405180830381865afa15801561244d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247191906143a1565b9050600080806001600160a01b038416156124fb57836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e891906143be565b90506124f58c8c8c61140a565b90935091505b82158015612507575081155b15612538578896508795506103e8612527612522888a6143d7565b61365f565b6125319190614261565b94506125cb565b60006125458a85856136cf565b905088811161258d5789975095508561258684612562848b6143d7565b61256c91906143f6565b84612577858b6143d7565b61258191906143f6565b613791565b95506125c9565b600061259a8a85876136cf565b98508997508890506125c5856125b085846143d7565b6125ba91906143f6565b85612577868c6143d7565b9650505b505b50505050955095509592505050565b600080600083428110156126005760405162461bcd60e51b81526004016105cd906141cb565b61262f8b7f00000000000000000000000000000000000000000000000000000000000000008c8c348d8d613070565b909450925060006126618c7f00000000000000000000000000000000000000000000000000000000000000008d610f5a565b905061266f8c338388612c55565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156126ca57600080fd5b505af11580156126de573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b038581166004830152602482018990527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af1158015612753573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277791906141f4565b61278357612783613898565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af11580156127cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ef91906143be565b92508334111561280c5761280c336128078634614261565b612fa2565b50509750975097945050505050565b600080824281101561283f5760405162461bcd60e51b81526004016105cd906141cb565b61286f8a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b6105a9565b909350915061287f8a86856137a9565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156128e157600080fd5b505af11580156128f5573d6000803e3d6000fd5b505050506129038583612fa2565b5097509795505050505050565b60008060006129408d7f00000000000000000000000000000000000000000000000000000000000000008e610f5a565b905060008661294f578b612953565b6000195b604051639fd5a6cf60e01b81529091506001600160a01b03831690639fd5a6cf9061298c903390309086908e908d908d90600401614321565b600060405180830381600087803b1580156129a657600080fd5b505af11580156129ba573d6000803e3d6000fd5b50505050610dde8e8e8e8e8e8e8e612b87565b60405163e5e31b1360e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015612a38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a5c91906141f4565b92915050565b60608142811015612a855760405162461bcd60e51b81526004016105cd906141cb565b612ad7888787808060200260200160405190810160405280939291908181526020016000905b82821015610acf57612ac8606083028601368190038101906142e8565b81526020019060010190612aab565b9150868260018451612ae99190614261565b81518110612af957612af9614235565b60200260200101511015612b1f5760405162461bcd60e51b81526004016105cd90614278565b612b3586866000818110610b3757610b37614235565b610d16828787808060200260200160405190810160405280939291908181526020016000905b8282101561180c57612b78606083028601368190038101906142e8565b81526020019060010190612b5b565b6000808242811015612bab5760405162461bcd60e51b81526004016105cd906141cb565b612bdb8a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b6105a9565b6040516370a0823160e01b8152306004820152919450925061287f908b9087906001600160a01b038316906370a0823190602401602060405180830381865afa158015612c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5091906143be565b6137a9565b6000846001600160a01b03163b11612c6c57600080fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612cd091906144a3565b6000604051808303816000865af19150503d8060008114612d0d576040519150601f19603f3d011682016040523d82523d6000602084013e612d12565b606091505b5091509150818015612d3c575080511580612d3c575080806020019051810190612d3c91906141f4565b612d4557600080fd5b505050505050565b60005b8251811015612f9c576000612d9f848381518110612d7057612d70614235565b602002602001015160000151858481518110612d8e57612d8e614235565b602002602001015160200151610ff6565b509050600085612db0846001614446565b81518110612dc057612dc0614235565b60200260200101519050600080836001600160a01b0316878681518110612de957612de9614235565b6020026020010151600001516001600160a01b031614612e0b57826000612e0f565b6000835b91509150600060018851612e239190614261565b8610612e2f5786612ea2565b612ea288612e3e886001614446565b81518110612e4e57612e4e614235565b60200260200101516000015189886001612e689190614446565b81518110612e7857612e78614235565b6020026020010151602001518a896001612e929190614446565b8151811061098d5761098d614235565b9050612ef5888781518110612eb957612eb9614235565b602002602001015160000151898881518110612ed757612ed7614235565b6020026020010151602001518a898151811061098d5761098d614235565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f191660200182016040528015612f32576020820181803683370190505b506040518563ffffffff1660e01b8152600401612f5294939291906144bf565b600060405180830381600087803b158015612f6c57600080fd5b505af1158015612f80573d6000803e3d6000fd5b5050505050505050508080612f949061445e565b915050612d50565b50505050565b604080516000808252602082019092526001600160a01b038416908390604051612fcc91906144a3565b60006040518083038185875af1925050503d8060008114613009576040519150601f19603f3d011682016040523d82523d6000602084013e61300e565b606091505b505090508061306b5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b60648201526084016105cd565b505050565b6000808386101561308057600080fd5b8285101561308d57600080fd5b6040516306801cc360e41b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636801cc30906130e0908d908d908d9060040161437d565b602060405180830381865afa1580156130fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312191906143a1565b90506001600160a01b0381166131c7576040516320b7f73960e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906382dfdce490613181908d908d908d9060040161437d565b6020604051808303816000875af11580156131a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c491906143a1565b90505b6000806131d58c8c8c61140a565b915091508160001480156131e7575080155b156131f7578894508793506132df565b60006132048a84846136cf565b9050888111613268578681101561325d5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e5400000060448201526064016105cd565b8995509350836132dd565b60006132758a84866136cf565b90508a81111561328757613287613898565b888110156132d75760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e5400000060448201526064016105cd565b95508894505b505b50505097509795505050505050565b60005b825181101561306b5760008084838151811061330f5761330f614235565b60200260200101516000015185848151811061332d5761332d614235565b6020026020010151602001519150915060006133498383610ff6565b509050600061339f87868151811061336357613363614235565b60200260200101516000015188878151811061338157613381614235565b60200260200101516020015189888151811061098d5761098d614235565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156133e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134099190614418565b50915091506000866001600160a01b0316896001600160a01b03161461342f5781613431565b825b6040516370a0823160e01b81526001600160a01b03888116600483015291925082918b16906370a0823190602401602060405180830381865afa15801561347c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a091906143be565b6134aa9190614261565b6040516378a051ad60e11b8152600481018290526001600160a01b038b811660248301529196509087169063f140a35a90604401602060405180830381865afa1580156134fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351f91906143be565b9350505050600080856001600160a01b0316886001600160a01b0316146135485782600061354c565b6000835b91509150600060018c516135609190614261565b8a1061356c578a6135cf565b6135cf8c61357b8c6001614446565b8151811061358b5761358b614235565b6020026020010151600001518d8c60016135a59190614446565b815181106135b5576135b5614235565b6020026020010151602001518e8d6001612e929190614446565b6040805160008152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f9061361190869086908690602481016144bf565b600060405180830381600087803b15801561362b57600080fd5b505af115801561363f573d6000803e3d6000fd5b5050505050505050505050505080806136579061445e565b9150506132f1565b600060038211156136c057508060006136796002836143f6565b613684906001614446565b90505b818110156136ba5790508060028161369f81866143f6565b6136a99190614446565b6136b391906143f6565b9050613687565b50919050565b81156136ca575060015b919050565b60008084116137205760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a20494e53554646494349454e545f414d4f554e54000000000060448201526064016105cd565b6000831180156137305750600082115b61377c5760405162461bcd60e51b815260206004820152601e60248201527f526f757465723a20494e53554646494349454e545f4c4951554944495459000060448201526064016105cd565b8261378783866143d7565b610fee91906143f6565b60008183106137a057816137a2565b825b9392505050565b6000836001600160a01b03163b116137c057600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161381c91906144a3565b6000604051808303816000865af19150503d8060008114613859576040519150601f19603f3d011682016040523d82523d6000602084013e61385e565b606091505b509150915081801561388857508051158061388857508080602001905181019061388891906141f4565b61389157600080fd5b5050505050565b634e487b7160e01b600052600160045260246000fd5b6001600160a01b03811681146138c357600080fd5b50565b80356136ca816138ae565b80151581146138c357600080fd5b600080600080600080600080610100898b0312156138fc57600080fd5b8835613907816138ae565b97506020890135613917816138ae565b96506040890135613927816138d1565b9550606089013594506080890135935060a0890135925060c089013561394c816138ae565b8092505060e089013590509295985092959890939650565b600080600080600080600060e0888a03121561397f57600080fd5b87359650602088013595506040880135613998816138ae565b945060608801356139a8816138ae565b935060808801356139b8816138d1565b925060a08801356139c8816138ae565b8092505060c0880135905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015613a17578351835292840192918401916001016139fb565b50909695505050505050565b60008083601f840112613a3557600080fd5b50813567ffffffffffffffff811115613a4d57600080fd5b6020830191508360206060830285010111156110cf57600080fd5b60008060008060008060a08789031215613a8157600080fd5b8635955060208701359450604087013567ffffffffffffffff811115613aa657600080fd5b613ab289828a01613a23565b9095509350506060870135613ac6816138ae565b80925050608087013590509295509295509295565b60008083601f840112613aed57600080fd5b50813567ffffffffffffffff811115613b0557600080fd5b6020830191508360208285010111156110cf57600080fd5b6000806000806000806000806000806101208b8d031215613b3d57600080fd5b8a35613b48816138ae565b995060208b0135613b58816138d1565b985060408b0135975060608b0135965060808b0135955060a08b0135613b7d816138ae565b945060c08b0135935060e08b0135613b94816138d1565b92506101008b013567ffffffffffffffff811115613bb157600080fd5b613bbd8d828e01613adb565b915080935050809150509295989b9194979a5092959850565b60008060008060808587031215613bec57600080fd5b8435613bf7816138ae565b93506020850135613c07816138ae565b92506040850135613c17816138d1565b9396929550929360600135925050565b600080600060608486031215613c3c57600080fd5b8335613c47816138ae565b92506020840135613c57816138ae565b91506040840135613c67816138d1565b809150509250925092565b60008060408385031215613c8557600080fd5b8235613c90816138ae565b91506020830135613ca0816138ae565b809150509250929050565b60008060008060008060008060006101208a8c031215613cca57600080fd5b8935613cd5816138ae565b985060208a0135613ce5816138ae565b975060408a0135613cf5816138d1565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135613d21816138ae565b809250506101008a013590509295985092959850929598565b600080600060608486031215613d4f57600080fd5b833592506020840135613d61816138ae565b91506040840135613c67816138ae565b600080600080600060808688031215613d8957600080fd5b85359450602086013567ffffffffffffffff811115613da757600080fd5b613db388828901613a23565b9095509350506040860135613dc7816138ae565b949793965091946060013592915050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613e1757613e17613dd8565b604052919050565b600067ffffffffffffffff821115613e3957613e39613dd8565b5060051b60200190565b600080600080600060808688031215613e5b57600080fd5b853567ffffffffffffffff80821115613e7357600080fd5b818801915088601f830112613e8757600080fd5b81356020613e9c613e9783613e1f565b613dee565b82815260059290921b8401810191818101908c841115613ebb57600080fd5b948201945b83861015613ed957853582529482019490820190613ec0565b99505089013592505080821115613eef57600080fd5b50613efc88828901613a23565b9095509350613dc79050604087016138c6565b60008060008060008060008060008060006101408c8e031215613f3157600080fd5b8b35613f3c816138ae565b9a5060208c0135613f4c816138ae565b995060408c0135613f5c816138d1565b985060608c0135975060808c0135965060a08c0135955060c08c0135613f81816138ae565b945060e08c013593506101008c0135613f99816138d1565b92506101208c013567ffffffffffffffff811115613fb657600080fd5b613fc28e828f01613adb565b915080935050809150509295989b509295989b9093969950565b600060608284031215613fee57600080fd5b6040516060810181811067ffffffffffffffff8211171561401157614011613dd8565b6040529050808235614022816138ae565b81526020830135614032816138ae565b60208201526040830135614045816138d1565b6040919091015292915050565b6000806040838503121561406557600080fd5b8235915060208084013567ffffffffffffffff81111561408457600080fd5b8401601f8101861361409557600080fd5b80356140a3613e9782613e1f565b818152606091820283018401918482019190898411156140c257600080fd5b938501935b838510156140e8576140d98a86613fdc565b835293840193918501916140c7565b5080955050505050509250929050565b600080600080600060a0868803121561411057600080fd5b853561411b816138ae565b9450602086013561412b816138ae565b9350604086013561413b816138d1565b94979396509394606081013594506080013592915050565b600080600080600080600060e0888a03121561416e57600080fd5b8735614179816138ae565b96506020880135614189816138d1565b955060408801359450606088013593506080880135925060a08801356139c8816138ae565b6000602082840312156141c057600080fd5b81356137a2816138ae565b6020808252600f908201526e149bdd5d195c8e8811561412549151608a1b604082015260600190565b60006020828403121561420657600080fd5b81516137a2816138d1565b6000806040838503121561422457600080fd5b505080516020909101519092909150565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156142735761427361424b565b500390565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f55604082015261139560f21b606082015260800190565b6020808252601490820152730a4deeae8cae47440929cac82989288bea082a8960631b604082015260600190565b6000606082840312156142fa57600080fd5b6137a28383613fdc565b60006020828403121561431657600080fd5b81356137a2816138d1565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b6001600160a01b039384168152919092166020820152901515604082015260600190565b6000602082840312156143b357600080fd5b81516137a2816138ae565b6000602082840312156143d057600080fd5b5051919050565b60008160001904831182151516156143f1576143f161424b565b500290565b60008261441357634e487b7160e01b600052601260045260246000fd5b500490565b60008060006060848603121561442d57600080fd5b8351925060208401519150604084015190509250925092565b600082198211156144595761445961424b565b500190565b6000600182016144705761447061424b565b5060010190565b60005b8381101561449257818101518382015260200161447a565b83811115612f9c5750506000910152565b600082516144b5818460208701614477565b9190910192915050565b84815283602082015260018060a01b038316604082015260806060820152600082518060808401526144f88160a0850160208701614477565b601f01601f19169190910160a0019594505050505056fea2646970667358221220e591b2af3ea7fcca7fe871d8fe661c37454dbeaa75d1f2c8a7fdae926359ee4f64736f6c634300080d0033000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b200000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb8

Deployed Bytecode

0x6080604052600436106101855760003560e01c80637301e3c8116100d1578063b7e0d4c01161008a578063d9dce3aa11610064578063d9dce3aa14610519578063e5e31b1314610539578063f41766d814610569578063fe411f141461058957600080fd5b8063b7e0d4c0146104b2578063c45a0155146104c5578063d7b0e0a5146104f957600080fd5b80637301e3c8146103ff57806376c727511461041f5780637af728c81461043257806384808c29146104525780639881fcb41461047257806398a0fb3c1461049257600080fd5b80634c1ee03e1161013e5780635e1e6325116101185780635e1e6325146103775780635e60dab5146103ac57806367ffb66a146103cc5780636cc1ae13146103df57600080fd5b80634c1ee03e146102dc578063544caa56146102fc5780635a47ddc31461033c57600080fd5b80630dede6c4146101c957806313dcfc591461020357806318a13086146102305780632a6ca10f146102505780633fc8cef3146102705780634386e63c146102bc57600080fd5b366101c457336001600160a01b037f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb816146101c2576101c2613898565b005b600080fd5b3480156101d557600080fd5b506101e96101e43660046138df565b6105a9565b604080519283526020830191909152015b60405180910390f35b34801561020f57600080fd5b5061022361021e366004613964565b6107c3565b6040516101fa91906139df565b34801561023c57600080fd5b5061022361024b366004613a68565b6109d6565b34801561025c57600080fd5b506101e961026b366004613b1d565b610d21565b34801561027c57600080fd5b506102a47f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb881565b6040516001600160a01b0390911681526020016101fa565b3480156102c857600080fd5b506101e96102d7366004613bd6565b610df3565b3480156102e857600080fd5b506102a46102f7366004613c27565b610f5a565b34801561030857600080fd5b5061031c610317366004613c72565b610ff6565b604080516001600160a01b039384168152929091166020830152016101fa565b34801561034857600080fd5b5061035c610357366004613cab565b6110d6565b604080519384526020840192909252908201526060016101fa565b34801561038357600080fd5b50610397610392366004613d3a565b6111b6565b604080519283529015156020830152016101fa565b3480156103b857600080fd5b506101e96103c7366004613c27565b61140a565b6102236103da366004613d71565b6114c2565b3480156103eb57600080fd5b506101c26103fa366004613a68565b611821565b34801561040b57600080fd5b5061022361041a366004613e43565b611a60565b6101c261042d366004613d71565b611b36565b34801561043e57600080fd5b506101c261044d366004613a68565b611e71565b34801561045e57600080fd5b506101e961046d366004613f0f565b6120b9565b34801561047e57600080fd5b5061022361048d366004614052565b612158565b34801561049e57600080fd5b5061035c6104ad3660046140f8565b6123da565b61035c6104c0366004614153565b6125da565b3480156104d157600080fd5b506102a47f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b281565b34801561050557600080fd5b506101e9610514366004614153565b61281b565b34801561052557600080fd5b506101e9610534366004613b1d565b612910565b34801561054557600080fd5b506105596105543660046141ae565b6129cd565b60405190151581526020016101fa565b34801561057557600080fd5b50610223610584366004613a68565b612a62565b34801561059557600080fd5b506101e96105a4366004614153565b612b87565b60008082428110156105d65760405162461bcd60e51b81526004016105cd906141cb565b60405180910390fd5b60006105e38c8c8c610f5a565b6040516323b872dd60e01b81523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd906064016020604051808303816000875af1158015610639573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061065d91906141f4565b61066657600080fd5b60405163226bf2d160e21b81526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af11580156106b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d69190614211565b9150915060006106e68f8f610ff6565b509050806001600160a01b03168f6001600160a01b03161461070957818361070c565b82825b90975095508a8710156107615760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e5400000060448201526064016105cd565b898610156107b15760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e5400000060448201526064016105cd565b50505050509850989650505050505050565b606081428110156107e65760405162461bcd60e51b81526004016105cd906141cb565b604080516001808252818301909252600091816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816107fd579050509050878160008151811061084057610840614235565b6020026020010151600001906001600160a01b031690816001600160a01b031681525050868160008151811061087857610878614235565b6020026020010151602001906001600160a01b031690816001600160a01b03168152505085816000815181106108b0576108b0614235565b60209081029190910101519015156040909101526108ce8a82612158565b92508883600185516108e09190614261565b815181106108f0576108f0614235565b602002602001015110156109165760405162461bcd60e51b81526004016105cd90614278565b6109be8160008151811061092c5761092c614235565b6020026020010151600001513361099e8460008151811061094f5761094f614235565b6020026020010151600001518560008151811061096e5761096e614235565b6020026020010151602001518660008151811061098d5761098d614235565b602002602001015160400151610f5a565b866000815181106109b1576109b1614235565b6020026020010151612c55565b6109c9838287612d4d565b5050979650505050505050565b606081428110156109f95760405162461bcd60e51b81526004016105cd906141cb565b6001600160a01b037f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb8168686610a30600182614261565b818110610a3f57610a3f614235565b9050606002016020016020810190610a5791906141ae565b6001600160a01b031614610a7d5760405162461bcd60e51b81526004016105cd906142ba565b610ad9888787808060200260200160405190810160405280939291908181526020016000905b82821015610acf57610ac0606083028601368190038101906142e8565b81526020019060010190610aa3565b5050505050612158565b9150868260018451610aeb9190614261565b81518110610afb57610afb614235565b60200260200101511015610b215760405162461bcd60e51b81526004016105cd90614278565b610be386866000818110610b3757610b37614235565b610b4d92602060609092020190810191506141ae565b33610bd089896000818110610b6457610b64614235565b610b7a92602060609092020190810191506141ae565b8a8a6000818110610b8d57610b8d614235565b9050606002016020016020810190610ba591906141ae565b8b8b6000818110610bb857610bb8614235565b90506060020160400160208101906102f79190614304565b856000815181106109b1576109b1614235565b610c40828787808060200260200160405190810160405280939291908181526020016000905b82821015610c3557610c26606083028601368190038101906142e8565b81526020019060010190610c09565b505050505030612d4d565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b0316632e1a7d4d8360018551610c7e9190614261565b81518110610c8e57610c8e614235565b60200260200101516040518263ffffffff1660e01b8152600401610cb491815260200190565b600060405180830381600087803b158015610cce57600080fd5b505af1158015610ce2573d6000803e3d6000fd5b50505050610d16848360018551610cf99190614261565b81518110610d0957610d09614235565b6020026020010151612fa2565b509695505050505050565b6000806000610d518d7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88e610f5a565b9050600086610d60578b610d64565b6000195b604051639fd5a6cf60e01b81529091506001600160a01b03831690639fd5a6cf90610d9d903390309086908e908d908d90600401614321565b600060405180830381600087803b158015610db757600080fd5b505af1158015610dcb573d6000803e3d6000fd5b50505050610dde8e8e8e8e8e8e8e61281b565b909f909e509c50505050505050505050505050565b60008060007f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b26001600160a01b0316636801cc308888886040518463ffffffff1660e01b8152600401610e489392919061437d565b602060405180830381865afa158015610e65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8991906143a1565b90506001600160a01b038116610ea6576000809250925050610f51565b600080610eb489898961140a565b915091506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ef8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f1c91906143be565b905080610f2984896143d7565b610f3391906143f6565b955080610f4083896143d7565b610f4a91906143f6565b9450505050505b94509492505050565b6040516306801cc360e41b81526000906001600160a01b037f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b21690636801cc3090610fad9087908790879060040161437d565b602060405180830381865afa158015610fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fee91906143a1565b949350505050565b600080826001600160a01b0316846001600160a01b03160361105a5760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a204944454e544943414c5f414444524553534553000000000060448201526064016105cd565b826001600160a01b0316846001600160a01b03161061107a57828461107d565b83835b90925090506001600160a01b0382166110cf5760405162461bcd60e51b8152602060048201526014602482015273526f757465723a205a45524f5f4144445245535360601b60448201526064016105cd565b9250929050565b600080600083428110156110fc5760405162461bcd60e51b81526004016105cd906141cb565b61110b8d8d8d8d8d8d8d613070565b9094509250600061111d8e8e8e610f5a565b905061112b8e338388612c55565b6111378d338387612c55565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af115801561117f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a391906143be565b9250505099509950999650505050505050565b60008060006111c785856001610f5a565b60405163e5e31b1360e01b81526001600160a01b03828116600483015291925060009182917f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b29091169063e5e31b1390602401602060405180830381865afa158015611237573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125b91906141f4565b156112d4576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa1580156112ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d191906143be565b91505b6112e087876000610f5a565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529194507f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b29091169063e5e31b1390602401602060405180830381865afa15801561134b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061136f91906141f4565b156113e8576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa1580156113c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e591906143be565b90505b8082116113f7578060006113fb565b8160015b94509450505050935093915050565b60008060006114198686610ff6565b50905060008061142a888888610f5a565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611467573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061148b9190614418565b5091509150826001600160a01b0316886001600160a01b0316146114b05780826114b3565b81815b90999098509650505050505050565b606081428110156114e55760405162461bcd60e51b81526004016105cd906141cb565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b03168686600081811061152257611522614235565b61153892602060609092020190810191506141ae565b6001600160a01b03161461155e5760405162461bcd60e51b81526004016105cd906142ba565b6115b0348787808060200260200160405190810160405280939291908181526020016000905b82821015610acf576115a1606083028601368190038101906142e8565b81526020019060010190611584565b91508682600184516115c29190614261565b815181106115d2576115d2614235565b602002602001015110156115f85760405162461bcd60e51b81526004016105cd90614278565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663d0e30db08360008151811061163a5761163a614235565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561166d57600080fd5b505af1158015611681573d6000803e3d6000fd5b50505050507f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663a9059cbb61171f888860008181106116cb576116cb614235565b6116e192602060609092020190810191506141ae565b898960008181106116f4576116f4614235565b905060600201602001602081019061170c91906141ae565b8a8a6000818110610bb857610bb8614235565b8460008151811061173257611732614235565b60200260200101516040518363ffffffff1660e01b815260040161176b9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af115801561178a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ae91906141f4565b6117ba576117ba613898565b611817828787808060200260200160405190810160405280939291908181526020016000905b8282101561180c576117fd606083028601368190038101906142e8565b815260200190600101906117e0565b505050505086612d4d565b5095945050505050565b80428110156118425760405162461bcd60e51b81526004016105cd906141cb565b61188b8585600081811061185857611858614235565b61186e92602060609092020190810191506141ae565b33611885888860008181106116cb576116cb614235565b8a612c55565b6000858561189a600182614261565b8181106118a9576118a9614235565b90506060020160200160208101906118c191906141ae565b6040516370a0823160e01b81526001600160a01b03868116600483015291909116906370a0823190602401602060405180830381865afa158015611909573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061192d91906143be565b905061198b8686808060200260200160405190810160405280939291908181526020016000905b8282101561198057611971606083028601368190038101906142e8565b81526020019060010190611954565b5050505050856132ee565b8681878761199a600182614261565b8181106119a9576119a9614235565b90506060020160200160208101906119c191906141ae565b6040516370a0823160e01b81526001600160a01b03888116600483015291909116906370a08231906024015b602060405180830381865afa158015611a0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a2e91906143be565b611a389190614261565b1015611a565760405162461bcd60e51b81526004016105cd90614278565b5050505050505050565b60608142811015611a835760405162461bcd60e51b81526004016105cd906141cb565b611ad986866000818110611a9957611a99614235565b611aaf92602060609092020190810191506141ae565b33611ac689896000818110610b6457610b64614235565b8a6000815181106109b1576109b1614235565b611b2b878787808060200260200160405190810160405280939291908181526020016000905b8282101561180c57611b1c606083028601368190038101906142e8565b81526020019060010190611aff565b509495945050505050565b8042811015611b575760405162461bcd60e51b81526004016105cd906141cb565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031685856000818110611b9457611b94614235565b611baa92602060609092020190810191506141ae565b6001600160a01b031614611bd05760405162461bcd60e51b81526004016105cd906142ba565b60003490507f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611c3057600080fd5b505af1158015611c44573d6000803e3d6000fd5b50505050507f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663a9059cbb611c8e888860008181106116cb576116cb614235565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af1158015611cdb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cff91906141f4565b611d0b57611d0b613898565b60008686611d1a600182614261565b818110611d2957611d29614235565b9050606002016020016020810190611d4191906141ae565b6040516370a0823160e01b81526001600160a01b03878116600483015291909116906370a0823190602401602060405180830381865afa158015611d89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dad91906143be565b9050611e0b8787808060200260200160405190810160405280939291908181526020016000905b82821015611e0057611df1606083028601368190038101906142e8565b81526020019060010190611dd4565b5050505050866132ee565b87818888611e1a600182614261565b818110611e2957611e29614235565b9050606002016020016020810190611e4191906141ae565b6040516370a0823160e01b81526001600160a01b03898116600483015291909116906370a08231906024016119ed565b8042811015611e925760405162461bcd60e51b81526004016105cd906141cb565b6001600160a01b037f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb8168585611ec9600182614261565b818110611ed857611ed8614235565b9050606002016020016020810190611ef091906141ae565b6001600160a01b031614611f165760405162461bcd60e51b81526004016105cd906142ba565b611f2c8585600081811061185857611858614235565b611f888585808060200260200160405190810160405280939291908181526020016000905b82821015611f7d57611f6e606083028601368190038101906142e8565b81526020019060010190611f51565b5050505050306132ee565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b0316906370a0823190602401602060405180830381865afa158015611fef573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061201391906143be565b9050868110156120355760405162461bcd60e51b81526004016105cd90614278565b604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561209757600080fd5b505af11580156120ab573d6000803e3d6000fd5b50505050611a568482612fa2565b60008060006120c98e8e8e610f5a565b90506000866120d8578b6120dc565b6000195b604051639fd5a6cf60e01b81529091506001600160a01b03831690639fd5a6cf90612115903390309086908e908d908d90600401614321565b600060405180830381600087803b15801561212f57600080fd5b505af1158015612143573d6000803e3d6000fd5b5050505050610dde8e8e8e8e8e8e8e8e6105a9565b606060018251101561217c5760405162461bcd60e51b81526004016105cd906142ba565b8151612189906001614446565b67ffffffffffffffff8111156121a1576121a1613dd8565b6040519080825280602002602001820160405280156121ca578160200160208202803683370190505b50905082816000815181106121e1576121e1614235565b60200260200101818152505060005b82518110156123d357600061224c84838151811061221057612210614235565b60200260200101516000015185848151811061222e5761222e614235565b60200260200101516020015186858151811061098d5761098d614235565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b29091169063e5e31b1390602401602060405180830381865afa1580156122b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122db91906141f4565b156123c057806001600160a01b031663f140a35a84848151811061230157612301614235565b602002602001015186858151811061231b5761231b614235565b6020026020010151600001516040518363ffffffff1660e01b81526004016123569291909182526001600160a01b0316602082015260400190565b602060405180830381865afa158015612373573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061239791906143be565b836123a3846001614446565b815181106123b3576123b3614235565b6020026020010181815250505b50806123cb8161445e565b9150506121f0565b5092915050565b6000806000807f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b26001600160a01b0316636801cc308a8a8a6040518463ffffffff1660e01b81526004016124309392919061437d565b602060405180830381865afa15801561244d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247191906143a1565b9050600080806001600160a01b038416156124fb57836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156124c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e891906143be565b90506124f58c8c8c61140a565b90935091505b82158015612507575081155b15612538578896508795506103e8612527612522888a6143d7565b61365f565b6125319190614261565b94506125cb565b60006125458a85856136cf565b905088811161258d5789975095508561258684612562848b6143d7565b61256c91906143f6565b84612577858b6143d7565b61258191906143f6565b613791565b95506125c9565b600061259a8a85876136cf565b98508997508890506125c5856125b085846143d7565b6125ba91906143f6565b85612577868c6143d7565b9650505b505b50505050955095509592505050565b600080600083428110156126005760405162461bcd60e51b81526004016105cd906141cb565b61262f8b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88c8c348d8d613070565b909450925060006126618c7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88d610f5a565b905061266f8c338388612c55565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156126ca57600080fd5b505af11580156126de573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b038581166004830152602482018990527f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb816935063a9059cbb925060440190506020604051808303816000875af1158015612753573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061277791906141f4565b61278357612783613898565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af11580156127cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127ef91906143be565b92508334111561280c5761280c336128078634614261565b612fa2565b50509750975097945050505050565b600080824281101561283f5760405162461bcd60e51b81526004016105cd906141cb565b61286f8a7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88b8b8b8b308b6105a9565b909350915061287f8a86856137a9565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156128e157600080fd5b505af11580156128f5573d6000803e3d6000fd5b505050506129038583612fa2565b5097509795505050505050565b60008060006129408d7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88e610f5a565b905060008661294f578b612953565b6000195b604051639fd5a6cf60e01b81529091506001600160a01b03831690639fd5a6cf9061298c903390309086908e908d908d90600401614321565b600060405180830381600087803b1580156129a657600080fd5b505af11580156129ba573d6000803e3d6000fd5b50505050610dde8e8e8e8e8e8e8e612b87565b60405163e5e31b1360e01b81526001600160a01b0382811660048301526000917f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b29091169063e5e31b1390602401602060405180830381865afa158015612a38573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a5c91906141f4565b92915050565b60608142811015612a855760405162461bcd60e51b81526004016105cd906141cb565b612ad7888787808060200260200160405190810160405280939291908181526020016000905b82821015610acf57612ac8606083028601368190038101906142e8565b81526020019060010190612aab565b9150868260018451612ae99190614261565b81518110612af957612af9614235565b60200260200101511015612b1f5760405162461bcd60e51b81526004016105cd90614278565b612b3586866000818110610b3757610b37614235565b610d16828787808060200260200160405190810160405280939291908181526020016000905b8282101561180c57612b78606083028601368190038101906142e8565b81526020019060010190612b5b565b6000808242811015612bab5760405162461bcd60e51b81526004016105cd906141cb565b612bdb8a7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88b8b8b8b308b6105a9565b6040516370a0823160e01b8152306004820152919450925061287f908b9087906001600160a01b038316906370a0823190602401602060405180830381865afa158015612c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c5091906143be565b6137a9565b6000846001600160a01b03163b11612c6c57600080fd5b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691612cd091906144a3565b6000604051808303816000865af19150503d8060008114612d0d576040519150601f19603f3d011682016040523d82523d6000602084013e612d12565b606091505b5091509150818015612d3c575080511580612d3c575080806020019051810190612d3c91906141f4565b612d4557600080fd5b505050505050565b60005b8251811015612f9c576000612d9f848381518110612d7057612d70614235565b602002602001015160000151858481518110612d8e57612d8e614235565b602002602001015160200151610ff6565b509050600085612db0846001614446565b81518110612dc057612dc0614235565b60200260200101519050600080836001600160a01b0316878681518110612de957612de9614235565b6020026020010151600001516001600160a01b031614612e0b57826000612e0f565b6000835b91509150600060018851612e239190614261565b8610612e2f5786612ea2565b612ea288612e3e886001614446565b81518110612e4e57612e4e614235565b60200260200101516000015189886001612e689190614446565b81518110612e7857612e78614235565b6020026020010151602001518a896001612e929190614446565b8151811061098d5761098d614235565b9050612ef5888781518110612eb957612eb9614235565b602002602001015160000151898881518110612ed757612ed7614235565b6020026020010151602001518a898151811061098d5761098d614235565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f191660200182016040528015612f32576020820181803683370190505b506040518563ffffffff1660e01b8152600401612f5294939291906144bf565b600060405180830381600087803b158015612f6c57600080fd5b505af1158015612f80573d6000803e3d6000fd5b5050505050505050508080612f949061445e565b915050612d50565b50505050565b604080516000808252602082019092526001600160a01b038416908390604051612fcc91906144a3565b60006040518083038185875af1925050503d8060008114613009576040519150601f19603f3d011682016040523d82523d6000602084013e61300e565b606091505b505090508061306b5760405162461bcd60e51b815260206004820152602360248201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960448201526213115160ea1b60648201526084016105cd565b505050565b6000808386101561308057600080fd5b8285101561308d57600080fd5b6040516306801cc360e41b81526000906001600160a01b037f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b21690636801cc30906130e0908d908d908d9060040161437d565b602060405180830381865afa1580156130fd573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061312191906143a1565b90506001600160a01b0381166131c7576040516320b7f73960e21b81526001600160a01b037f000000000000000000000000061ffe84b0f9e1669a6bf24548e5390dbf1e03b216906382dfdce490613181908d908d908d9060040161437d565b6020604051808303816000875af11580156131a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131c491906143a1565b90505b6000806131d58c8c8c61140a565b915091508160001480156131e7575080155b156131f7578894508793506132df565b60006132048a84846136cf565b9050888111613268578681101561325d5760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f425f414d4f554e5400000060448201526064016105cd565b8995509350836132dd565b60006132758a84866136cf565b90508a81111561328757613287613898565b888110156132d75760405162461bcd60e51b815260206004820152601d60248201527f526f757465723a20494e53554646494349454e545f415f414d4f554e5400000060448201526064016105cd565b95508894505b505b50505097509795505050505050565b60005b825181101561306b5760008084838151811061330f5761330f614235565b60200260200101516000015185848151811061332d5761332d614235565b6020026020010151602001519150915060006133498383610ff6565b509050600061339f87868151811061336357613363614235565b60200260200101516000015188878151811061338157613381614235565b60200260200101516020015189888151811061098d5761098d614235565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156133e5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134099190614418565b50915091506000866001600160a01b0316896001600160a01b03161461342f5781613431565b825b6040516370a0823160e01b81526001600160a01b03888116600483015291925082918b16906370a0823190602401602060405180830381865afa15801561347c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134a091906143be565b6134aa9190614261565b6040516378a051ad60e11b8152600481018290526001600160a01b038b811660248301529196509087169063f140a35a90604401602060405180830381865afa1580156134fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061351f91906143be565b9350505050600080856001600160a01b0316886001600160a01b0316146135485782600061354c565b6000835b91509150600060018c516135609190614261565b8a1061356c578a6135cf565b6135cf8c61357b8c6001614446565b8151811061358b5761358b614235565b6020026020010151600001518d8c60016135a59190614446565b815181106135b5576135b5614235565b6020026020010151602001518e8d6001612e929190614446565b6040805160008152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f9061361190869086908690602481016144bf565b600060405180830381600087803b15801561362b57600080fd5b505af115801561363f573d6000803e3d6000fd5b5050505050505050505050505080806136579061445e565b9150506132f1565b600060038211156136c057508060006136796002836143f6565b613684906001614446565b90505b818110156136ba5790508060028161369f81866143f6565b6136a99190614446565b6136b391906143f6565b9050613687565b50919050565b81156136ca575060015b919050565b60008084116137205760405162461bcd60e51b815260206004820152601b60248201527f526f757465723a20494e53554646494349454e545f414d4f554e54000000000060448201526064016105cd565b6000831180156137305750600082115b61377c5760405162461bcd60e51b815260206004820152601e60248201527f526f757465723a20494e53554646494349454e545f4c4951554944495459000060448201526064016105cd565b8261378783866143d7565b610fee91906143f6565b60008183106137a057816137a2565b825b9392505050565b6000836001600160a01b03163b116137c057600080fd5b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b179052915160009283929087169161381c91906144a3565b6000604051808303816000865af19150503d8060008114613859576040519150601f19603f3d011682016040523d82523d6000602084013e61385e565b606091505b509150915081801561388857508051158061388857508080602001905181019061388891906141f4565b61389157600080fd5b5050505050565b634e487b7160e01b600052600160045260246000fd5b6001600160a01b03811681146138c357600080fd5b50565b80356136ca816138ae565b80151581146138c357600080fd5b600080600080600080600080610100898b0312156138fc57600080fd5b8835613907816138ae565b97506020890135613917816138ae565b96506040890135613927816138d1565b9550606089013594506080890135935060a0890135925060c089013561394c816138ae565b8092505060e089013590509295985092959890939650565b600080600080600080600060e0888a03121561397f57600080fd5b87359650602088013595506040880135613998816138ae565b945060608801356139a8816138ae565b935060808801356139b8816138d1565b925060a08801356139c8816138ae565b8092505060c0880135905092959891949750929550565b6020808252825182820181905260009190848201906040850190845b81811015613a17578351835292840192918401916001016139fb565b50909695505050505050565b60008083601f840112613a3557600080fd5b50813567ffffffffffffffff811115613a4d57600080fd5b6020830191508360206060830285010111156110cf57600080fd5b60008060008060008060a08789031215613a8157600080fd5b8635955060208701359450604087013567ffffffffffffffff811115613aa657600080fd5b613ab289828a01613a23565b9095509350506060870135613ac6816138ae565b80925050608087013590509295509295509295565b60008083601f840112613aed57600080fd5b50813567ffffffffffffffff811115613b0557600080fd5b6020830191508360208285010111156110cf57600080fd5b6000806000806000806000806000806101208b8d031215613b3d57600080fd5b8a35613b48816138ae565b995060208b0135613b58816138d1565b985060408b0135975060608b0135965060808b0135955060a08b0135613b7d816138ae565b945060c08b0135935060e08b0135613b94816138d1565b92506101008b013567ffffffffffffffff811115613bb157600080fd5b613bbd8d828e01613adb565b915080935050809150509295989b9194979a5092959850565b60008060008060808587031215613bec57600080fd5b8435613bf7816138ae565b93506020850135613c07816138ae565b92506040850135613c17816138d1565b9396929550929360600135925050565b600080600060608486031215613c3c57600080fd5b8335613c47816138ae565b92506020840135613c57816138ae565b91506040840135613c67816138d1565b809150509250925092565b60008060408385031215613c8557600080fd5b8235613c90816138ae565b91506020830135613ca0816138ae565b809150509250929050565b60008060008060008060008060006101208a8c031215613cca57600080fd5b8935613cd5816138ae565b985060208a0135613ce5816138ae565b975060408a0135613cf5816138d1565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135613d21816138ae565b809250506101008a013590509295985092959850929598565b600080600060608486031215613d4f57600080fd5b833592506020840135613d61816138ae565b91506040840135613c67816138ae565b600080600080600060808688031215613d8957600080fd5b85359450602086013567ffffffffffffffff811115613da757600080fd5b613db388828901613a23565b9095509350506040860135613dc7816138ae565b949793965091946060013592915050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613e1757613e17613dd8565b604052919050565b600067ffffffffffffffff821115613e3957613e39613dd8565b5060051b60200190565b600080600080600060808688031215613e5b57600080fd5b853567ffffffffffffffff80821115613e7357600080fd5b818801915088601f830112613e8757600080fd5b81356020613e9c613e9783613e1f565b613dee565b82815260059290921b8401810191818101908c841115613ebb57600080fd5b948201945b83861015613ed957853582529482019490820190613ec0565b99505089013592505080821115613eef57600080fd5b50613efc88828901613a23565b9095509350613dc79050604087016138c6565b60008060008060008060008060008060006101408c8e031215613f3157600080fd5b8b35613f3c816138ae565b9a5060208c0135613f4c816138ae565b995060408c0135613f5c816138d1565b985060608c0135975060808c0135965060a08c0135955060c08c0135613f81816138ae565b945060e08c013593506101008c0135613f99816138d1565b92506101208c013567ffffffffffffffff811115613fb657600080fd5b613fc28e828f01613adb565b915080935050809150509295989b509295989b9093969950565b600060608284031215613fee57600080fd5b6040516060810181811067ffffffffffffffff8211171561401157614011613dd8565b6040529050808235614022816138ae565b81526020830135614032816138ae565b60208201526040830135614045816138d1565b6040919091015292915050565b6000806040838503121561406557600080fd5b8235915060208084013567ffffffffffffffff81111561408457600080fd5b8401601f8101861361409557600080fd5b80356140a3613e9782613e1f565b818152606091820283018401918482019190898411156140c257600080fd5b938501935b838510156140e8576140d98a86613fdc565b835293840193918501916140c7565b5080955050505050509250929050565b600080600080600060a0868803121561411057600080fd5b853561411b816138ae565b9450602086013561412b816138ae565b9350604086013561413b816138d1565b94979396509394606081013594506080013592915050565b600080600080600080600060e0888a03121561416e57600080fd5b8735614179816138ae565b96506020880135614189816138d1565b955060408801359450606088013593506080880135925060a08801356139c8816138ae565b6000602082840312156141c057600080fd5b81356137a2816138ae565b6020808252600f908201526e149bdd5d195c8e8811561412549151608a1b604082015260600190565b60006020828403121561420657600080fd5b81516137a2816138d1565b6000806040838503121561422457600080fd5b505080516020909101519092909150565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000828210156142735761427361424b565b500390565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f55604082015261139560f21b606082015260800190565b6020808252601490820152730a4deeae8cae47440929cac82989288bea082a8960631b604082015260600190565b6000606082840312156142fa57600080fd5b6137a28383613fdc565b60006020828403121561431657600080fd5b81356137a2816138d1565b6001600160a01b03878116825286166020820152604081018590526060810184905260a06080820181905281018290526000828460c0840137600060c0848401015260c0601f19601f8501168301019050979650505050505050565b6001600160a01b039384168152919092166020820152901515604082015260600190565b6000602082840312156143b357600080fd5b81516137a2816138ae565b6000602082840312156143d057600080fd5b5051919050565b60008160001904831182151516156143f1576143f161424b565b500290565b60008261441357634e487b7160e01b600052601260045260246000fd5b500490565b60008060006060848603121561442d57600080fd5b8351925060208401519150604084015190509250925092565b600082198211156144595761445961424b565b500190565b6000600182016144705761447061424b565b5060010190565b60005b8381101561449257818101518382015260200161447a565b83811115612f9c5750506000910152565b600082516144b5818460208701614477565b9190910192915050565b84815283602082015260018060a01b038316604082015260806060820152600082518060808401526144f88160a0850160208701614477565b601f01601f19169190910160a0019594505050505056fea2646970667358221220e591b2af3ea7fcca7fe871d8fe661c37454dbeaa75d1f2c8a7fdae926359ee4f64736f6c634300080d0033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

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

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