MNT Price: $0.86 (+1.74%)
Gas: 1 Gwei

Contract

0x2C2954cf16f974033e1e2345fCe1cA434dc14497
 

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
Remove Liquidity885938222025-12-09 22:05:5647 days ago1765317956IN
0x2C2954cf...34dc14497
0 MNT0.023300270.0249
Remove Liquidity871227962025-11-05 20:51:4481 days ago1762375904IN
0x2C2954cf...34dc14497
0 MNT0.017432190.0201
Remove Liquidity870341522025-11-03 19:36:5683 days ago1762198616IN
0x2C2954cf...34dc14497
0 MNT0.020052380.02412
Remove Liquidity870341162025-11-03 19:35:4483 days ago1762198544IN
0x2C2954cf...34dc14497
0 MNT0.035428690.04
Remove Liquidity846554792025-09-09 18:07:50138 days ago1757441270IN
0x2C2954cf...34dc14497
0 MNT0.043074520.04
Remove Liquidity838018432025-08-20 23:53:18158 days ago1755733998IN
0x2C2954cf...34dc14497
0 MNT0.019573770.0202
Remove Liquidity833192912025-08-09 19:48:14169 days ago1754768894IN
0x2C2954cf...34dc14497
0 MNT0.021389460.02
Remove Liquidity814921232025-06-28 12:42:38212 days ago1751114558IN
0x2C2954cf...34dc14497
0 MNT0.023349310.02
Remove Liquidity806594422025-06-09 6:06:36231 days ago1749449196IN
0x2C2954cf...34dc14497
0 MNT0.022499030.02
Remove Liquidity803980682025-06-03 4:54:08237 days ago1748926448IN
0x2C2954cf...34dc14497
0 MNT0.034073470.03
Remove Liquidity763922412025-03-02 11:26:34330 days ago1740914794IN
0x2C2954cf...34dc14497
0 MNT0.019162840.02
Remove Liquidity760960642025-02-23 14:54:00337 days ago1740322440IN
0x2C2954cf...34dc14497
0 MNT0.018290570.02
Remove Liquidity760132582025-02-21 16:53:48339 days ago1740156828IN
0x2C2954cf...34dc14497
0 MNT0.017394240.02
Remove Liquidity751597762025-02-01 22:44:24358 days ago1738449864IN
0x2C2954cf...34dc14497
0 MNT0.030825130.04
Remove Liquidity751597372025-02-01 22:43:06358 days ago1738449786IN
0x2C2954cf...34dc14497
0 MNT0.027091030.04
Remove Liquidity751597142025-02-01 22:42:20358 days ago1738449740IN
0x2C2954cf...34dc14497
0 MNT0.023223210.04
Remove Liquidity751596412025-02-01 22:39:54358 days ago1738449594IN
0x2C2954cf...34dc14497
0 MNT0.016231510.03
Remove Liquidity750590072025-01-30 14:45:26361 days ago1738248326IN
0x2C2954cf...34dc14497
0 MNT0.016216180.02
Swap Exact Token...747491192025-01-23 10:35:50368 days ago1737628550IN
0x2C2954cf...34dc14497
0 MNT0.024493950.03
Remove Liquidity723305932024-11-28 10:58:18424 days ago1732791498IN
0x2C2954cf...34dc14497
0 MNT0.040705890.03
Remove Liquidity716840922024-11-13 11:48:16439 days ago1731498496IN
0x2C2954cf...34dc14497
0 MNT0.027417430.02
Remove Liquidity716840442024-11-13 11:46:40439 days ago1731498400IN
0x2C2954cf...34dc14497
0 MNT0.02976280.02
Remove Liquidity716840062024-11-13 11:45:24439 days ago1731498324IN
0x2C2954cf...34dc14497
0 MNT0.029921960.02
Remove Liquidity716839712024-11-13 11:44:14439 days ago1731498254IN
0x2C2954cf...34dc14497
0 MNT0.031428510.02
Remove Liquidity715628202024-11-10 16:25:52442 days ago1731255952IN
0x2C2954cf...34dc14497
0 MNT0.027505380.02
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
658215762024-06-30 18:51:04574 days ago1719773464
0x2C2954cf...34dc14497
1 MNT
657714142024-06-29 14:59:00576 days ago1719673140
0x2C2954cf...34dc14497
9.24961368 MNT
657714142024-06-29 14:59:00576 days ago1719673140
0x2C2954cf...34dc14497
9.24961368 MNT
657630112024-06-29 10:18:54576 days ago1719656334
0x2C2954cf...34dc14497
5 MNT
657629682024-06-29 10:17:28576 days ago1719656248
0x2C2954cf...34dc14497
5 MNT
657480242024-06-29 1:59:20576 days ago1719626360
0x2C2954cf...34dc14497
13.35282747 MNT
657480242024-06-29 1:59:20576 days ago1719626360
0x2C2954cf...34dc14497
13.35282747 MNT
656633352024-06-27 2:56:22578 days ago1719456982
0x2C2954cf...34dc14497
27 MNT
656483282024-06-26 18:36:08578 days ago1719426968
0x2C2954cf...34dc14497
0.43499019 MNT
656483282024-06-26 18:36:08578 days ago1719426968
0x2C2954cf...34dc14497
0.43499019 MNT
655944882024-06-25 12:41:28580 days ago1719319288
0x2C2954cf...34dc14497
100 MNT
655478772024-06-24 10:47:46581 days ago1719226066
0x2C2954cf...34dc14497
2.45783871 MNT
655478772024-06-24 10:47:46581 days ago1719226066
0x2C2954cf...34dc14497
2.45783871 MNT
645322862024-05-31 22:34:44604 days ago1717194884
0x2C2954cf...34dc14497
9.41984523 MNT
645322862024-05-31 22:34:44604 days ago1717194884
0x2C2954cf...34dc14497
9.41984523 MNT
644732142024-05-30 13:45:40606 days ago1717076740
0x2C2954cf...34dc14497
0.07298304 MNT
644732142024-05-30 13:45:40606 days ago1717076740
0x2C2954cf...34dc14497
0.07298304 MNT
644601322024-05-30 6:29:36606 days ago1717050576
0x2C2954cf...34dc14497
0.00000042 MNT
644601322024-05-30 6:29:36606 days ago1717050576
0x2C2954cf...34dc14497
46.80575757 MNT
644601042024-05-30 6:28:40606 days ago1717050520
0x2C2954cf...34dc14497
48 MNT
644453532024-05-29 22:16:58606 days ago1717021018
0x2C2954cf...34dc14497
50 MNT
644057132024-05-29 0:15:38607 days ago1716941738
0x2C2954cf...34dc14497
4.5 MNT
644055112024-05-29 0:08:54607 days ago1716941334
0x2C2954cf...34dc14497
14.66433521 MNT
644055112024-05-29 0:08:54607 days ago1716941334
0x2C2954cf...34dc14497
14.66433521 MNT
642422712024-05-25 5:27:34611 days ago1716614854
0x2C2954cf...34dc14497
37 MNT
View All Internal Transactions

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CrustRouter01

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 8 : CrustRouter01.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.13;

import "../../lib/Math.sol";
import "../../lib/SafeERC20.sol";
import "../../interface/IERC20.sol";
import "../../interface/IWMNT.sol";
import "../../interface/IPair.sol";
import "../../interface/IFactory.sol";

contract CrustRouter01 {
  using SafeERC20 for IERC20;

  struct Route {
    address from;
    address to;
    bool stable;
  }

  address public immutable factory;
  IWMNT public immutable wmnt;
  uint internal constant MINIMUM_LIQUIDITY = 10 ** 3;
  bytes32 immutable pairCodeHash;

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

  constructor(address _factory, address _wmnt) {
    factory = _factory;
    pairCodeHash = IFactory(_factory).pairCodeHash();
    wmnt = IWMNT(_wmnt);
  }

  receive() external payable {
    // only accept MNT via fallback from the WMNT contract
    require(msg.sender == address(wmnt), "CrustRouter: NOT_WMNT");
  }

  function sortTokens(address tokenA, address tokenB) external pure returns (address token0, address token1) {
    return _sortTokens(tokenA, tokenB);
  }

  function _sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
    require(tokenA != tokenB, 'CrustRouter: IDENTICAL_ADDRESSES');
    (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    require(token0 != address(0), 'CrustRouter: ZERO_ADDRESS');
  }

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

  /// @dev Calculates the CREATE2 address for a pair without making any external calls.
  function _pairFor(address tokenA, address tokenB, bool stable) internal view returns (address pair) {
    (address token0, address token1) = _sortTokens(tokenA, tokenB);
    pair = address(uint160(uint(keccak256(abi.encodePacked(
        hex'ff',
        factory,
        keccak256(abi.encodePacked(token0, token1, stable)),
        pairCodeHash // init code hash
      )))));
  }

  function quoteLiquidity(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB) {
    return _quoteLiquidity(amountA, reserveA, reserveB);
  }

  /// @dev 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, 'CrustRouter: INSUFFICIENT_AMOUNT');
    require(reserveA > 0 && reserveB > 0, 'CrustRouter: INSUFFICIENT_LIQUIDITY');
    amountB = amountA * reserveB / reserveA;
  }

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

  /// @dev Fetches and sorts the reserves for a pair.
  function _getReserves(address tokenA, address tokenB, bool stable) internal 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);
  }

  /// @dev 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 (IFactory(factory).isPair(pair)) {
      amountStable = IPair(pair).getAmountOut(amountIn, tokenIn);
    }
    pair = _pairFor(tokenIn, tokenOut, false);
    if (IFactory(factory).isPair(pair)) {
      amountVolatile = IPair(pair).getAmountOut(amountIn, tokenIn);
    }
    return amountStable > amountVolatile ? (amountStable, true) : (amountVolatile, false);
  }

  function getExactAmountOut(uint amountIn, address tokenIn, address tokenOut, bool stable) external view returns (uint) {
    address pair = _pairFor(tokenIn, tokenOut, stable);
    if (IFactory(factory).isPair(pair)) {
      return IPair(pair).getAmountOut(amountIn, tokenIn);
    }
    return 0;
  }

  /// @dev Performs chained getAmountOut calculations on any number of pairs.
  function getAmountsOut(uint amountIn, Route[] memory routes) external view returns (uint[] memory amounts) {
    return _getAmountsOut(amountIn, routes);
  }

  function _getAmountsOut(uint amountIn, Route[] memory routes) internal view returns (uint[] memory amounts) {
    require(routes.length >= 1, 'CrustRouter: 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 (IFactory(factory).isPair(pair)) {
        amounts[i + 1] = IPair(pair).getAmountOut(amounts[i], routes[i].from);
      }
    }
  }

  function isPair(address pair) external view returns (bool) {
    return IFactory(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 = IFactory(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 = IFactory(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();
    // using balances ensures pro-rata distribution
    amountA = liquidity * reserveA / _totalSupply;
    // using balances ensures pro-rata distribution
    amountB = liquidity * reserveB / _totalSupply;

  }

  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, "CrustRouter: DESIRED_A_AMOUNT");
    require(amountBDesired >= amountBMin, "CrustRouter: DESIRED_B_AMOUNT");
    // create the pair if it doesn't exist yet
    address _pair = IFactory(factory).getPair(tokenA, tokenB, stable);
    if (_pair == address(0)) {
      _pair = IFactory(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, 'CrustRouter: INSUFFICIENT_B_AMOUNT');
        (amountA, amountB) = (amountADesired, amountBOptimal);
      } else {
        uint amountAOptimal = _quoteLiquidity(amountBDesired, reserveB, reserveA);
        assert(amountAOptimal <= amountADesired);
        require(amountAOptimal >= amountAMin, 'CrustRouter: 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);
    SafeERC20.safeTransferFrom(IERC20(tokenA), msg.sender, pair, amountA);
    SafeERC20.safeTransferFrom(IERC20(tokenB), msg.sender, pair, amountB);
    liquidity = IPair(pair).mint(to);
  }

  function addLiquidityMNT(
    address token,
    bool stable,
    uint amountTokenDesired,
    uint amountTokenMin,
    uint amountMNTMin,
    address to,
    uint deadline
  ) external payable ensure(deadline) returns (uint amountToken, uint amountMNT, uint liquidity) {
    (amountToken, amountMNT) = _addLiquidity(
      token,
      address(wmnt),
      stable,
      amountTokenDesired,
      msg.value,
      amountTokenMin,
      amountMNTMin
    );
    address pair = _pairFor(token, address(wmnt), stable);
    IERC20(token).safeTransferFrom(msg.sender, pair, amountToken);
    wmnt.deposit{value : amountMNT}();
    assert(wmnt.transfer(pair, amountMNT));
    liquidity = IPair(pair).mint(to);
    // refund dust mnt, if any
    if (msg.value > amountMNT) _safeTransferMNT(msg.sender, msg.value - amountMNT);
  }

  // **** REMOVE 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) {
    return _removeLiquidity(
      tokenA,
      tokenB,
      stable,
      liquidity,
      amountAMin,
      amountBMin,
      to,
      deadline
    );
  }

  function _removeLiquidity(
    address tokenA,
    address tokenB,
    bool stable,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  ) internal ensure(deadline) returns (uint amountA, uint amountB) {
    address pair = _pairFor(tokenA, tokenB, stable);
    IERC20(pair).safeTransferFrom(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, 'CrustRouter: INSUFFICIENT_A_AMOUNT');
    require(amountB >= amountBMin, 'CrustRouter: INSUFFICIENT_B_AMOUNT');
  }

  function removeLiquidityMNT(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountMNTMin,
    address to,
    uint deadline
  ) external returns (uint amountToken, uint amountMNT) {
    return _removeLiquidityMNT(
      token,
      stable,
      liquidity,
      amountTokenMin,
      amountMNTMin,
      to,
      deadline
    );
  }

  function _removeLiquidityMNT(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountMNTMin,
    address to,
    uint deadline
  ) internal ensure(deadline) returns (uint amountToken, uint amountMNT) {
    (amountToken, amountMNT) = _removeLiquidity(
      token,
      address(wmnt),
      stable,
      liquidity,
      amountTokenMin,
      amountMNTMin,
      address(this),
      deadline
    );
    IERC20(token).safeTransfer(to, amountToken);
    wmnt.withdraw(amountMNT);
    _safeTransferMNT(to, amountMNT);
  }

  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
  ) 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);
    }

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

  function removeLiquidityMNTWithPermit(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountMNTMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external returns (uint amountToken, uint amountMNT) {
    address pair = _pairFor(token, address(wmnt), stable);
    uint value = approveMax ? type(uint).max : liquidity;
    IPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
    (amountToken, amountMNT) = _removeLiquidityMNT(token, stable, liquidity, amountTokenMin, amountMNTMin, to, deadline);
  }

  function removeLiquidityMNTSupportingFeeOnTransferTokens(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountMNTMin,
    address to,
    uint deadline
  ) external returns (uint amountToken, uint amountFTM) {
    return _removeLiquidityMNTSupportingFeeOnTransferTokens(
      token,
      stable,
      liquidity,
      amountTokenMin,
      amountMNTMin,
      to,
      deadline
    );
  }

  function _removeLiquidityMNTSupportingFeeOnTransferTokens(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountMNTMin,
    address to,
    uint deadline
  ) internal ensure(deadline) returns (uint amountToken, uint amountFTM) {
    (amountToken, amountFTM) = _removeLiquidity(
      token,
      address(wmnt),
      stable,
      liquidity,
      amountTokenMin,
      amountMNTMin,
      address(this),
      deadline
    );
    IERC20(token).safeTransfer(to, IERC20(token).balanceOf(address(this)));
    wmnt.withdraw(amountFTM);
    _safeTransferMNT(to, amountFTM);
  }

  function removeLiquidityMNTWithPermitSupportingFeeOnTransferTokens(
    address token,
    bool stable,
    uint liquidity,
    uint amountTokenMin,
    uint amountMNTMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external returns (uint amountToken, uint amountFTM) {
    address pair = _pairFor(token, address(wmnt), stable);
    uint value = approveMax ? type(uint).max : liquidity;
    IPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
    (amountToken, amountFTM) = _removeLiquidityMNTSupportingFeeOnTransferTokens(
      token, stable, liquidity, amountTokenMin, amountMNTMin, 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 _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 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, 'CrustRouter: INSUFFICIENT_OUTPUT_AMOUNT');
    IERC20(routes[0].from).safeTransferFrom(
      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, 'CrustRouter: INSUFFICIENT_OUTPUT_AMOUNT');
    IERC20(routes[0].from).safeTransferFrom(
      msg.sender, _pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]
    );
    _swap(amounts, routes, to);
  }

  function swapExactMNTForTokens(uint amountOutMin, Route[] calldata routes, address to, uint deadline)
  external
  payable
  ensure(deadline)
  returns (uint[] memory amounts)
  {
    require(routes[0].from == address(wmnt), 'CrustRouter: INVALID_PATH');
    amounts = _getAmountsOut(msg.value, routes);
    require(amounts[amounts.length - 1] >= amountOutMin, 'CrustRouter: INSUFFICIENT_OUTPUT_AMOUNT');
    wmnt.deposit{value : amounts[0]}();
    assert(wmnt.transfer(_pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]));
    _swap(amounts, routes, to);
  }

  function swapExactTokensForMNT(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(wmnt), 'CrustRouter: INVALID_PATH');
    amounts = _getAmountsOut(amountIn, routes);
    require(amounts[amounts.length - 1] >= amountOutMin, 'CrustRouter: INSUFFICIENT_OUTPUT_AMOUNT');
    IERC20(routes[0].from).safeTransferFrom(
      msg.sender, _pairFor(routes[0].from, routes[0].to, routes[0].stable), amounts[0]
    );
    _swap(amounts, routes, address(this));
    wmnt.withdraw(amounts[amounts.length - 1]);
    _safeTransferMNT(to, amounts[amounts.length - 1]);
  }

  function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    Route[] calldata routes,
    address to,
    uint deadline
  ) external ensure(deadline) {
    IERC20(routes[0].from).safeTransferFrom(
      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,
      'CrustRouter: INSUFFICIENT_OUTPUT_AMOUNT'
    );
  }

  function swapExactMNTForTokensSupportingFeeOnTransferTokens(
    uint amountOutMin,
    Route[] calldata routes,
    address to,
    uint deadline
  )
  external
  payable
  ensure(deadline)
  {
    require(routes[0].from == address(wmnt), 'CrustRouter: INVALID_PATH');
    uint amountIn = msg.value;
    wmnt.deposit{value : amountIn}();
    assert(wmnt.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,
      'CrustRouter: INSUFFICIENT_OUTPUT_AMOUNT'
    );
  }

  function swapExactTokensForMNTSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    Route[] calldata routes,
    address to,
    uint deadline
  )
  external
  ensure(deadline)
  {
    require(routes[routes.length - 1].to == address(wmnt), 'CrustRouter: INVALID_PATH');
    IERC20(routes[0].from).safeTransferFrom(
      msg.sender, _pairFor(routes[0].from, routes[0].to, routes[0].stable), amountIn
    );
    _swapSupportingFeeOnTransferTokens(routes, address(this));
    uint amountOut = IERC20(address(wmnt)).balanceOf(address(this));
    require(amountOut >= amountOutMin, 'CrustRouter: INSUFFICIENT_OUTPUT_AMOUNT');
    wmnt.withdraw(amountOut);
    _safeTransferMNT(to, amountOut);
  }

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

  function _safeTransferMNT(address to, uint value) internal {
    (bool success,) = to.call{value : value}(new bytes(0));
    require(success, 'CrustRouter: MNT_TRANSFER_FAILED');
  }
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.13;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {

  function decimals() external view returns (uint8);

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

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

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

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

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

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

  /**
   * @dev Emitted when `value` tokens are moved from one account (`from`) to
   * another (`to`).
   *
   * Note that `value` may be zero.
   */
  event Transfer(address indexed from, address indexed to, uint256 value);

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.13;

interface IFactory {
  function treasury() external view returns (address);

  function treasuryFee() external view returns (uint);

  function nftStakersFee() external view returns (uint);

  function admin() external view returns (address);

  function nftStakingContract() external view returns (address);

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

  function getInitializable() external view returns (address, address, bool);

  function isPaused() external view returns (bool);

  function getFees(bool _stable) external view returns (uint);

  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 IPair {

  // Structure to capture time period obervations every 30 minutes, used for local oracles
  struct Observation {
    uint timestamp;
    uint reserve0Cumulative;
    uint reserve1Cumulative;
  }

  function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) 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 (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast);

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

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

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

  function token0() external view returns (address);

  function token1() external view returns (address);

  function stable() external view returns (bool);

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

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.13;

interface IWMNT {
  function name() external view returns (string memory);

  function approve(address guy, uint256 wad) external returns (bool);

  function totalSupply() external view returns (uint256);

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

  function withdraw(uint256 wad) external;

  function decimals() external view returns (uint8);

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

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

  function transfer(address dst, uint256 wad) external returns (bool);

  function deposit() external payable;

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

}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.13;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
  /**
   * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
  function isContract(address account) internal view returns (bool) {
    // This method relies on extcodesize/address.code.length, which returns 0
    // for contracts in construction, since the code is only stored at the end
    // of the constructor execution.

    return account.code.length > 0;
  }

  function functionCall(
    address target,
    bytes memory data,
    string memory errorMessage
  ) internal returns (bytes memory) {
    require(isContract(target), "Address: call to non-contract");
    (bool success, bytes memory returndata) = target.call(data);
    return verifyCallResult(success, returndata, errorMessage);
  }

  /**
   * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
  function verifyCallResult(
    bool success,
    bytes memory returndata,
    string memory errorMessage
  ) internal pure returns (bytes memory) {
    if (success) {
      return returndata;
    } else {
      // Look for revert reason and bubble it up if present
      if (returndata.length > 0) {
        // The easiest way to bubble the revert reason is using memory via assembly
        assembly {
          let returndata_size := mload(returndata)
          revert(add(32, returndata), returndata_size)
        }
      } else {
        revert(errorMessage);
      }
    }
  }
}

// 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 positiveInt128(int128 value) internal pure returns (int128) {
    return value < 0 ? int128(0) : value;
  }

  function closeTo(uint a, uint b, uint target) internal pure returns (bool) {
    if (a > b) {
      if (a - b <= target) {
        return true;
      }
    } else {
      if (b - a <= target) {
        return true;
      }
    }
    return false;
  }

  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;
    }
  }

}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.13;

import "../interface/IERC20.sol";
import "./Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
  using Address for address;

  function safeTransfer(
    IERC20 token,
    address to,
    uint value
  ) internal {
    _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
  }

  function safeTransferFrom(
    IERC20 token,
    address from,
    address to,
    uint value
  ) internal {
    _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
  }

  function safeIncreaseAllowance(
    IERC20 token,
    address spender,
    uint value
  ) internal {
    uint newAllowance = token.allowance(address(this), spender) + value;
    _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
  }

  /**
   * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
  function _callOptionalReturn(IERC20 token, bytes memory data) private {
    // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
    // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
    // the target address contains contract code and also asserts for success in the low-level call.

    bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
    if (returndata.length > 0) {
      // Return data is optional
      require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
    }
  }

}

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":"_wmnt","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 CrustRouter01.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":"amountMNTMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityMNT","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountMNT","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 CrustRouter01.Route[]","name":"routes","type":"tuple[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"name":"getExactAmountOut","outputs":[{"internalType":"uint256","name":"","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":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quoteLiquidity","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","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":"amountMNTMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityMNT","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountMNT","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":"amountMNTMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityMNTSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountFTM","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":"amountMNTMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityMNTWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountMNT","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":"amountMNTMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityMNTWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountFTM","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"}],"name":"sortTokens","outputs":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct CrustRouter01.Route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactMNTForTokens","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 CrustRouter01.Route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactMNTForTokensSupportingFeeOnTransferTokens","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 CrustRouter01.Route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForMNT","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 CrustRouter01.Route[]","name":"routes","type":"tuple[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForMNTSupportingFeeOnTransferTokens","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 CrustRouter01.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 CrustRouter01.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":"wmnt","outputs":[{"internalType":"contract IWMNT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e06040523480156200001157600080fd5b5060405162004bb838038062004bb88339810160408190526200003491620000d8565b6001600160a01b038216608081905260408051631355724960e31b81529051639aab9248916004808201926020929091908290030181865afa1580156200007f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000a5919062000110565b60c0526001600160a01b031660a052506200012a565b80516001600160a01b0381168114620000d357600080fd5b919050565b60008060408385031215620000ec57600080fd5b620000f783620000bb565b91506200010760208401620000bb565b90509250929050565b6000602082840312156200012357600080fd5b5051919050565b60805160a05160c05161498562000233600039600061270d0152600081816101cb015281816103030152818161067501528181610793015281816107c9015281816108070152818161089c015281816110e2015281816111ff0152818161128d01528181611466015281816114e40152818161155801528181611b3201528181611c3a01528181611ce501528181611d5e01528181611e3f01528181611fdf015281816127bd0152818161288101526138420152600081816105f801528181610bdf01528181610e8701528181610f9b015281816120d2015281816123c2015281816124ef015281816126d201528181612afe01528181612b9f0152612f2e01526149856000f3fe6080604052600436106101bb5760003560e01c80637301e3c8116100ec578063a32b1fcd1161008a578063c0fd6dfc11610064578063c0fd6dfc146105c6578063c45a0155146105e6578063e5e31b131461061a578063f41766d81461064a57600080fd5b8063a32b1fcd14610558578063ae56886814610578578063b6710cb9146105a657600080fd5b80638d953649116100c65780638d953649146104d857806397a680b4146104f85780639881fcb41461051857806398a0fb3c1461053857600080fd5b80637301e3c8146104785780637367ba9f14610498578063778a787c146104b857600080fd5b8063544caa56116101595780635e60dab5116101335780635e60dab51461041257806362a698e4146104325780636420a18c146104455780636cc1ae131461045857600080fd5b8063544caa561461037d5780635a47ddc3146103bd5780635e1e6325146103dd57600080fd5b806313dcfc591161019557806313dcfc59146102c457806321e232e2146102f15780634386e63c1461033d5780634c1ee03e1461035d57600080fd5b8063086830ac1461023c5780630dede6c41461027657806310bdb5bc1461029657600080fd5b3661023757336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102355760405162461bcd60e51b815260206004820152601560248201527410dc9d5cdd149bdd5d195c8e881393d517d5d35395605a1b60448201526064015b60405180910390fd5b005b600080fd5b34801561024857600080fd5b5061025c610257366004613c26565b61066a565b604080519283526020830191909152015b60405180910390f35b34801561028257600080fd5b5061025c610291366004613cd0565b610743565b6102a96102a4366004613d55565b610767565b6040805193845260208401929092529082015260600161026d565b3480156102d057600080fd5b506102e46102df366004613dc7565b6109b1565b60405161026d9190613e2b565b3480156102fd57600080fd5b506103257f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161026d565b34801561034957600080fd5b5061025c610358366004613e6f565b610bd8565b34801561036957600080fd5b50610325610378366004613ec0565b610d3f565b34801561038957600080fd5b5061039d610398366004613f0b565b610d56565b604080516001600160a01b0393841681529290911660208301520161026d565b3480156103c957600080fd5b506102a96103d8366004613f44565b610d6f565b3480156103e957600080fd5b506103fd6103f8366004613fd3565b610e4f565b6040805192835290151560208301520161026d565b34801561041e57600080fd5b5061025c61042d366004613ec0565b6110a3565b6102e461044036600461404f565b6110bd565b61023561045336600461404f565b611443565b34801561046457600080fd5b506102356104733660046140b6565b6117ed565b34801561048457600080fd5b506102e4610493366004614194565b611a1d565b3480156104a457600080fd5b5061025c6104b3366004613d55565b611ae5565b3480156104c457600080fd5b506102356104d33660046140b6565b611b07565b3480156104e457600080fd5b5061025c6104f3366004613c26565b611d53565b34801561050457600080fd5b506102e46105133660046140b6565b611e12565b34801561052457600080fd5b506102e46105333660046142d6565b6120be565b34801561054457600080fd5b506102a961055336600461437c565b6120ca565b34801561056457600080fd5b5061025c6105733660046143d7565b6122ca565b34801561058457600080fd5b50610598610593366004614493565b612385565b60405190815260200161026d565b3480156105b257600080fd5b506105986105c13660046144bf565b612392565b3480156105d257600080fd5b5061025c6105e1366004613d55565b6124bb565b3480156105f257600080fd5b506103257f000000000000000000000000000000000000000000000000000000000000000081565b34801561062657600080fd5b5061063a610635366004614512565b6124cd565b604051901515815260200161026d565b34801561065657600080fd5b506102e46106653660046140b6565b612562565b600080600061069a8e7f00000000000000000000000000000000000000000000000000000000000000008f61268b565b90506000876106a9578c6106ad565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf906106e8903390309086908f908e908e908e9060040161452f565b600060405180830381600087803b15801561070257600080fd5b505af1158015610716573d6000803e3d6000fd5b505050506107298f8f8f8f8f8f8f612793565b809450819550505050509b509b9950505050505050505050565b6000806107568a8a8a8a8a8a8a8a6128fc565b915091509850989650505050505050565b6000806000834281101561078d5760405162461bcd60e51b815260040161022c90614570565b6107bc8b7f00000000000000000000000000000000000000000000000000000000000000008c8c348d8d612a41565b909450925060006107ee8c7f00000000000000000000000000000000000000000000000000000000000000008d61268b565b90506108056001600160a01b038d16338388612ce5565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b15801561086057600080fd5b505af1158015610874573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b038581166004830152602482018990527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af11580156108e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090d919061459e565b610919576109196145bb565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af1158015610961573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098591906145d1565b9250833411156109a2576109a23361099d8634614600565b612d56565b50509750975097945050505050565b606081428110156109d45760405162461bcd60e51b815260040161022c90614570565b604080516001808252818301909252600091816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816109eb5790505090508781600081518110610a2e57610a2e614617565b6020026020010151600001906001600160a01b031690816001600160a01b0316815250508681600081518110610a6657610a66614617565b6020026020010151602001906001600160a01b031690816001600160a01b0316815250508581600081518110610a9e57610a9e614617565b6020908102919091010151901515604090910152610abc8a82612e18565b9250888360018551610ace9190614600565b81518110610ade57610ade614617565b60200260200101511015610b045760405162461bcd60e51b815260040161022c9061462d565b610bc033610b6d83600081518110610b1e57610b1e614617565b60200260200101516000015184600081518110610b3d57610b3d614617565b60200260200101516020015185600081518110610b5c57610b5c614617565b60200260200101516040015161268b565b85600081518110610b8057610b80614617565b602002602001015184600081518110610b9b57610b9b614617565b6020026020010151600001516001600160a01b0316612ce5909392919063ffffffff16565b610bcb83828761309a565b5050979650505050505050565b60008060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308888886040518463ffffffff1660e01b8152600401610c2d93929190614674565b602060405180830381865afa158015610c4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6e9190614698565b90506001600160a01b038116610c8b576000809250925050610d36565b600080610c998989896132e9565b915091506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0191906145d1565b905080610d0e84896146b5565b610d1891906146d4565b955080610d2583896146b5565b610d2f91906146d4565b9450505050505b94509492505050565b6000610d4c84848461268b565b90505b9392505050565b600080610d6384846133b3565b915091505b9250929050565b60008060008342811015610d955760405162461bcd60e51b815260040161022c90614570565b610da48d8d8d8d8d8d8d612a41565b90945092506000610db68e8e8e61268b565b9050610dc48e338388612ce5565b610dd08d338387612ce5565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af1158015610e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3c91906145d1565b9250505099509950999650505050505050565b6000806000610e608585600161268b565b60405163e5e31b1360e01b81526001600160a01b03828116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015610ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef4919061459e565b15610f6d576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa158015610f46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6a91906145d1565b91505b610f798787600061268b565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529194507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015610fe4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611008919061459e565b15611081576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e91906145d1565b90505b80821161109057806000611094565b8160015b94509450505050935093915050565b6000806110b18585856132e9565b91509150935093915050565b606081428110156110e05760405162461bcd60e51b815260040161022c90614570565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168686600081811061111d5761111d614617565b6111339260206060909202019081019150614512565b6001600160a01b0316146111595760405162461bcd60e51b815260040161022c906146f6565b6111b5348787808060200260200160405190810160405280939291908181526020016000905b828210156111ab5761119c6060830286013681900381019061472d565b8152602001906001019061117f565b5050505050612e18565b91508682600184516111c79190614600565b815181106111d7576111d7614617565b602002602001015110156111fd5760405162461bcd60e51b815260040161022c9061462d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061123f5761123f614617565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561127257600080fd5b505af1158015611286573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb611341888860008181106112d0576112d0614617565b6112e69260206060909202019081019150614512565b898960008181106112f9576112f9614617565b90506060020160200160208101906113119190614512565b8a8a600081811061132457611324614617565b905060600201604001602081019061133c9190614749565b61268b565b8460008151811061135457611354614617565b60200260200101516040518363ffffffff1660e01b815260040161138d9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af11580156113ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d0919061459e565b6113dc576113dc6145bb565b611439828787808060200260200160405190810160405280939291908181526020016000905b8282101561142e5761141f6060830286013681900381019061472d565b81526020019060010190611402565b50505050508661309a565b5095945050505050565b80428110156114645760405162461bcd60e51b815260040161022c90614570565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316858560008181106114a1576114a1614617565b6114b79260206060909202019081019150614512565b6001600160a01b0316146114dd5760405162461bcd60e51b815260040161022c906146f6565b60003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561153d57600080fd5b505af1158015611551573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb61159b888860008181106112d0576112d0614617565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af11580156115e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160c919061459e565b611618576116186145bb565b60008686611627600182614600565b81811061163657611636614617565b905060600201602001602081019061164e9190614512565b6040516370a0823160e01b81526001600160a01b03878116600483015291909116906370a0823190602401602060405180830381865afa158015611696573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ba91906145d1565b90506117188787808060200260200160405190810160405280939291908181526020016000905b8282101561170d576116fe6060830286013681900381019061472d565b815260200190600101906116e1565b505050505086613495565b87818888611727600182614600565b81811061173657611736614617565b905060600201602001602081019061174e9190614512565b6040516370a0823160e01b81526001600160a01b03898116600483015291909116906370a08231906024015b602060405180830381865afa158015611797573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117bb91906145d1565b6117c59190614600565b10156117e35760405162461bcd60e51b815260040161022c9061462d565b5050505050505050565b804281101561180e5760405162461bcd60e51b815260040161022c90614570565b6118b73361187c8787600081811061182857611828614617565b61183e9260206060909202019081019150614512565b8888600081811061185157611851614617565b90506060020160200160208101906118699190614512565b8989600081811061132457611324614617565b898888600081811061189057611890614617565b6118a69260206060909202019081019150614512565b6001600160a01b0316929190612ce5565b600085856118c6600182614600565b8181106118d5576118d5614617565b90506060020160200160208101906118ed9190614512565b6040516370a0823160e01b81526001600160a01b03868116600483015291909116906370a0823190602401602060405180830381865afa158015611935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195991906145d1565b90506119b78686808060200260200160405190810160405280939291908181526020016000905b828210156119ac5761199d6060830286013681900381019061472d565b81526020019060010190611980565b505050505085613495565b868187876119c6600182614600565b8181106119d5576119d5614617565b90506060020160200160208101906119ed9190614512565b6040516370a0823160e01b81526001600160a01b03888116600483015291909116906370a082319060240161177a565b60608142811015611a405760405162461bcd60e51b815260040161022c90614570565b611a8833611a5a888860008181106112d0576112d0614617565b89600081518110611a6d57611a6d614617565b60200260200101518989600081811061189057611890614617565b611ada878787808060200260200160405190810160405280939291908181526020016000905b8282101561142e57611acb6060830286013681900381019061472d565b81526020019060010190611aae565b509495945050505050565b600080611af789898989898989613818565b9150915097509795505050505050565b8042811015611b285760405162461bcd60e51b815260040161022c90614570565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168585611b5f600182614600565b818110611b6e57611b6e614617565b9050606002016020016020810190611b869190614512565b6001600160a01b031614611bac5760405162461bcd60e51b815260040161022c906146f6565b611bc63361187c8787600081811061182857611828614617565b611c228585808060200260200160405190810160405280939291908181526020016000905b82821015611c1757611c086060830286013681900381019061472d565b81526020019060010190611beb565b505050505030613495565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611c89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cad91906145d1565b905086811015611ccf5760405162461bcd60e51b815260040161022c9061462d565b604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015611d3157600080fd5b505af1158015611d45573d6000803e3d6000fd5b505050506117e38482612d56565b6000806000611d838e7f00000000000000000000000000000000000000000000000000000000000000008f61268b565b9050600087611d92578c611d96565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90611dd1903390309086908f908e908e908e9060040161452f565b600060405180830381600087803b158015611deb57600080fd5b505af1158015611dff573d6000803e3d6000fd5b505050506107298f8f8f8f8f8f8f613818565b60608142811015611e355760405162461bcd60e51b815260040161022c90614570565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686611e6c600182614600565b818110611e7b57611e7b614617565b9050606002016020016020810190611e939190614512565b6001600160a01b031614611eb95760405162461bcd60e51b815260040161022c906146f6565b611f0b888787808060200260200160405190810160405280939291908181526020016000905b828210156111ab57611efc6060830286013681900381019061472d565b81526020019060010190611edf565b9150868260018451611f1d9190614600565b81518110611f2d57611f2d614617565b60200260200101511015611f535760405162461bcd60e51b815260040161022c9061462d565b611f8033611f6d888860008181106112d0576112d0614617565b84600081518110611a6d57611a6d614617565b611fdd828787808060200260200160405190810160405280939291908181526020016000905b82821015611fd257611fc36060830286013681900381019061472d565b81526020019060010190611fa6565b50505050503061309a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836001855161201b9190614600565b8151811061202b5761202b614617565b60200260200101516040518263ffffffff1660e01b815260040161205191815260200190565b600060405180830381600087803b15801561206b57600080fd5b505af115801561207f573d6000803e3d6000fd5b505050506120b38483600185516120969190614600565b815181106120a6576120a6614617565b6020026020010151612d56565b509695505050505050565b6060610d4f8383612e18565b6000806000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636801cc308a8a8a6040518463ffffffff1660e01b815260040161212093929190614674565b602060405180830381865afa15801561213d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121619190614698565b9050600080806001600160a01b038416156121eb57836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d891906145d1565b90506121e58c8c8c6132e9565b90935091505b821580156121f7575081155b15612228578896508795506103e8612217612212888a6146b5565b613885565b6122219190614600565b94506122bb565b60006122358a85856138f5565b905088811161227d5789975095508561227684612252848b6146b5565b61225c91906146d4565b84612267858b6146b5565b61227191906146d4565b6139c3565b95506122b9565b600061228a8a85876138f5565b98508997508890506122b5856122a085846146b5565b6122aa91906146d4565b85612267868c6146b5565b9650505b505b50505050955095509592505050565b60008060006122da8f8f8f61268b565b90506000876122e9578c6122ed565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90612328903390309086908f908e908e908e9060040161452f565b600060405180830381600087803b15801561234257600080fd5b505af1158015612356573d6000803e3d6000fd5b505050505061236b8f8f8f8f8f8f8f8f6128fc565b8093508194505050509c509c9a5050505050505050505050565b6000610d4c8484846138f5565b6000806123a085858561268b565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa15801561240b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242f919061459e565b156124ad576040516378a051ad60e11b8152600481018790526001600160a01b03868116602483015282169063f140a35a90604401602060405180830381865afa158015612481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a591906145d1565b9150506124b3565b60009150505b949350505050565b600080611af789898989898989612793565b60405163e5e31b1360e01b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015612538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061255c919061459e565b92915050565b606081428110156125855760405162461bcd60e51b815260040161022c90614570565b6125d7888787808060200260200160405190810160405280939291908181526020016000905b828210156111ab576125c86060830286013681900381019061472d565b815260200190600101906125ab565b91508682600184516125e99190614600565b815181106125f9576125f9614617565b6020026020010151101561261f5760405162461bcd60e51b815260040161022c9061462d565b61263933611f6d888860008181106112d0576112d0614617565b6120b3828787808060200260200160405190810160405280939291908181526020016000905b8282101561142e5761267c6060830286013681900381019061472d565b8152602001906001019061265f565b600080600061269a86866133b3565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015286151560f81b604882015291935091507f000000000000000000000000000000000000000000000000000000000000000090604901604051602081830303815290604052805190602001207f0000000000000000000000000000000000000000000000000000000000000000604051602001612771939291906001600160f81b0319815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b60408051601f1981840301815291905280516020909101209695505050505050565b60008082428110156127b75760405162461bcd60e51b815260040161022c90614570565b6127e78a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b6128fc565b6040516370a0823160e01b8152306004820152919450925061286b9086906001600160a01b038d16906370a0823190602401602060405180830381865afa158015612836573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285a91906145d1565b6001600160a01b038d1691906139d9565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156128cd57600080fd5b505af11580156128e1573d6000803e3d6000fd5b505050506128ef8583612d56565b5097509795505050505050565b60008082428110156129205760405162461bcd60e51b815260040161022c90614570565b600061292d8c8c8c61268b565b90506129446001600160a01b03821633838c612ce5565b60405163226bf2d160e21b81526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015612990573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b49190614766565b9150915060006129c48f8f6133b3565b509050806001600160a01b03168f6001600160a01b0316146129e75781836129ea565b82825b90975095508a871015612a0f5760405162461bcd60e51b815260040161022c9061478a565b89861015612a2f5760405162461bcd60e51b815260040161022c906147cc565b50505050509850989650505050505050565b60008083861015612a945760405162461bcd60e51b815260206004820152601d60248201527f4372757374526f757465723a20444553495245445f415f414d4f554e54000000604482015260640161022c565b82851015612ae45760405162461bcd60e51b815260206004820152601d60248201527f4372757374526f757465723a20444553495245445f425f414d4f554e54000000604482015260640161022c565b6040516306801cc360e41b81526000906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636801cc3090612b37908d908d908d90600401614674565b602060405180830381865afa158015612b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b789190614698565b90506001600160a01b038116612c1e576040516320b7f73960e21b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906382dfdce490612bd8908d908d908d90600401614674565b6020604051808303816000875af1158015612bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1b9190614698565b90505b600080612c2c8c8c8c6132e9565b91509150816000148015612c3e575080155b15612c4e57889450879350612cd6565b6000612c5b8a84846138f5565b9050888111612c8f5786811015612c845760405162461bcd60e51b815260040161022c906147cc565b899550935083612cd4565b6000612c9c8a84866138f5565b90508a811115612cae57612cae6145bb565b88811015612cce5760405162461bcd60e51b815260040161022c9061478a565b95508894505b505b50505097509795505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052612d509085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613a09565b50505050565b604080516000808252602082019092526001600160a01b038416908390604051612d80919061483a565b60006040518083038185875af1925050503d8060008114612dbd576040519150601f19603f3d011682016040523d82523d6000602084013e612dc2565b606091505b5050905080612e135760405162461bcd60e51b815260206004820181905260248201527f4372757374526f757465723a204d4e545f5452414e534645525f4641494c4544604482015260640161022c565b505050565b6060600182511015612e3c5760405162461bcd60e51b815260040161022c906146f6565b8151612e49906001614856565b67ffffffffffffffff811115612e6157612e61614129565b604051908082528060200260200182016040528015612e8a578160200160208202803683370190505b5090508281600081518110612ea157612ea1614617565b60200260200101818152505060005b8251811015613093576000612f0c848381518110612ed057612ed0614617565b602002602001015160000151858481518110612eee57612eee614617565b602002602001015160200151868581518110610b5c57610b5c614617565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000000000000000000000000000000000000000000009091169063e5e31b1390602401602060405180830381865afa158015612f77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9b919061459e565b1561308057806001600160a01b031663f140a35a848481518110612fc157612fc1614617565b6020026020010151868581518110612fdb57612fdb614617565b6020026020010151600001516040518363ffffffff1660e01b81526004016130169291909182526001600160a01b0316602082015260400190565b602060405180830381865afa158015613033573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061305791906145d1565b83613063846001614856565b8151811061307357613073614617565b6020026020010181815250505b508061308b8161486e565b915050612eb0565b5092915050565b60005b8251811015612d505760006130ec8483815181106130bd576130bd614617565b6020026020010151600001518584815181106130db576130db614617565b6020026020010151602001516133b3565b5090506000856130fd846001614856565b8151811061310d5761310d614617565b60200260200101519050600080836001600160a01b031687868151811061313657613136614617565b6020026020010151600001516001600160a01b0316146131585782600061315c565b6000835b915091506000600188516131709190614600565b861061317c57866131ef565b6131ef8861318b886001614856565b8151811061319b5761319b614617565b602002602001015160000151898860016131b59190614856565b815181106131c5576131c5614617565b6020026020010151602001518a8960016131df9190614856565b81518110610b5c57610b5c614617565b905061324288878151811061320657613206614617565b60200260200101516000015189888151811061322457613224614617565b6020026020010151602001518a8981518110610b5c57610b5c614617565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f19166020018201604052801561327f576020820181803683370190505b506040518563ffffffff1660e01b815260040161329f94939291906148b3565b600060405180830381600087803b1580156132b957600080fd5b505af11580156132cd573d6000803e3d6000fd5b50505050505050505080806132e19061486e565b91505061309d565b60008060006132f886866133b3565b50905060008061330988888861268b565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336a91906148f7565b506001600160701b031691506001600160701b03169150826001600160a01b0316886001600160a01b0316146133a15780826133a4565b81815b90999098509650505050505050565b600080826001600160a01b0316846001600160a01b0316036134175760405162461bcd60e51b815260206004820181905260248201527f4372757374526f757465723a204944454e544943414c5f414444524553534553604482015260640161022c565b826001600160a01b0316846001600160a01b03161061343757828461343a565b83835b90925090506001600160a01b038216610d685760405162461bcd60e51b815260206004820152601960248201527f4372757374526f757465723a205a45524f5f4144445245535300000000000000604482015260640161022c565b60005b8251811015612e13576000808483815181106134b6576134b6614617565b6020026020010151600001518584815181106134d4576134d4614617565b6020026020010151602001519150915060006134f083836133b3565b509050600061354687868151811061350a5761350a614617565b60200260200101516000015188878151811061352857613528614617565b602002602001015160200151898881518110610b5c57610b5c614617565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561358c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135b091906148f7565b506001600160701b031691506001600160701b031691506000866001600160a01b0316896001600160a01b0316146135e857816135ea565b825b6040516370a0823160e01b81526001600160a01b03888116600483015291925082918b16906370a0823190602401602060405180830381865afa158015613635573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061365991906145d1565b6136639190614600565b6040516378a051ad60e11b8152600481018290526001600160a01b038b811660248301529196509087169063f140a35a90604401602060405180830381865afa1580156136b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d891906145d1565b9350505050600080856001600160a01b0316886001600160a01b03161461370157826000613705565b6000835b91509150600060018c516137199190614600565b8a10613725578a613788565b6137888c6137348c6001614856565b8151811061374457613744614617565b6020026020010151600001518d8c600161375e9190614856565b8151811061376e5761376e614617565b6020026020010151602001518e8d60016131df9190614856565b6040805160008152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f906137ca90869086908690602481016148b3565b600060405180830381600087803b1580156137e457600080fd5b505af11580156137f8573d6000803e3d6000fd5b5050505050505050505050505080806138109061486e565b915050613498565b600080824281101561383c5760405162461bcd60e51b815260040161022c90614570565b61386c8a7f00000000000000000000000000000000000000000000000000000000000000008b8b8b8b308b6128fc565b909350915061286b6001600160a01b038b1686856139d9565b600060038211156138e6575080600061389f6002836146d4565b6138aa906001614856565b90505b818110156138e0579050806002816138c581866146d4565b6138cf9190614856565b6138d991906146d4565b90506138ad565b50919050565b81156138f0575060015b919050565b60008084116139465760405162461bcd60e51b815260206004820181905260248201527f4372757374526f757465723a20494e53554646494349454e545f414d4f554e54604482015260640161022c565b6000831180156139565750600082115b6139ae5760405162461bcd60e51b815260206004820152602360248201527f4372757374526f757465723a20494e53554646494349454e545f4c495155494460448201526249545960e81b606482015260840161022c565b826139b983866146b5565b610d4c91906146d4565b60008183106139d25781610d4f565b5090919050565b6040516001600160a01b038316602482015260448101829052612e1390849063a9059cbb60e01b90606401612d19565b6000613a5e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613adb9092919063ffffffff16565b805190915015612e135780806020019051810190613a7c919061459e565b612e135760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161022c565b60606001600160a01b0384163b613b345760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161022c565b600080856001600160a01b031685604051613b4f919061483a565b6000604051808303816000865af19150503d8060008114613b8c576040519150601f19603f3d011682016040523d82523d6000602084013e613b91565b606091505b5091509150613ba1828286613bab565b9695505050505050565b60608315613bba575081610d4f565b825115613bca5782518084602001fd5b8160405162461bcd60e51b815260040161022c919061493c565b6001600160a01b0381168114613bf957600080fd5b50565b80356138f081613be4565b8015158114613bf957600080fd5b803560ff811681146138f057600080fd5b60008060008060008060008060008060006101608c8e031215613c4857600080fd5b8b35613c5381613be4565b9a5060208c0135613c6381613c07565b995060408c0135985060608c0135975060808c0135965060a08c0135613c8881613be4565b955060c08c0135945060e08c0135613c9f81613c07565b9350613cae6101008d01613c15565b92506101208c013591506101408c013590509295989b509295989b9093969950565b600080600080600080600080610100898b031215613ced57600080fd5b8835613cf881613be4565b97506020890135613d0881613be4565b96506040890135613d1881613c07565b9550606089013594506080890135935060a0890135925060c0890135613d3d81613be4565b8092505060e089013590509295985092959890939650565b600080600080600080600060e0888a031215613d7057600080fd5b8735613d7b81613be4565b96506020880135613d8b81613c07565b955060408801359450606088013593506080880135925060a0880135613db081613be4565b8092505060c0880135905092959891949750929550565b600080600080600080600060e0888a031215613de257600080fd5b87359650602088013595506040880135613dfb81613be4565b94506060880135613e0b81613be4565b93506080880135613e1b81613c07565b925060a0880135613db081613be4565b6020808252825182820181905260009190848201906040850190845b81811015613e6357835183529284019291840191600101613e47565b50909695505050505050565b60008060008060808587031215613e8557600080fd5b8435613e9081613be4565b93506020850135613ea081613be4565b92506040850135613eb081613c07565b9396929550929360600135925050565b600080600060608486031215613ed557600080fd5b8335613ee081613be4565b92506020840135613ef081613be4565b91506040840135613f0081613c07565b809150509250925092565b60008060408385031215613f1e57600080fd5b8235613f2981613be4565b91506020830135613f3981613be4565b809150509250929050565b60008060008060008060008060006101208a8c031215613f6357600080fd5b8935613f6e81613be4565b985060208a0135613f7e81613be4565b975060408a0135613f8e81613c07565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135613fba81613be4565b809250506101008a013590509295985092959850929598565b600080600060608486031215613fe857600080fd5b833592506020840135613ffa81613be4565b91506040840135613f0081613be4565b60008083601f84011261401c57600080fd5b50813567ffffffffffffffff81111561403457600080fd5b602083019150836020606083028501011115610d6857600080fd5b60008060008060006080868803121561406757600080fd5b85359450602086013567ffffffffffffffff81111561408557600080fd5b6140918882890161400a565b90955093505060408601356140a581613be4565b949793965091946060013592915050565b60008060008060008060a087890312156140cf57600080fd5b8635955060208701359450604087013567ffffffffffffffff8111156140f457600080fd5b61410089828a0161400a565b909550935050606087013561411481613be4565b80925050608087013590509295509295509295565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561416857614168614129565b604052919050565b600067ffffffffffffffff82111561418a5761418a614129565b5060051b60200190565b6000806000806000608086880312156141ac57600080fd5b853567ffffffffffffffff808211156141c457600080fd5b818801915088601f8301126141d857600080fd5b813560206141ed6141e883614170565b61413f565b82815260059290921b8401810191818101908c84111561420c57600080fd5b948201945b8386101561422a57853582529482019490820190614211565b9950508901359250508082111561424057600080fd5b5061424d8882890161400a565b90955093506140a5905060408701613bfc565b60006060828403121561427257600080fd5b6040516060810181811067ffffffffffffffff8211171561429557614295614129565b60405290508082356142a681613be4565b815260208301356142b681613be4565b602082015260408301356142c981613c07565b6040919091015292915050565b600080604083850312156142e957600080fd5b8235915060208084013567ffffffffffffffff81111561430857600080fd5b8401601f8101861361431957600080fd5b80356143276141e882614170565b8181526060918202830184019184820191908984111561434657600080fd5b938501935b8385101561436c5761435d8a86614260565b8352938401939185019161434b565b5080955050505050509250929050565b600080600080600060a0868803121561439457600080fd5b853561439f81613be4565b945060208601356143af81613be4565b935060408601356143bf81613c07565b94979396509394606081013594506080013592915050565b6000806000806000806000806000806000806101808d8f0312156143fa57600080fd5b8c3561440581613be4565b9b5060208d013561441581613be4565b9a5060408d013561442581613c07565b995060608d0135985060808d0135975060a08d0135965060c08d013561444a81613be4565b955060e08d013594506101008d013561446281613c07565b93506144716101208e01613c15565b92506101408d013591506101608d013590509295989b509295989b509295989b565b6000806000606084860312156144a857600080fd5b505081359360208301359350604090920135919050565b600080600080608085870312156144d557600080fd5b8435935060208501356144e781613be4565b925060408501356144f781613be4565b9150606085013561450781613c07565b939692955090935050565b60006020828403121561452457600080fd5b8135610d4f81613be4565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b60208082526014908201527310dc9d5cdd149bdd5d195c8e881156141254915160621b604082015260600190565b6000602082840312156145b057600080fd5b8151610d4f81613c07565b634e487b7160e01b600052600160045260246000fd5b6000602082840312156145e357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015614612576146126145ea565b500390565b634e487b7160e01b600052603260045260246000fd5b60208082526027908201527f4372757374526f757465723a20494e53554646494349454e545f4f555450555460408201526617d05353d5539560ca1b606082015260800190565b6001600160a01b039384168152919092166020820152901515604082015260600190565b6000602082840312156146aa57600080fd5b8151610d4f81613be4565b60008160001904831182151516156146cf576146cf6145ea565b500290565b6000826146f157634e487b7160e01b600052601260045260246000fd5b500490565b60208082526019908201527f4372757374526f757465723a20494e56414c49445f5041544800000000000000604082015260600190565b60006060828403121561473f57600080fd5b610d4f8383614260565b60006020828403121561475b57600080fd5b8135610d4f81613c07565b6000806040838503121561477957600080fd5b505080516020909101519092909150565b60208082526022908201527f4372757374526f757465723a20494e53554646494349454e545f415f414d4f55604082015261139560f21b606082015260800190565b60208082526022908201527f4372757374526f757465723a20494e53554646494349454e545f425f414d4f55604082015261139560f21b606082015260800190565b60005b83811015614829578181015183820152602001614811565b83811115612d505750506000910152565b6000825161484c81846020870161480e565b9190910192915050565b60008219821115614869576148696145ea565b500190565b600060018201614880576148806145ea565b5060010190565b6000815180845261489f81602086016020860161480e565b601f01601f19169290920160200192915050565b84815283602082015260018060a01b0383166040820152608060608201526000613ba16080830184614887565b80516001600160701b03811681146138f057600080fd5b60008060006060848603121561490c57600080fd5b614915846148e0565b9250614923602085016148e0565b9150604084015163ffffffff81168114613f0057600080fd5b602081526000610d4f602083018461488756fea26469706673582212205f0e12f7f2fd810cfe323126860e076daa9514d70b2117ed3b87feeaddc0cab464736f6c634300080d003300000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb8

Deployed Bytecode

0x6080604052600436106101bb5760003560e01c80637301e3c8116100ec578063a32b1fcd1161008a578063c0fd6dfc11610064578063c0fd6dfc146105c6578063c45a0155146105e6578063e5e31b131461061a578063f41766d81461064a57600080fd5b8063a32b1fcd14610558578063ae56886814610578578063b6710cb9146105a657600080fd5b80638d953649116100c65780638d953649146104d857806397a680b4146104f85780639881fcb41461051857806398a0fb3c1461053857600080fd5b80637301e3c8146104785780637367ba9f14610498578063778a787c146104b857600080fd5b8063544caa56116101595780635e60dab5116101335780635e60dab51461041257806362a698e4146104325780636420a18c146104455780636cc1ae131461045857600080fd5b8063544caa561461037d5780635a47ddc3146103bd5780635e1e6325146103dd57600080fd5b806313dcfc591161019557806313dcfc59146102c457806321e232e2146102f15780634386e63c1461033d5780634c1ee03e1461035d57600080fd5b8063086830ac1461023c5780630dede6c41461027657806310bdb5bc1461029657600080fd5b3661023757336001600160a01b037f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb816146102355760405162461bcd60e51b815260206004820152601560248201527410dc9d5cdd149bdd5d195c8e881393d517d5d35395605a1b60448201526064015b60405180910390fd5b005b600080fd5b34801561024857600080fd5b5061025c610257366004613c26565b61066a565b604080519283526020830191909152015b60405180910390f35b34801561028257600080fd5b5061025c610291366004613cd0565b610743565b6102a96102a4366004613d55565b610767565b6040805193845260208401929092529082015260600161026d565b3480156102d057600080fd5b506102e46102df366004613dc7565b6109b1565b60405161026d9190613e2b565b3480156102fd57600080fd5b506103257f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb881565b6040516001600160a01b03909116815260200161026d565b34801561034957600080fd5b5061025c610358366004613e6f565b610bd8565b34801561036957600080fd5b50610325610378366004613ec0565b610d3f565b34801561038957600080fd5b5061039d610398366004613f0b565b610d56565b604080516001600160a01b0393841681529290911660208301520161026d565b3480156103c957600080fd5b506102a96103d8366004613f44565b610d6f565b3480156103e957600080fd5b506103fd6103f8366004613fd3565b610e4f565b6040805192835290151560208301520161026d565b34801561041e57600080fd5b5061025c61042d366004613ec0565b6110a3565b6102e461044036600461404f565b6110bd565b61023561045336600461404f565b611443565b34801561046457600080fd5b506102356104733660046140b6565b6117ed565b34801561048457600080fd5b506102e4610493366004614194565b611a1d565b3480156104a457600080fd5b5061025c6104b3366004613d55565b611ae5565b3480156104c457600080fd5b506102356104d33660046140b6565b611b07565b3480156104e457600080fd5b5061025c6104f3366004613c26565b611d53565b34801561050457600080fd5b506102e46105133660046140b6565b611e12565b34801561052457600080fd5b506102e46105333660046142d6565b6120be565b34801561054457600080fd5b506102a961055336600461437c565b6120ca565b34801561056457600080fd5b5061025c6105733660046143d7565b6122ca565b34801561058457600080fd5b50610598610593366004614493565b612385565b60405190815260200161026d565b3480156105b257600080fd5b506105986105c13660046144bf565b612392565b3480156105d257600080fd5b5061025c6105e1366004613d55565b6124bb565b3480156105f257600080fd5b506103257f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce81565b34801561062657600080fd5b5061063a610635366004614512565b6124cd565b604051901515815260200161026d565b34801561065657600080fd5b506102e46106653660046140b6565b612562565b600080600061069a8e7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88f61268b565b90506000876106a9578c6106ad565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf906106e8903390309086908f908e908e908e9060040161452f565b600060405180830381600087803b15801561070257600080fd5b505af1158015610716573d6000803e3d6000fd5b505050506107298f8f8f8f8f8f8f612793565b809450819550505050509b509b9950505050505050505050565b6000806107568a8a8a8a8a8a8a8a6128fc565b915091509850989650505050505050565b6000806000834281101561078d5760405162461bcd60e51b815260040161022c90614570565b6107bc8b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88c8c348d8d612a41565b909450925060006107ee8c7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88d61268b565b90506108056001600160a01b038d16338388612ce5565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b15801561086057600080fd5b505af1158015610874573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b038581166004830152602482018990527f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb816935063a9059cbb925060440190506020604051808303816000875af11580156108e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090d919061459e565b610919576109196145bb565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af1158015610961573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098591906145d1565b9250833411156109a2576109a23361099d8634614600565b612d56565b50509750975097945050505050565b606081428110156109d45760405162461bcd60e51b815260040161022c90614570565b604080516001808252818301909252600091816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816109eb5790505090508781600081518110610a2e57610a2e614617565b6020026020010151600001906001600160a01b031690816001600160a01b0316815250508681600081518110610a6657610a66614617565b6020026020010151602001906001600160a01b031690816001600160a01b0316815250508581600081518110610a9e57610a9e614617565b6020908102919091010151901515604090910152610abc8a82612e18565b9250888360018551610ace9190614600565b81518110610ade57610ade614617565b60200260200101511015610b045760405162461bcd60e51b815260040161022c9061462d565b610bc033610b6d83600081518110610b1e57610b1e614617565b60200260200101516000015184600081518110610b3d57610b3d614617565b60200260200101516020015185600081518110610b5c57610b5c614617565b60200260200101516040015161268b565b85600081518110610b8057610b80614617565b602002602001015184600081518110610b9b57610b9b614617565b6020026020010151600001516001600160a01b0316612ce5909392919063ffffffff16565b610bcb83828761309a565b5050979650505050505050565b60008060007f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce6001600160a01b0316636801cc308888886040518463ffffffff1660e01b8152600401610c2d93929190614674565b602060405180830381865afa158015610c4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c6e9190614698565b90506001600160a01b038116610c8b576000809250925050610d36565b600080610c998989896132e9565b915091506000836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d0191906145d1565b905080610d0e84896146b5565b610d1891906146d4565b955080610d2583896146b5565b610d2f91906146d4565b9450505050505b94509492505050565b6000610d4c84848461268b565b90505b9392505050565b600080610d6384846133b3565b915091505b9250929050565b60008060008342811015610d955760405162461bcd60e51b815260040161022c90614570565b610da48d8d8d8d8d8d8d612a41565b90945092506000610db68e8e8e61268b565b9050610dc48e338388612ce5565b610dd08d338387612ce5565b6040516335313c2160e11b81526001600160a01b038881166004830152821690636a627842906024016020604051808303816000875af1158015610e18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3c91906145d1565b9250505099509950999650505050505050565b6000806000610e608585600161268b565b60405163e5e31b1360e01b81526001600160a01b03828116600483015291925060009182917f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce9091169063e5e31b1390602401602060405180830381865afa158015610ed0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ef4919061459e565b15610f6d576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa158015610f46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6a91906145d1565b91505b610f798787600061268b565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529194507f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce9091169063e5e31b1390602401602060405180830381865afa158015610fe4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611008919061459e565b15611081576040516378a051ad60e11b8152600481018990526001600160a01b03888116602483015284169063f140a35a90604401602060405180830381865afa15801561105a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107e91906145d1565b90505b80821161109057806000611094565b8160015b94509450505050935093915050565b6000806110b18585856132e9565b91509150935093915050565b606081428110156110e05760405162461bcd60e51b815260040161022c90614570565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b03168686600081811061111d5761111d614617565b6111339260206060909202019081019150614512565b6001600160a01b0316146111595760405162461bcd60e51b815260040161022c906146f6565b6111b5348787808060200260200160405190810160405280939291908181526020016000905b828210156111ab5761119c6060830286013681900381019061472d565b8152602001906001019061117f565b5050505050612e18565b91508682600184516111c79190614600565b815181106111d7576111d7614617565b602002602001015110156111fd5760405162461bcd60e51b815260040161022c9061462d565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663d0e30db08360008151811061123f5761123f614617565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561127257600080fd5b505af1158015611286573d6000803e3d6000fd5b50505050507f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663a9059cbb611341888860008181106112d0576112d0614617565b6112e69260206060909202019081019150614512565b898960008181106112f9576112f9614617565b90506060020160200160208101906113119190614512565b8a8a600081811061132457611324614617565b905060600201604001602081019061133c9190614749565b61268b565b8460008151811061135457611354614617565b60200260200101516040518363ffffffff1660e01b815260040161138d9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af11580156113ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d0919061459e565b6113dc576113dc6145bb565b611439828787808060200260200160405190810160405280939291908181526020016000905b8282101561142e5761141f6060830286013681900381019061472d565b81526020019060010190611402565b50505050508661309a565b5095945050505050565b80428110156114645760405162461bcd60e51b815260040161022c90614570565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b0316858560008181106114a1576114a1614617565b6114b79260206060909202019081019150614512565b6001600160a01b0316146114dd5760405162461bcd60e51b815260040161022c906146f6565b60003490507f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561153d57600080fd5b505af1158015611551573d6000803e3d6000fd5b50505050507f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031663a9059cbb61159b888860008181106112d0576112d0614617565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af11580156115e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061160c919061459e565b611618576116186145bb565b60008686611627600182614600565b81811061163657611636614617565b905060600201602001602081019061164e9190614512565b6040516370a0823160e01b81526001600160a01b03878116600483015291909116906370a0823190602401602060405180830381865afa158015611696573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116ba91906145d1565b90506117188787808060200260200160405190810160405280939291908181526020016000905b8282101561170d576116fe6060830286013681900381019061472d565b815260200190600101906116e1565b505050505086613495565b87818888611727600182614600565b81811061173657611736614617565b905060600201602001602081019061174e9190614512565b6040516370a0823160e01b81526001600160a01b03898116600483015291909116906370a08231906024015b602060405180830381865afa158015611797573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117bb91906145d1565b6117c59190614600565b10156117e35760405162461bcd60e51b815260040161022c9061462d565b5050505050505050565b804281101561180e5760405162461bcd60e51b815260040161022c90614570565b6118b73361187c8787600081811061182857611828614617565b61183e9260206060909202019081019150614512565b8888600081811061185157611851614617565b90506060020160200160208101906118699190614512565b8989600081811061132457611324614617565b898888600081811061189057611890614617565b6118a69260206060909202019081019150614512565b6001600160a01b0316929190612ce5565b600085856118c6600182614600565b8181106118d5576118d5614617565b90506060020160200160208101906118ed9190614512565b6040516370a0823160e01b81526001600160a01b03868116600483015291909116906370a0823190602401602060405180830381865afa158015611935573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195991906145d1565b90506119b78686808060200260200160405190810160405280939291908181526020016000905b828210156119ac5761199d6060830286013681900381019061472d565b81526020019060010190611980565b505050505085613495565b868187876119c6600182614600565b8181106119d5576119d5614617565b90506060020160200160208101906119ed9190614512565b6040516370a0823160e01b81526001600160a01b03888116600483015291909116906370a082319060240161177a565b60608142811015611a405760405162461bcd60e51b815260040161022c90614570565b611a8833611a5a888860008181106112d0576112d0614617565b89600081518110611a6d57611a6d614617565b60200260200101518989600081811061189057611890614617565b611ada878787808060200260200160405190810160405280939291908181526020016000905b8282101561142e57611acb6060830286013681900381019061472d565b81526020019060010190611aae565b509495945050505050565b600080611af789898989898989613818565b9150915097509795505050505050565b8042811015611b285760405162461bcd60e51b815260040161022c90614570565b6001600160a01b037f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb8168585611b5f600182614600565b818110611b6e57611b6e614617565b9050606002016020016020810190611b869190614512565b6001600160a01b031614611bac5760405162461bcd60e51b815260040161022c906146f6565b611bc63361187c8787600081811061182857611828614617565b611c228585808060200260200160405190810160405280939291908181526020016000905b82821015611c1757611c086060830286013681900381019061472d565b81526020019060010190611beb565b505050505030613495565b6040516370a0823160e01b81523060048201526000907f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b0316906370a0823190602401602060405180830381865afa158015611c89573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cad91906145d1565b905086811015611ccf5760405162461bcd60e51b815260040161022c9061462d565b604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015611d3157600080fd5b505af1158015611d45573d6000803e3d6000fd5b505050506117e38482612d56565b6000806000611d838e7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88f61268b565b9050600087611d92578c611d96565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90611dd1903390309086908f908e908e908e9060040161452f565b600060405180830381600087803b158015611deb57600080fd5b505af1158015611dff573d6000803e3d6000fd5b505050506107298f8f8f8f8f8f8f613818565b60608142811015611e355760405162461bcd60e51b815260040161022c90614570565b6001600160a01b037f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb8168686611e6c600182614600565b818110611e7b57611e7b614617565b9050606002016020016020810190611e939190614512565b6001600160a01b031614611eb95760405162461bcd60e51b815260040161022c906146f6565b611f0b888787808060200260200160405190810160405280939291908181526020016000905b828210156111ab57611efc6060830286013681900381019061472d565b81526020019060010190611edf565b9150868260018451611f1d9190614600565b81518110611f2d57611f2d614617565b60200260200101511015611f535760405162461bcd60e51b815260040161022c9061462d565b611f8033611f6d888860008181106112d0576112d0614617565b84600081518110611a6d57611a6d614617565b611fdd828787808060200260200160405190810160405280939291908181526020016000905b82821015611fd257611fc36060830286013681900381019061472d565b81526020019060010190611fa6565b50505050503061309a565b7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b0316632e1a7d4d836001855161201b9190614600565b8151811061202b5761202b614617565b60200260200101516040518263ffffffff1660e01b815260040161205191815260200190565b600060405180830381600087803b15801561206b57600080fd5b505af115801561207f573d6000803e3d6000fd5b505050506120b38483600185516120969190614600565b815181106120a6576120a6614617565b6020026020010151612d56565b509695505050505050565b6060610d4f8383612e18565b6000806000807f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce6001600160a01b0316636801cc308a8a8a6040518463ffffffff1660e01b815260040161212093929190614674565b602060405180830381865afa15801561213d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121619190614698565b9050600080806001600160a01b038416156121eb57836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121d891906145d1565b90506121e58c8c8c6132e9565b90935091505b821580156121f7575081155b15612228578896508795506103e8612217612212888a6146b5565b613885565b6122219190614600565b94506122bb565b60006122358a85856138f5565b905088811161227d5789975095508561227684612252848b6146b5565b61225c91906146d4565b84612267858b6146b5565b61227191906146d4565b6139c3565b95506122b9565b600061228a8a85876138f5565b98508997508890506122b5856122a085846146b5565b6122aa91906146d4565b85612267868c6146b5565b9650505b505b50505050955095509592505050565b60008060006122da8f8f8f61268b565b90506000876122e9578c6122ed565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90612328903390309086908f908e908e908e9060040161452f565b600060405180830381600087803b15801561234257600080fd5b505af1158015612356573d6000803e3d6000fd5b505050505061236b8f8f8f8f8f8f8f8f6128fc565b8093508194505050509c509c9a5050505050505050505050565b6000610d4c8484846138f5565b6000806123a085858561268b565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce9091169063e5e31b1390602401602060405180830381865afa15801561240b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242f919061459e565b156124ad576040516378a051ad60e11b8152600481018790526001600160a01b03868116602483015282169063f140a35a90604401602060405180830381865afa158015612481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a591906145d1565b9150506124b3565b60009150505b949350505050565b600080611af789898989898989612793565b60405163e5e31b1360e01b81526001600160a01b0382811660048301526000917f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce9091169063e5e31b1390602401602060405180830381865afa158015612538573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061255c919061459e565b92915050565b606081428110156125855760405162461bcd60e51b815260040161022c90614570565b6125d7888787808060200260200160405190810160405280939291908181526020016000905b828210156111ab576125c86060830286013681900381019061472d565b815260200190600101906125ab565b91508682600184516125e99190614600565b815181106125f9576125f9614617565b6020026020010151101561261f5760405162461bcd60e51b815260040161022c9061462d565b61263933611f6d888860008181106112d0576112d0614617565b6120b3828787808060200260200160405190810160405280939291908181526020016000905b8282101561142e5761267c6060830286013681900381019061472d565b8152602001906001019061265f565b600080600061269a86866133b3565b6040516bffffffffffffffffffffffff19606084811b8216602084015283901b16603482015286151560f81b604882015291935091507f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce90604901604051602081830303815290604052805190602001207f7bc86d3461c6b25a75205e3bcd8e9815e8477f2af410ccbe931d784a528143fd604051602001612771939291906001600160f81b0319815260609390931b6bffffffffffffffffffffffff191660018401526015830191909152603582015260550190565b60408051601f1981840301815291905280516020909101209695505050505050565b60008082428110156127b75760405162461bcd60e51b815260040161022c90614570565b6127e78a7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88b8b8b8b308b6128fc565b6040516370a0823160e01b8152306004820152919450925061286b9086906001600160a01b038d16906370a0823190602401602060405180830381865afa158015612836573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061285a91906145d1565b6001600160a01b038d1691906139d9565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb86001600160a01b031690632e1a7d4d90602401600060405180830381600087803b1580156128cd57600080fd5b505af11580156128e1573d6000803e3d6000fd5b505050506128ef8583612d56565b5097509795505050505050565b60008082428110156129205760405162461bcd60e51b815260040161022c90614570565b600061292d8c8c8c61268b565b90506129446001600160a01b03821633838c612ce5565b60405163226bf2d160e21b81526001600160a01b03878116600483015260009182918416906389afcb449060240160408051808303816000875af1158015612990573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129b49190614766565b9150915060006129c48f8f6133b3565b509050806001600160a01b03168f6001600160a01b0316146129e75781836129ea565b82825b90975095508a871015612a0f5760405162461bcd60e51b815260040161022c9061478a565b89861015612a2f5760405162461bcd60e51b815260040161022c906147cc565b50505050509850989650505050505050565b60008083861015612a945760405162461bcd60e51b815260206004820152601d60248201527f4372757374526f757465723a20444553495245445f415f414d4f554e54000000604482015260640161022c565b82851015612ae45760405162461bcd60e51b815260206004820152601d60248201527f4372757374526f757465723a20444553495245445f425f414d4f554e54000000604482015260640161022c565b6040516306801cc360e41b81526000906001600160a01b037f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce1690636801cc3090612b37908d908d908d90600401614674565b602060405180830381865afa158015612b54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b789190614698565b90506001600160a01b038116612c1e576040516320b7f73960e21b81526001600160a01b037f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce16906382dfdce490612bd8908d908d908d90600401614674565b6020604051808303816000875af1158015612bf7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c1b9190614698565b90505b600080612c2c8c8c8c6132e9565b91509150816000148015612c3e575080155b15612c4e57889450879350612cd6565b6000612c5b8a84846138f5565b9050888111612c8f5786811015612c845760405162461bcd60e51b815260040161022c906147cc565b899550935083612cd4565b6000612c9c8a84866138f5565b90508a811115612cae57612cae6145bb565b88811015612cce5760405162461bcd60e51b815260040161022c9061478a565b95508894505b505b50505097509795505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052612d509085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613a09565b50505050565b604080516000808252602082019092526001600160a01b038416908390604051612d80919061483a565b60006040518083038185875af1925050503d8060008114612dbd576040519150601f19603f3d011682016040523d82523d6000602084013e612dc2565b606091505b5050905080612e135760405162461bcd60e51b815260206004820181905260248201527f4372757374526f757465723a204d4e545f5452414e534645525f4641494c4544604482015260640161022c565b505050565b6060600182511015612e3c5760405162461bcd60e51b815260040161022c906146f6565b8151612e49906001614856565b67ffffffffffffffff811115612e6157612e61614129565b604051908082528060200260200182016040528015612e8a578160200160208202803683370190505b5090508281600081518110612ea157612ea1614617565b60200260200101818152505060005b8251811015613093576000612f0c848381518110612ed057612ed0614617565b602002602001015160000151858481518110612eee57612eee614617565b602002602001015160200151868581518110610b5c57610b5c614617565b60405163e5e31b1360e01b81526001600160a01b0380831660048301529192507f00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce9091169063e5e31b1390602401602060405180830381865afa158015612f77573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f9b919061459e565b1561308057806001600160a01b031663f140a35a848481518110612fc157612fc1614617565b6020026020010151868581518110612fdb57612fdb614617565b6020026020010151600001516040518363ffffffff1660e01b81526004016130169291909182526001600160a01b0316602082015260400190565b602060405180830381865afa158015613033573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061305791906145d1565b83613063846001614856565b8151811061307357613073614617565b6020026020010181815250505b508061308b8161486e565b915050612eb0565b5092915050565b60005b8251811015612d505760006130ec8483815181106130bd576130bd614617565b6020026020010151600001518584815181106130db576130db614617565b6020026020010151602001516133b3565b5090506000856130fd846001614856565b8151811061310d5761310d614617565b60200260200101519050600080836001600160a01b031687868151811061313657613136614617565b6020026020010151600001516001600160a01b0316146131585782600061315c565b6000835b915091506000600188516131709190614600565b861061317c57866131ef565b6131ef8861318b886001614856565b8151811061319b5761319b614617565b602002602001015160000151898860016131b59190614856565b815181106131c5576131c5614617565b6020026020010151602001518a8960016131df9190614856565b81518110610b5c57610b5c614617565b905061324288878151811061320657613206614617565b60200260200101516000015189888151811061322457613224614617565b6020026020010151602001518a8981518110610b5c57610b5c614617565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f19166020018201604052801561327f576020820181803683370190505b506040518563ffffffff1660e01b815260040161329f94939291906148b3565b600060405180830381600087803b1580156132b957600080fd5b505af11580156132cd573d6000803e3d6000fd5b50505050505050505080806132e19061486e565b91505061309d565b60008060006132f886866133b3565b50905060008061330988888861268b565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015613346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336a91906148f7565b506001600160701b031691506001600160701b03169150826001600160a01b0316886001600160a01b0316146133a15780826133a4565b81815b90999098509650505050505050565b600080826001600160a01b0316846001600160a01b0316036134175760405162461bcd60e51b815260206004820181905260248201527f4372757374526f757465723a204944454e544943414c5f414444524553534553604482015260640161022c565b826001600160a01b0316846001600160a01b03161061343757828461343a565b83835b90925090506001600160a01b038216610d685760405162461bcd60e51b815260206004820152601960248201527f4372757374526f757465723a205a45524f5f4144445245535300000000000000604482015260640161022c565b60005b8251811015612e13576000808483815181106134b6576134b6614617565b6020026020010151600001518584815181106134d4576134d4614617565b6020026020010151602001519150915060006134f083836133b3565b509050600061354687868151811061350a5761350a614617565b60200260200101516000015188878151811061352857613528614617565b602002602001015160200151898881518110610b5c57610b5c614617565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561358c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135b091906148f7565b506001600160701b031691506001600160701b031691506000866001600160a01b0316896001600160a01b0316146135e857816135ea565b825b6040516370a0823160e01b81526001600160a01b03888116600483015291925082918b16906370a0823190602401602060405180830381865afa158015613635573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061365991906145d1565b6136639190614600565b6040516378a051ad60e11b8152600481018290526001600160a01b038b811660248301529196509087169063f140a35a90604401602060405180830381865afa1580156136b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d891906145d1565b9350505050600080856001600160a01b0316886001600160a01b03161461370157826000613705565b6000835b91509150600060018c516137199190614600565b8a10613725578a613788565b6137888c6137348c6001614856565b8151811061374457613744614617565b6020026020010151600001518d8c600161375e9190614856565b8151811061376e5761376e614617565b6020026020010151602001518e8d60016131df9190614856565b6040805160008152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f906137ca90869086908690602481016148b3565b600060405180830381600087803b1580156137e457600080fd5b505af11580156137f8573d6000803e3d6000fd5b5050505050505050505050505080806138109061486e565b915050613498565b600080824281101561383c5760405162461bcd60e51b815260040161022c90614570565b61386c8a7f00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb88b8b8b8b308b6128fc565b909350915061286b6001600160a01b038b1686856139d9565b600060038211156138e6575080600061389f6002836146d4565b6138aa906001614856565b90505b818110156138e0579050806002816138c581866146d4565b6138cf9190614856565b6138d991906146d4565b90506138ad565b50919050565b81156138f0575060015b919050565b60008084116139465760405162461bcd60e51b815260206004820181905260248201527f4372757374526f757465723a20494e53554646494349454e545f414d4f554e54604482015260640161022c565b6000831180156139565750600082115b6139ae5760405162461bcd60e51b815260206004820152602360248201527f4372757374526f757465723a20494e53554646494349454e545f4c495155494460448201526249545960e81b606482015260840161022c565b826139b983866146b5565b610d4c91906146d4565b60008183106139d25781610d4f565b5090919050565b6040516001600160a01b038316602482015260448101829052612e1390849063a9059cbb60e01b90606401612d19565b6000613a5e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613adb9092919063ffffffff16565b805190915015612e135780806020019051810190613a7c919061459e565b612e135760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161022c565b60606001600160a01b0384163b613b345760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161022c565b600080856001600160a01b031685604051613b4f919061483a565b6000604051808303816000865af19150503d8060008114613b8c576040519150601f19603f3d011682016040523d82523d6000602084013e613b91565b606091505b5091509150613ba1828286613bab565b9695505050505050565b60608315613bba575081610d4f565b825115613bca5782518084602001fd5b8160405162461bcd60e51b815260040161022c919061493c565b6001600160a01b0381168114613bf957600080fd5b50565b80356138f081613be4565b8015158114613bf957600080fd5b803560ff811681146138f057600080fd5b60008060008060008060008060008060006101608c8e031215613c4857600080fd5b8b35613c5381613be4565b9a5060208c0135613c6381613c07565b995060408c0135985060608c0135975060808c0135965060a08c0135613c8881613be4565b955060c08c0135945060e08c0135613c9f81613c07565b9350613cae6101008d01613c15565b92506101208c013591506101408c013590509295989b509295989b9093969950565b600080600080600080600080610100898b031215613ced57600080fd5b8835613cf881613be4565b97506020890135613d0881613be4565b96506040890135613d1881613c07565b9550606089013594506080890135935060a0890135925060c0890135613d3d81613be4565b8092505060e089013590509295985092959890939650565b600080600080600080600060e0888a031215613d7057600080fd5b8735613d7b81613be4565b96506020880135613d8b81613c07565b955060408801359450606088013593506080880135925060a0880135613db081613be4565b8092505060c0880135905092959891949750929550565b600080600080600080600060e0888a031215613de257600080fd5b87359650602088013595506040880135613dfb81613be4565b94506060880135613e0b81613be4565b93506080880135613e1b81613c07565b925060a0880135613db081613be4565b6020808252825182820181905260009190848201906040850190845b81811015613e6357835183529284019291840191600101613e47565b50909695505050505050565b60008060008060808587031215613e8557600080fd5b8435613e9081613be4565b93506020850135613ea081613be4565b92506040850135613eb081613c07565b9396929550929360600135925050565b600080600060608486031215613ed557600080fd5b8335613ee081613be4565b92506020840135613ef081613be4565b91506040840135613f0081613c07565b809150509250925092565b60008060408385031215613f1e57600080fd5b8235613f2981613be4565b91506020830135613f3981613be4565b809150509250929050565b60008060008060008060008060006101208a8c031215613f6357600080fd5b8935613f6e81613be4565b985060208a0135613f7e81613be4565b975060408a0135613f8e81613c07565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135613fba81613be4565b809250506101008a013590509295985092959850929598565b600080600060608486031215613fe857600080fd5b833592506020840135613ffa81613be4565b91506040840135613f0081613be4565b60008083601f84011261401c57600080fd5b50813567ffffffffffffffff81111561403457600080fd5b602083019150836020606083028501011115610d6857600080fd5b60008060008060006080868803121561406757600080fd5b85359450602086013567ffffffffffffffff81111561408557600080fd5b6140918882890161400a565b90955093505060408601356140a581613be4565b949793965091946060013592915050565b60008060008060008060a087890312156140cf57600080fd5b8635955060208701359450604087013567ffffffffffffffff8111156140f457600080fd5b61410089828a0161400a565b909550935050606087013561411481613be4565b80925050608087013590509295509295509295565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561416857614168614129565b604052919050565b600067ffffffffffffffff82111561418a5761418a614129565b5060051b60200190565b6000806000806000608086880312156141ac57600080fd5b853567ffffffffffffffff808211156141c457600080fd5b818801915088601f8301126141d857600080fd5b813560206141ed6141e883614170565b61413f565b82815260059290921b8401810191818101908c84111561420c57600080fd5b948201945b8386101561422a57853582529482019490820190614211565b9950508901359250508082111561424057600080fd5b5061424d8882890161400a565b90955093506140a5905060408701613bfc565b60006060828403121561427257600080fd5b6040516060810181811067ffffffffffffffff8211171561429557614295614129565b60405290508082356142a681613be4565b815260208301356142b681613be4565b602082015260408301356142c981613c07565b6040919091015292915050565b600080604083850312156142e957600080fd5b8235915060208084013567ffffffffffffffff81111561430857600080fd5b8401601f8101861361431957600080fd5b80356143276141e882614170565b8181526060918202830184019184820191908984111561434657600080fd5b938501935b8385101561436c5761435d8a86614260565b8352938401939185019161434b565b5080955050505050509250929050565b600080600080600060a0868803121561439457600080fd5b853561439f81613be4565b945060208601356143af81613be4565b935060408601356143bf81613c07565b94979396509394606081013594506080013592915050565b6000806000806000806000806000806000806101808d8f0312156143fa57600080fd5b8c3561440581613be4565b9b5060208d013561441581613be4565b9a5060408d013561442581613c07565b995060608d0135985060808d0135975060a08d0135965060c08d013561444a81613be4565b955060e08d013594506101008d013561446281613c07565b93506144716101208e01613c15565b92506101408d013591506101608d013590509295989b509295989b509295989b565b6000806000606084860312156144a857600080fd5b505081359360208301359350604090920135919050565b600080600080608085870312156144d557600080fd5b8435935060208501356144e781613be4565b925060408501356144f781613be4565b9150606085013561450781613c07565b939692955090935050565b60006020828403121561452457600080fd5b8135610d4f81613be4565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b60208082526014908201527310dc9d5cdd149bdd5d195c8e881156141254915160621b604082015260600190565b6000602082840312156145b057600080fd5b8151610d4f81613c07565b634e487b7160e01b600052600160045260246000fd5b6000602082840312156145e357600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b600082821015614612576146126145ea565b500390565b634e487b7160e01b600052603260045260246000fd5b60208082526027908201527f4372757374526f757465723a20494e53554646494349454e545f4f555450555460408201526617d05353d5539560ca1b606082015260800190565b6001600160a01b039384168152919092166020820152901515604082015260600190565b6000602082840312156146aa57600080fd5b8151610d4f81613be4565b60008160001904831182151516156146cf576146cf6145ea565b500290565b6000826146f157634e487b7160e01b600052601260045260246000fd5b500490565b60208082526019908201527f4372757374526f757465723a20494e56414c49445f5041544800000000000000604082015260600190565b60006060828403121561473f57600080fd5b610d4f8383614260565b60006020828403121561475b57600080fd5b8135610d4f81613c07565b6000806040838503121561477957600080fd5b505080516020909101519092909150565b60208082526022908201527f4372757374526f757465723a20494e53554646494349454e545f415f414d4f55604082015261139560f21b606082015260800190565b60208082526022908201527f4372757374526f757465723a20494e53554646494349454e545f425f414d4f55604082015261139560f21b606082015260800190565b60005b83811015614829578181015183820152602001614811565b83811115612d505750506000910152565b6000825161484c81846020870161480e565b9190910192915050565b60008219821115614869576148696145ea565b500190565b600060018201614880576148806145ea565b5060010190565b6000815180845261489f81602086016020860161480e565b601f01601f19169290920160200192915050565b84815283602082015260018060a01b0383166040820152608060608201526000613ba16080830184614887565b80516001600160701b03811681146138f057600080fd5b60008060006060848603121561490c57600080fd5b614915846148e0565b9250614923602085016148e0565b9150604084015163ffffffff81168114613f0057600080fd5b602081526000610d4f602083018461488756fea26469706673582212205f0e12f7f2fd810cfe323126860e076daa9514d70b2117ed3b87feeaddc0cab464736f6c634300080d0033

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

00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb8

-----Decoded View---------------
Arg [0] : _factory (address): 0x62DbCa39067f99C9D788a253cB325c6BA50e51cE
Arg [1] : _wmnt (address): 0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000062dbca39067f99c9d788a253cb325c6ba50e51ce
Arg [1] : 00000000000000000000000078c1b0c915c4faa5fffa6cabf0219da63d7f4cb8


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.