Contract 0xbca055f25c3670fe0b1463e8d470585fe15ca819 3

 
 
Txn Hash
Method
Block
From
To
Value [Txn Fee]
0x17aae273803adca234e76ee1ed448733ac7a1132036c199ebb8bf36374f4b1d1Swap Exact Token...408023262023-03-26 21:45:1459 mins ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.10640716676389.088981476
0xcd2a084e867d2a554c5b0b5c88b5fa10a030bd96d1e27bbbcc9bbf5af9b42a25Swap Exact Token...407987732023-03-26 19:19:343 hrs 25 mins ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.153674420203119.867009092
0xcb048f9d7b9749bcfe9b25e916367c0fb4bce3ed3d66b352b06128d6f1100fd7Swap Exact Token...407985312023-03-26 19:08:523 hrs 36 mins ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.170893617893133.75275236
0x0e08849dcf067b67424459558bce18bb8cdfdb0fabe516e5333783e9e1fcaf49Swap Exact Token...407985022023-03-26 19:07:323 hrs 37 mins ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.164188815671128.067104614
0x0403a8fc311221de5f04ff7f32c2372146575b8231bca7c2d9ab23a69af031d2Swap Exact Token...407984672023-03-26 19:06:043 hrs 39 mins ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.156404151304121.995074544
0x53cda0acd1f21124c6b4b9344afdc2f57cadc4c0bbc2ce8c45e488b41acaa6feSwap Exact Token...407984442023-03-26 19:05:143 hrs 39 mins ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.150558414705117.435406107
0x112b46014c710b24c46a74dfe3e8d969a2563d285616ac05632e89a7a8568d57Swap Exact Token...407913942023-03-26 13:42:429 hrs 2 mins ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.98569782172768.843270692
0x60298ebfd4872278517e2c4e77f22a2344c3dce656bbfda1637aa57b3dfe5faeSwap Exact Token...407646922023-03-25 20:29:261 day 2 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.10484493339673.561660347
0xb622b372ec0eae022fddfbd56f1f14b2aeea22616ded3701a7bf8dfcc59585e1Swap Exact Token...407622932023-03-25 19:02:511 day 3 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.132538005676110.966923486
0x7d2dbc9f1ed5e25368411bff5961eac36b384344a3a6540a68fc8e099af5b33eSwap Exact Token...407546722023-03-25 14:20:551 day 8 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.204444624275159.46659325
0xdc7cd8843401a5c9da365956eb519f7074cca85fe4701144aeda9aefbabc84f6Swap Exact Token...407546592023-03-25 14:20:271 day 8 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.206010017203160.687598097
0xa9baacf46afab398b61b45e0e32252a85f1b8e46169fe6079cd4f3eec81423c7Swap Exact Token...407545752023-03-25 14:17:271 day 8 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.247342670895192.927024776
0xe687f2bd879d3431ef2fc7c81dccc01e976b084e0b48487918525d1491ec5ddcSwap Exact Token...407543922023-03-25 14:10:591 day 8 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.220230586091184.280886477
0xf1926ddf1db350385f392cfb915fdbf82ac8b0d1e3ee3d765357d75663f62b6bSwap Exact Token...407352622023-03-25 2:35:131 day 20 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.193055534415161.543420853
0xa2eeb185e2871ee897d1940dfc58cd609b132271b6044834229411f6aa7b8e86Swap Exact Token...407349582023-03-25 2:23:231 day 20 hrs ago0x004992db228e2c11b4483f6039d6fc13b0af01fd IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.111926482568 92.753883776
0xa98648ae68c5cf77e1730cbfbce4db9e7ad6c92b8aeaaf76bbf4b9550d2f810dSwap Exact Token...407320372023-03-25 0:33:261 day 22 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.212884325362166.051105513
0xbf8e5130bcc46b5a7d9c206842c7a3df22922ee1fcb44efb99129771443e705aSwap Exact Token...407319732023-03-25 0:30:381 day 22 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.152308481539127.447437378
0x2b6754050d2345e9ea91cdb264a59c8555ba1e51f509053f4e54dd087cbec7ceSwap Exact Token...407319682023-03-25 0:30:281 day 22 hrs ago0x7ca5e8e735d1714104a534c9f39e2a29ab116139 IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.127529983773 107.204809526
0xf977b2a565a479ec2c4a74fb330e831fe88988fb5641ef07949849d743c54d52Swap Exact Token...407315062023-03-25 0:13:341 day 22 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.175764750011137.0963213
0x294f41e8e343dbd741c4801c7ba7de807c11fa8a8925a68bfc4aff59bb669330Swap Exact Token...407305842023-03-24 23:38:381 day 23 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.09419885776878.822153284
0x9da74630cb15b200d44cccaca55dd1923c431491f16df44da4e227d76c542823Swap Exact Token...407277092023-03-24 21:52:292 days 52 mins ago0xcfdd6663018840621fa812ba6043acb5b1fa29d1 IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.133712606097 93.011641774
0x943acdd7f7db8c3e87209cf4353e254ac62579e3e13efd8086b0705a1aae6a8cSwap Exact Token...407274332023-03-24 21:42:112 days 1 hr ago0x7ca5e8e735d1714104a534c9f39e2a29ab116139 IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.148069140627 103.88877629
0x3fc7144fb0a321717eb35089d2403d0227291cacaba64fdcf4358769862dbf48Swap Exact Token...407272522023-03-24 21:35:472 days 1 hr ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.146936489416103.094081678
0x6dfe2fcb64156b860385cf66c123551fb1b0e5df004c2b21bd2f0f6f3ab9c9beSwap Exact Token...407265622023-03-24 21:10:172 days 1 hr ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.1147401875196.065770292
0x0d7938c481230ac31849fa218f35145e7de1e386c7c5e70e5dbf2979d47ae817Swap Exact Token...407211632023-03-24 17:52:312 days 4 hrs ago0x8a3461fc1decc718e921195f54dc5208751aa6bc IN  0xbca055f25c3670fe0b1463e8d470585fe15ca8190 MATIC0.241044093914169.122180642
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x712731f4b4b278ca60edff1b5ad6cda439616b251d0605e7eb431dc001b29b6e402680682023-03-12 17:38:3814 days 5 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x550dd35691e684b2ad82af803b02cd481ba52c5a44.873103615207934968 MATIC
0x712731f4b4b278ca60edff1b5ad6cda439616b251d0605e7eb431dc001b29b6e402680682023-03-12 17:38:3814 days 5 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca81944.873103615207934968 MATIC
0xeb87e64547e0cb635101a0648901489ef0937cc04771f637cc6548445d944e20401891772023-03-10 16:12:1216 days 6 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x51185590592891139d888c647b190004ab128f5f9.782416171928041501 MATIC
0xeb87e64547e0cb635101a0648901489ef0937cc04771f637cc6548445d944e20401891772023-03-10 16:12:1216 days 6 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca8199.782416171928041501 MATIC
0xe6423be72c124242fa33b9da76c4b4bf3ef2348a256886a263695bae8fc21044400775092023-03-07 17:14:5419 days 5 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x4f5997aa478c1b9d4efe64f53cfac408a5a614ab37.547622704569998741 MATIC
0xe6423be72c124242fa33b9da76c4b4bf3ef2348a256886a263695bae8fc21044400775092023-03-07 17:14:5419 days 5 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca81937.547622704569998741 MATIC
0x4982e7a8e36edf819cf43035431b808542de27bb3d9d0af4033034525efe2c67400543192023-03-07 2:47:5819 days 19 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x469d3e86fe04ea16cad35981fedd670ab90a0fd880.321508226250167512 MATIC
0x4982e7a8e36edf819cf43035431b808542de27bb3d9d0af4033034525efe2c67400543192023-03-07 2:47:5819 days 19 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca81980.321508226250167512 MATIC
0xf934b9999d4a4b92d6df442e68614531fc51cce1a85bc734036b473c813d0747400066442023-03-05 20:58:3621 days 1 hr ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x3d6991085ab1ae3926cb96f25684c40a364b68560.866172855472144029 MATIC
0xf934b9999d4a4b92d6df442e68614531fc51cce1a85bc734036b473c813d0747400066442023-03-05 20:58:3621 days 1 hr ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca8190.866172855472144029 MATIC
0xbc47c94c6e7faf4e2a50f60e1e4770cec6f26b4d93587f3d89f70c4c63162336399344642023-03-03 23:42:0922 days 23 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x550dd35691e684b2ad82af803b02cd481ba52c5a40.240974734817183348 MATIC
0xbc47c94c6e7faf4e2a50f60e1e4770cec6f26b4d93587f3d89f70c4c63162336399344642023-03-03 23:42:0922 days 23 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca81940.240974734817183348 MATIC
0xb55846ee81114daa92d28a85e0dd30c2cf069302c73f04df26259ae5489e3d7c398511882023-03-01 18:25:3325 days 4 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x550dd35691e684b2ad82af803b02cd481ba52c5a50.463486318671852019 MATIC
0xb55846ee81114daa92d28a85e0dd30c2cf069302c73f04df26259ae5489e3d7c398511882023-03-01 18:25:3325 days 4 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca81950.463486318671852019 MATIC
0x913147a4fd269b0133bf8002a84cedb3c1b560d9fb0c3c66b4b5e8a91e15ad5b397009972023-02-25 16:49:5829 days 5 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x550dd35691e684b2ad82af803b02cd481ba52c5a125.497986928358254165 MATIC
0x913147a4fd269b0133bf8002a84cedb3c1b560d9fb0c3c66b4b5e8a91e15ad5b397009972023-02-25 16:49:5829 days 5 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca819125.497986928358254165 MATIC
0xba829fa0494b0091dc964710192952c651175291557aa713c1af3bca2912ec8d396947652023-02-25 12:59:2129 days 9 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x34f50c819634e01495b4f5b0df89b89273975f370.011757166937084596 MATIC
0xba829fa0494b0091dc964710192952c651175291557aa713c1af3bca2912ec8d396947652023-02-25 12:59:2129 days 9 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca8190.011757166937084596 MATIC
0x6bed1f9f77cc6f5ab0187ca20e66a3a665eeb71b33006d63edf03f9ca06585bf395658922023-02-21 23:14:3832 days 23 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190xd31bc504a90ba533c54b03664a70c43126478fba232.811213019780498633 MATIC
0x6bed1f9f77cc6f5ab0187ca20e66a3a665eeb71b33006d63edf03f9ca06585bf395658922023-02-21 23:14:3832 days 23 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca819232.811213019780498633 MATIC
0xfd754a266d5b2ae1d67457aa071443204b957e0833ef0b85d15e7caf87b9fc92392900072023-02-14 17:24:2740 days 5 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190x3e051c89cd06e6867ce98c758fcc665d2148e1bb9.662010791701775016 MATIC
0xfd754a266d5b2ae1d67457aa071443204b957e0833ef0b85d15e7caf87b9fc92392900072023-02-14 17:24:2740 days 5 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca8199.662010791701775016 MATIC
0xf76291b2935c3338626f1a27bf9e3eba5bd026838ccaf63db6092bcba4b96b89392702052023-02-14 4:32:2740 days 18 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190xdbe8a352b8ca984f9a044794614ad8cf233a4f7928.134776028110933628 MATIC
0xf76291b2935c3338626f1a27bf9e3eba5bd026838ccaf63db6092bcba4b96b89392702052023-02-14 4:32:2740 days 18 hrs ago Polygon: WMATIC Token 0xbca055f25c3670fe0b1463e8d470585fe15ca81928.134776028110933628 MATIC
0x7b9fc011466df15bba34003ac260597d225b87541d2f7f1c8d08a81601ab067c392701562023-02-14 4:30:4340 days 18 hrs ago 0xbca055f25c3670fe0b1463e8d470585fe15ca8190xdbe8a352b8ca984f9a044794614ad8cf233a4f7912.498872273203227821 MATIC
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TetuSwapRouter

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 150 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 10 : TetuSwapRouter.sol
// SPDX-License-Identifier: UNLICENSED
/**
* By using this software, you understand, acknowledge and accept that Tetu
* and/or the underlying software are provided “as is” and “as available”
* basis and without warranties or representations of any kind either expressed
* or implied. Any use of this open source software released under the ISC
* Internet Systems Consortium license is done at your own risk to the fullest
* extent permissible pursuant to applicable law any and all liability as well
* as all warranties, including any fitness for a particular purpose with respect
* to Tetu and/or the underlying software and the use thereof are disclaimed.
*/

pragma solidity 0.8.4;

import "../openzeppelin/IERC20.sol";
import "./libraries/TransferHelper.sol";
import "./libraries/TetuSwapLibrary.sol";
import "./interfaces/ITetuSwapERC20.sol";
import "./interfaces/ITetuSwapPair.sol";
import "./interfaces/ITetuSwapRouter.sol";
import "./interfaces/ITetuSwapFactory.sol";
import "./interfaces/IWETH.sol";

/// @title UniswapV2Router02 https://github.com/Uniswap/v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol
/// @dev Few changes for compatability with Tetu Swap
contract TetuSwapRouter is ITetuSwapRouter {

  address public immutable override factory;
  address public immutable override WETH;
  string public constant VERSION = "1.1.1";

  event EthReceived(address sender);

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

  constructor(address _factory, address _WETH) {
    require(_factory != address(0), "TSR: Zero factory");
    require(_WETH != address(0), "TSR: Zero WETH");
    factory = _factory;
    WETH = _WETH;
  }

  receive() external payable {
    require(msg.sender == WETH, "TSR: ETH sender is not WETH contract");
    // only accept ETH via fallback from the WETH contract
    emit EthReceived(msg.sender);
  }

  // **** ADD LIQUIDITY ****
  function _addLiquidity(
    address tokenA,
    address tokenB,
    uint amountADesired,
    uint amountBDesired,
    uint amountAMin,
    uint amountBMin
  ) internal virtual returns (uint amountA, uint amountB) {
    require(ITetuSwapFactory(factory).getPair(tokenA, tokenB) != address(0), "TSR: Pair not exist");
    (uint reserveA, uint reserveB) = TetuSwapLibrary.getReserves(factory, tokenA, tokenB);
    if (reserveA == 0 && reserveB == 0) {
      (amountA, amountB) = (amountADesired, amountBDesired);
    } else {
      uint amountBOptimal = TetuSwapLibrary.quote(amountADesired, reserveA, reserveB);
      if (amountBOptimal <= amountBDesired) {
        require(amountBOptimal >= amountBMin, "TSR: INSUFFICIENT_B_AMOUNT");
        (amountA, amountB) = (amountADesired, amountBOptimal);
      } else {
        uint amountAOptimal = TetuSwapLibrary.quote(amountBDesired, reserveB, reserveA);
        assert(amountAOptimal <= amountADesired);
        require(amountAOptimal >= amountAMin, "TSR: INSUFFICIENT_A_AMOUNT");
        (amountA, amountB) = (amountAOptimal, amountBDesired);
      }
    }
  }

  function addLiquidity(
    address tokenA,
    address tokenB,
    uint amountADesired,
    uint amountBDesired,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
    (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
    address pair = TetuSwapLibrary.pairFor(factory, tokenA, tokenB);
    TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
    TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
    liquidity = ITetuSwapPair(pair).mint(to);
  }

  function addLiquidityETH(
    address token,
    uint amountTokenDesired,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) external virtual override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
    (amountToken, amountETH) = _addLiquidity(
      token,
      WETH,
      amountTokenDesired,
      msg.value,
      amountTokenMin,
      amountETHMin
    );
    address pair = TetuSwapLibrary.pairFor(factory, token, WETH);
    TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
    IWETH(WETH).deposit{value : amountETH}();
    assert(IWETH(WETH).transfer(pair, amountETH));
    liquidity = ITetuSwapPair(pair).mint(to);
    // refund dust eth, if any
    if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
  }

  // **** REMOVE LIQUIDITY ****
  function removeLiquidity(
    address tokenA,
    address tokenB,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline
  ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) {
    address pair = TetuSwapLibrary.pairFor(factory, tokenA, tokenB);
    ITetuSwapERC20(pair).transferFrom(msg.sender, pair, liquidity);
    // send liquidity to pair
    (uint amount0, uint amount1) = ITetuSwapPair(pair).burn(to);
    (address token0,) = TetuSwapLibrary.sortTokens(tokenA, tokenB);
    (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
    require(amountA >= amountAMin, "TSR: INSUFFICIENT_A_AMOUNT");
    require(amountB >= amountBMin, "TSR: INSUFFICIENT_B_AMOUNT");
  }

  function removeLiquidityETH(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) public virtual override ensure(deadline) returns (uint amountToken, uint amountETH) {
    (amountToken, amountETH) = removeLiquidity(
      token,
      WETH,
      liquidity,
      amountTokenMin,
      amountETHMin,
      address(this),
      deadline
    );
    TransferHelper.safeTransfer(token, to, amountToken);
    IWETH(WETH).withdraw(amountETH);
    TransferHelper.safeTransferETH(to, amountETH);
  }

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

  function removeLiquidityETHWithPermit(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external virtual override returns (uint amountToken, uint amountETH) {
    address pair = TetuSwapLibrary.pairFor(factory, token, WETH);
    uint value = approveMax ? type(uint).max : liquidity;
    ITetuSwapERC20(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
    (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline);
  }

  // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens) ****
  function removeLiquidityETHSupportingFeeOnTransferTokens(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline
  ) public virtual override ensure(deadline) returns (uint amountETH) {
    (, amountETH) = removeLiquidity(
      token,
      WETH,
      liquidity,
      amountTokenMin,
      amountETHMin,
      address(this),
      deadline
    );
    TransferHelper.safeTransfer(token, to, IERC20(token).balanceOf(address(this)));
    IWETH(WETH).withdraw(amountETH);
    TransferHelper.safeTransferETH(to, amountETH);
  }

  function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external virtual override returns (uint amountETH) {
    address pair = TetuSwapLibrary.pairFor(factory, token, WETH);
    uint value = approveMax ? type(uint).max : liquidity;
    ITetuSwapERC20(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
    amountETH = removeLiquidityETHSupportingFeeOnTransferTokens(
      token, liquidity, amountTokenMin, amountETHMin, to, deadline
    );
  }

  // **** SWAP ****
  // requires the initial amount to have already been sent to the first pair
  function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual {
    for (uint i; i < path.length - 1; i++) {
      (address input, address output) = (path[i], path[i + 1]);
      (address token0,) = TetuSwapLibrary.sortTokens(input, output);
      uint amountOut = amounts[i + 1];
      (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0));
      address to = i < path.length - 2 ? TetuSwapLibrary.pairFor(factory, output, path[i + 2]) : _to;
      ITetuSwapPair(TetuSwapLibrary.pairFor(factory, input, output)).swap(
        amount0Out, amount1Out, to, new bytes(0)
      );
    }
  }

  function swapExactTokensForTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
  ) external virtual override ensure(deadline) returns (uint[] memory amounts) {
    callSync(path);
    amounts = TetuSwapLibrary.getAmountsOut(factory, amountIn, path);
    require(amounts[amounts.length - 1] >= amountOutMin, "TSR: INSUFFICIENT_OUTPUT_AMOUNT");
    TransferHelper.safeTransferFrom(
      path[0], msg.sender, TetuSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]
    );
    _swap(amounts, path, to);
  }

  function swapTokensForExactTokens(
    uint amountOut,
    uint amountInMax,
    address[] calldata path,
    address to,
    uint deadline
  ) external virtual override ensure(deadline) returns (uint[] memory amounts) {
    callSync(path);
    amounts = TetuSwapLibrary.getAmountsIn(factory, amountOut, path);
    require(amounts[0] <= amountInMax, "TSR: EXCESSIVE_INPUT_AMOUNT");
    TransferHelper.safeTransferFrom(
      path[0], msg.sender, TetuSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]
    );
    _swap(amounts, path, to);
  }

  function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
  external
  virtual
  override
  payable
  ensure(deadline)
  returns (uint[] memory amounts)
  {
    require(path[0] == WETH, "TSR: INVALID_PATH");
    callSync(path);
    amounts = TetuSwapLibrary.getAmountsOut(factory, msg.value, path);
    require(amounts[amounts.length - 1] >= amountOutMin, "TSR: INSUFFICIENT_OUTPUT_AMOUNT");
    IWETH(WETH).deposit{value : amounts[0]}();
    assert(IWETH(WETH).transfer(TetuSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
    _swap(amounts, path, to);
  }

  function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
  external
  virtual
  override
  ensure(deadline)
  returns (uint[] memory amounts)
  {
    require(path[path.length - 1] == WETH, "TSR: INVALID_PATH");
    callSync(path);
    amounts = TetuSwapLibrary.getAmountsIn(factory, amountOut, path);
    require(amounts[0] <= amountInMax, "TSR: EXCESSIVE_INPUT_AMOUNT");
    TransferHelper.safeTransferFrom(
      path[0], msg.sender, TetuSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]
    );
    _swap(amounts, path, address(this));
    IWETH(WETH).withdraw(amounts[amounts.length - 1]);
    TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
  }

  function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
  external
  virtual
  override
  ensure(deadline)
  returns (uint[] memory amounts)
  {
    require(path[path.length - 1] == WETH, "TSR: INVALID_PATH");
    callSync(path);
    amounts = TetuSwapLibrary.getAmountsOut(factory, amountIn, path);
    require(amounts[amounts.length - 1] >= amountOutMin, "TSR: INSUFFICIENT_OUTPUT_AMOUNT");
    TransferHelper.safeTransferFrom(
      path[0], msg.sender, TetuSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]
    );
    _swap(amounts, path, address(this));
    IWETH(WETH).withdraw(amounts[amounts.length - 1]);
    TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
  }

  function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
  external
  virtual
  override
  payable
  ensure(deadline)
  returns (uint[] memory amounts)
  {
    require(path[0] == WETH, "TSR: INVALID_PATH");
    callSync(path);
    amounts = TetuSwapLibrary.getAmountsIn(factory, amountOut, path);
    require(amounts[0] <= msg.value, "TSR: EXCESSIVE_INPUT_AMOUNT");
    IWETH(WETH).deposit{value : amounts[0]}();
    assert(IWETH(WETH).transfer(TetuSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
    _swap(amounts, path, to);
    // refund dust eth, if any
    if (msg.value > amounts[0]) TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]);
  }

  // **** SWAP (supporting fee-on-transfer tokens) ****
  // requires the initial amount to have already been sent to the first pair
  function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual {
    for (uint i; i < path.length - 1; i++) {
      (address input, address output) = (path[i], path[i + 1]);
      (address token0,) = TetuSwapLibrary.sortTokens(input, output);
      ITetuSwapPair pair = ITetuSwapPair(TetuSwapLibrary.pairFor(factory, input, output));
      uint amountInput;
      uint amountOutput;
      {// scope to avoid stack too deep errors
        (uint reserve0, uint reserve1,) = pair.getReserves();
        (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
        amountInput = pair.balanceOfVaultUnderlying(input) + IERC20(input).balanceOf(address(pair)) - reserveInput;
        amountOutput = TetuSwapLibrary.getAmountOut(
          amountInput,
          reserveInput,
          reserveOutput,
          pair.fee()
        );
      }
      (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0));
      address to = i < path.length - 2 ? TetuSwapLibrary.pairFor(factory, output, path[i + 2]) : _to;
      pair.swap(amount0Out, amount1Out, to, new bytes(0));
    }
  }

  function swapExactTokensForTokensSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
  ) external virtual override ensure(deadline) {
    callSync(path);
    TransferHelper.safeTransferFrom(
      path[0], msg.sender, TetuSwapLibrary.pairFor(factory, path[0], path[1]), amountIn
    );
    uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
    _swapSupportingFeeOnTransferTokens(path, to);
    require(
      IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin,
      "TSR: INSUFFICIENT_OUTPUT_AMOUNT"
    );
  }

  function swapExactETHForTokensSupportingFeeOnTransferTokens(
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
  )
  external
  virtual
  override
  payable
  ensure(deadline)
  {
    require(path[0] == WETH, "TSR: INVALID_PATH");
    callSync(path);
    uint amountIn = msg.value;
    IWETH(WETH).deposit{value : amountIn}();
    assert(IWETH(WETH).transfer(TetuSwapLibrary.pairFor(factory, path[0], path[1]), amountIn));
    uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to);
    _swapSupportingFeeOnTransferTokens(path, to);
    require(
      IERC20(path[path.length - 1]).balanceOf(to) - balanceBefore >= amountOutMin,
      "TSR: INSUFFICIENT_OUTPUT_AMOUNT"
    );
  }

  function swapExactTokensForETHSupportingFeeOnTransferTokens(
    uint amountIn,
    uint amountOutMin,
    address[] calldata path,
    address to,
    uint deadline
  )
  external
  virtual
  override
  ensure(deadline)
  {
    require(path[path.length - 1] == WETH, "TSR: INVALID_PATH");
    callSync(path);
    TransferHelper.safeTransferFrom(
      path[0], msg.sender, TetuSwapLibrary.pairFor(factory, path[0], path[1]), amountIn
    );
    _swapSupportingFeeOnTransferTokens(path, address(this));
    uint amountOut = IERC20(WETH).balanceOf(address(this));
    require(amountOut >= amountOutMin, "TSR: INSUFFICIENT_OUTPUT_AMOUNT");
    IWETH(WETH).withdraw(amountOut);
    TransferHelper.safeTransferETH(to, amountOut);
  }

  function callSync(address[] memory path) private {
    require(path.length >= 2, "TSR: INVALID_PATH");
    for (uint i; i < path.length - 1; i++) {
      ITetuSwapPair(TetuSwapLibrary.pairFor(factory, path[i], path[i + 1])).sync();
    }
  }

  // **** LIBRARY FUNCTIONS ****
  function quote(uint amountA, uint reserveA, uint reserveB) public pure virtual override returns (uint amountB) {
    return TetuSwapLibrary.quote(amountA, reserveA, reserveB);
  }

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

  function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut, uint fee)
  public
  pure
  virtual
  override
  returns (uint amountIn)
  {
    return TetuSwapLibrary.getAmountIn(amountOut, reserveIn, reserveOut, fee);
  }

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

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

File 2 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
  /**
   * @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);
}

File 3 of 10 : TransferHelper.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity 0.8.4;

/// @title helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {

  function safeApprove(
    address token,
    address to,
    uint256 value
  ) internal {
    // bytes4(keccak256(bytes('approve(address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
    require(
      success && (data.length == 0 || abi.decode(data, (bool))),
      "TransferHelper::safeApprove: approve failed"
    );
  }

  function safeTransfer(
    address token,
    address to,
    uint256 value
  ) internal {
    // bytes4(keccak256(bytes('transfer(address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
    require(
      success && (data.length == 0 || abi.decode(data, (bool))),
      "TransferHelper::safeTransfer: transfer failed"
    );
  }

  function safeTransferFrom(
    address token,
    address from,
    address to,
    uint256 value
  ) internal {
    // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
    require(
      success && (data.length == 0 || abi.decode(data, (bool))),
      "TransferHelper::transferFrom: transferFrom failed"
    );
  }

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

File 4 of 10 : TetuSwapLibrary.sol
// SPDX-License-Identifier: ISC
/**
* By using this software, you understand, acknowledge and accept that Tetu
* and/or the underlying software are provided “as is” and “as available”
* basis and without warranties or representations of any kind either expressed
* or implied. Any use of this open source software released under the ISC
* Internet Systems Consortium license is done at your own risk to the fullest
* extent permissible pursuant to applicable law any and all liability as well
* as all warranties, including any fitness for a particular purpose with respect
* to Tetu and/or the underlying software and the use thereof are disclaimed.
*/

pragma solidity 0.8.4;

import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../interfaces/ITetuSwapPair.sol";
import "../interfaces/ITetuSwapFactory.sol";

/// @title UniswapV2Library https://github.com/Uniswap/v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol
library TetuSwapLibrary {
  using SafeMath for uint;

  uint constant private _PRECISION = 10000;
  uint constant private _FEE = 2;

  /// @dev returns sorted token addresses, used to handle return values from pairs sorted in this order
  function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
    require(tokenA != tokenB, "TSL: IDENTICAL_ADDRESSES");
    (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
    require(token0 != address(0), "TSL: ZERO_ADDRESS");
  }

  /// @dev use stored in factory pairs instead on the flay calculation
  ///      we have more flexible system and can't use old function
  function pairFor(address factory, address tokenA, address tokenB) internal view returns (address pair) {
    return ITetuSwapFactory(factory).getPair(tokenA, tokenB);
  }

  /// @dev fetches and sorts the reserves for a pair
  function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
    (address token0,) = sortTokens(tokenA, tokenB);
    (uint reserve0, uint reserve1,) = ITetuSwapPair(pairFor(factory, tokenA, tokenB)).getReserves();
    (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
  }

  /// @dev given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
  function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) {
    require(amountA > 0, "TSL: INSUFFICIENT_AMOUNT");
    require(reserveA > 0 && reserveB > 0, "TSL: INSUFFICIENT_LIQUIDITY");
    amountB = amountA.mul(reserveB) / reserveA;
  }

  /// @dev given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
  function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut, uint fee) internal pure returns (uint amountOut) {
    require(amountIn > 0, "TSL: INSUFFICIENT_INPUT_AMOUNT");
    require(reserveIn > 0 && reserveOut > 0, "TSL: INSUFFICIENT_LIQUIDITY");
    uint amountInWithFee = amountIn.mul(_PRECISION - fee);
    uint numerator = amountInWithFee.mul(reserveOut);
    uint denominator = reserveIn.mul(_PRECISION).add(amountInWithFee);
    amountOut = numerator / denominator;
  }

  /// @dev given an output amount of an asset and pair reserves, returns a required input amount of the other asset
  function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut, uint fee) internal pure returns (uint amountIn) {
    require(amountOut > 0, "TSL: INSUFFICIENT_OUTPUT_AMOUNT");
    require(reserveIn > 0 && reserveOut > 0, "TSL: INSUFFICIENT_LIQUIDITY");
    uint numerator = reserveIn.mul(amountOut).mul(_PRECISION);
    uint denominator = reserveOut.sub(amountOut).mul(_PRECISION - fee);
    amountIn = (numerator / denominator).add(1);
  }

  /// @dev performs chained getAmountOut calculations on any number of pairs
  function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) {
    require(path.length >= 2, "TSL: INVALID_PATH");
    amounts = new uint[](path.length);
    amounts[0] = amountIn;
    for (uint i; i < path.length - 1; i++) {
      (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]);
      amounts[i + 1] = getAmountOut(
        amounts[i],
        reserveIn,
        reserveOut,
        ITetuSwapPair(pairFor(factory, path[i], path[i + 1])).fee()
      );
    }
  }

  /// @dev performs chained getAmountIn calculations on any number of pairs
  function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) {
    require(path.length >= 2, "TSL: INVALID_PATH");
    amounts = new uint[](path.length);
    amounts[amounts.length - 1] = amountOut;
    for (uint i = path.length - 1; i > 0; i--) {
      (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]);
      amounts[i - 1] = getAmountIn(
        amounts[i],
        reserveIn,
        reserveOut,
        ITetuSwapPair(pairFor(factory, path[i - 1], path[i])).fee()
      );
    }
  }
}

File 5 of 10 : ITetuSwapERC20.sol
// SPDX-License-Identifier: ISC
/**
* By using this software, you understand, acknowledge and accept that Tetu
* and/or the underlying software are provided “as is” and “as available”
* basis and without warranties or representations of any kind either expressed
* or implied. Any use of this open source software released under the ISC
* Internet Systems Consortium license is done at your own risk to the fullest
* extent permissible pursuant to applicable law any and all liability as well
* as all warranties, including any fitness for a particular purpose with respect
* to Tetu and/or the underlying software and the use thereof are disclaimed.
*/

pragma solidity 0.8.4;

interface ITetuSwapERC20 {

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

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

  function decimals() external pure returns (uint8);

  function totalSupply() external view returns (uint);

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

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

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

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

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

  function DOMAIN_SEPARATOR() external view returns (bytes32);

  function PERMIT_TYPEHASH() external pure returns (bytes32);

  function nonces(address owner) external view returns (uint);

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

File 6 of 10 : ITetuSwapPair.sol
// SPDX-License-Identifier: ISC
/**
* By using this software, you understand, acknowledge and accept that Tetu
* and/or the underlying software are provided “as is” and “as available”
* basis and without warranties or representations of any kind either expressed
* or implied. Any use of this open source software released under the ISC
* Internet Systems Consortium license is done at your own risk to the fullest
* extent permissible pursuant to applicable law any and all liability as well
* as all warranties, including any fitness for a particular purpose with respect
* to Tetu and/or the underlying software and the use thereof are disclaimed.
*/

pragma solidity 0.8.4;

interface ITetuSwapPair {

  function balanceOfVaultUnderlying(address _token) external view returns (uint);

  function setFee(uint _fee) external;

  function setVaults(address _vault0, address _vault1) external;

  function setRewardRecipient(address _recipient) external;

  function claimAll() external;

  function MINIMUM_LIQUIDITY() external pure returns (uint);

  function factory() external view returns (address);

  function rewardRecipient() external view returns (address);

  function fee() external view returns (uint);

  function token0() external view returns (address);

  function token1() external view returns (address);

  function vault0() external view returns (address);

  function vault1() external view returns (address);

  function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);

  function price0CumulativeLast() external view returns (uint);

  function price1CumulativeLast() external view returns (uint);

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

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

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

  function sync() external;

  function initialize(
    address _token0,
    address _token1,
    uint _fee
  ) external;

}

File 7 of 10 : ITetuSwapRouter.sol
// SPDX-License-Identifier: ISC
/**
* By using this software, you understand, acknowledge and accept that Tetu
* and/or the underlying software are provided “as is” and “as available”
* basis and without warranties or representations of any kind either expressed
* or implied. Any use of this open source software released under the ISC
* Internet Systems Consortium license is done at your own risk to the fullest
* extent permissible pursuant to applicable law any and all liability as well
* as all warranties, including any fitness for a particular purpose with respect
* to Tetu and/or the underlying software and the use thereof are disclaimed.
*/

pragma solidity 0.8.4;

interface ITetuSwapRouter {

  function factory() external view returns (address);

  function WETH() external view returns (address);

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

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

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

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

  function removeLiquidityWithPermit(
    address tokenA,
    address tokenB,
    uint liquidity,
    uint amountAMin,
    uint amountBMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external returns (uint amountA, uint amountB);

  function removeLiquidityETHWithPermit(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external returns (uint amountToken, uint amountETH);

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

  function swapTokensForExactTokens(
    uint amountOut,
    uint amountInMax,
    address[] calldata path,
    address to,
    uint deadline
  ) external returns (uint[] memory amounts);

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

  function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
  external
  returns (uint[] memory amounts);

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

  function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
  external
  payable
  returns (uint[] memory amounts);

  function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);

  function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut, uint fee) external pure returns (uint amountOut);

  function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut, uint fee) external pure returns (uint amountIn);

  function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);

  function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);

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

  function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
    address token,
    uint liquidity,
    uint amountTokenMin,
    uint amountETHMin,
    address to,
    uint deadline,
    bool approveMax, uint8 v, bytes32 r, bytes32 s
  ) external returns (uint amountETH);

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

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

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

}

File 8 of 10 : ITetuSwapFactory.sol
// SPDX-License-Identifier: ISC
/**
* By using this software, you understand, acknowledge and accept that Tetu
* and/or the underlying software are provided “as is” and “as available”
* basis and without warranties or representations of any kind either expressed
* or implied. Any use of this open source software released under the ISC
* Internet Systems Consortium license is done at your own risk to the fullest
* extent permissible pursuant to applicable law any and all liability as well
* as all warranties, including any fitness for a particular purpose with respect
* to Tetu and/or the underlying software and the use thereof are disclaimed.
*/

pragma solidity 0.8.4;

interface ITetuSwapFactory {

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

  function allPairs(uint) external view returns (address pair);

  function allPairsLength() external view returns (uint);

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

  function validPairs(address _pair) external view returns (bool);

}

File 9 of 10 : IWETH.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.4;

interface IWETH {
  function deposit() external payable;

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

  function withdraw(uint) external;
}

File 10 of 10 : SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"EthReceived","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"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":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","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":"quote","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":"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":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"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":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"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":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040523480156200001157600080fd5b5060405162004c9e38038062004c9e833981016040819052620000349162000109565b6001600160a01b038216620000845760405162461bcd60e51b81526020600482015260116024820152705453523a205a65726f20666163746f727960781b60448201526064015b60405180910390fd5b6001600160a01b038116620000cd5760405162461bcd60e51b815260206004820152600e60248201526d0a8a6a47440b4cae4de40ae8aa8960931b60448201526064016200007b565b6001600160601b0319606092831b8116608052911b1660a05262000140565b80516001600160a01b03811681146200010457600080fd5b919050565b600080604083850312156200011c578182fd5b6200012783620000ec565b91506200013760208401620000ec565b90509250929050565b60805160601c60a05160601c6149c6620002d86000396000818161016a01528181610402015281816105e101528181610630015281816106d70152818161098a01528181610d3501528181610eed015281816112dd0152818161141a015281816114d70152818161156a015281816116e00152818161177c01528181611a2e01528181611afa01528181611b8b01528181611c5201528181611cc6015281816121c4015281816123c70152818161241d01528181612451015281816124d70152818161264b015281816127b501526128510152600081816104b60152818161079d0152818161088b01528181610a8c01528181610ac301528181610bf601528181610dfb01528181610ecb0152818161104c0152818161162f015281816117ae0152818161194d01528181611cf801528181611f5501528181612172015281816121a2015281816122cb015281816123fb015281816127100152818161288301528181612c6d015281816132a3015281816132d60152818161387001528181613af101528181613d410152613e1201526149c66000f3fe60806040526004361061015a5760003560e01c80638803dbee116100c1578063c45a01551161007a578063c45a0155146104a4578063d06ca61f146104d8578063ded9382a146104f8578063e8e3370014610518578063f305d71914610553578063fb3bdb4114610566578063ffa1ad741461057957600080fd5b80638803dbee146103d0578063ad5c4648146103f0578063ad615dec14610431578063af2979eb14610451578063b6f9de9514610471578063baa2abde1461048457600080fd5b806352707d8c1161011357806352707d8c1461030d578063571fd0121461033b5780635b0d59841461035b5780635c11d7951461037b578063791ac9471461039d5780637ff36ab5146103bd57600080fd5b806302751cec1461022657806318cbafe5146102605780631f00ca741461028d5780632195995c146102ad57806338ed1739146102cd5780634a25d94a146102ed57600080fd5b3661022157336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101e85760405162461bcd60e51b8152602060048201526024808201527f5453523a204554482073656e646572206973206e6f74205745544820636f6e746044820152631c9858dd60e21b60648201526084015b60405180910390fd5b7f43d9b737f57bab095d7084cbd3c577bc42c225e75b71031ad697545794e3984a336040516102179190614680565b60405180910390a1005b600080fd5b34801561023257600080fd5b5061024661024136600461429c565b6105b7565b604080519283526020830191909152015b60405180910390f35b34801561026c57600080fd5b5061028061027b36600461456b565b6106aa565b60405161025791906146ee565b34801561029957600080fd5b506102806102a8366004614475565b610a85565b3480156102b957600080fd5b506102466102c8366004614178565b610ab9565b3480156102d957600080fd5b506102806102e836600461456b565b610b92565b3480156102f957600080fd5b5061028061030836600461456b565b610d08565b34801561031957600080fd5b5061032d610328366004614607565b610e9e565b604051908152602001610257565b34801561034757600080fd5b5061032d610356366004614607565b610eb5565b34801561036757600080fd5b5061032d6103763660046142f9565b610ec3565b34801561038757600080fd5b5061039b61039636600461456b565b610fb0565b005b3480156103a957600080fd5b5061039b6103b836600461456b565b6112b2565b6102806103cb366004614410565b611545565b3480156103dc57600080fd5b506102806103eb36600461456b565b6118e9565b3480156103fc57600080fd5b506104247f000000000000000000000000000000000000000000000000000000000000000081565b6040516102579190614680565b34801561043d57600080fd5b5061032d61044c3660046145dc565b6119f0565b34801561045d57600080fd5b5061032d61046c36600461429c565b611a05565b61039b61047f366004614410565b611b68565b34801561049057600080fd5b5061024661049f366004614107565b611f2a565b3480156104b057600080fd5b506104247f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e457600080fd5b506102806104f3366004614475565b61216b565b34801561050457600080fd5b506102466105133660046142f9565b612198565b34801561052457600080fd5b50610538610533366004614221565b61228b565b60408051938452602084019290925290820152606001610257565b61053861056136600461429c565b61239b565b610280610574366004614410565b612626565b34801561058557600080fd5b506105aa60405180604001604052806005815260200164312e312e3160d81b81525081565b6040516102579190614732565b60008082428110156105db5760405162461bcd60e51b81526004016101df906147a7565b61060a897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a611f2a565b909350915061061a898685612a1c565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561067c57600080fd5b505af1158015610690573d6000803e3d6000fd5b5050505061069e8583612b4f565b50965096945050505050565b606081428110156106cd5760405162461bcd60e51b81526004016101df906147a7565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001686866107046001826148c9565b81811061072157634e487b7160e01b600052603260045260246000fd5b905060200201602081019061073691906140cf565b6001600160a01b03161461075c5760405162461bcd60e51b81526004016101df9061477c565b610798868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b6107f67f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612d5692505050565b915086826001845161080891906148c9565b8151811061082657634e487b7160e01b600052603260045260246000fd5b6020026020010151101561084c5760405162461bcd60e51b81526004016101df90614804565b6109498686600081811061087057634e487b7160e01b600052603260045260246000fd5b905060200201602081019061088591906140cf565b3361091b7f00000000000000000000000000000000000000000000000000000000000000008a8a60008181106108cb57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906108e091906140cf565b8b8b600181811061090157634e487b7160e01b600052603260045260246000fd5b905060200201602081019061091691906140cf565b612fd3565b8560008151811061093c57634e487b7160e01b600052603260045260246000fd5b6020026020010151613058565b61098882878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613196915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d83600185516109c691906148c9565b815181106109e457634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b8152600401610a0a91815260200190565b600060405180830381600087803b158015610a2457600080fd5b505af1158015610a38573d6000803e3d6000fd5b50505050610a7a848360018551610a4f91906148c9565b81518110610a6d57634e487b7160e01b600052603260045260246000fd5b6020026020010151612b4f565b509695505050505050565b6060610ab27f000000000000000000000000000000000000000000000000000000000000000084846133ab565b9392505050565b6000806000610ae97f00000000000000000000000000000000000000000000000000000000000000008f8f612fd3565b9050600087610af8578c610afc565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90610b37903390309086908f908e908e908e90600401614694565b600060405180830381600087803b158015610b5157600080fd5b505af1158015610b65573d6000803e3d6000fd5b50505050610b788f8f8f8f8f8f8f611f2a565b809450819550505050509b509b9950505050505050505050565b60608142811015610bb55760405162461bcd60e51b81526004016101df906147a7565b610bf1868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b610c4f7f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612d5692505050565b9150868260018451610c6191906148c9565b81518110610c7f57634e487b7160e01b600052603260045260246000fd5b60200260200101511015610ca55760405162461bcd60e51b81526004016101df90614804565b610cc98686600081811061087057634e487b7160e01b600052603260045260246000fd5b610a7a82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613196915050565b60608142811015610d2b5760405162461bcd60e51b81526004016101df906147a7565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168686610d626001826148c9565b818110610d7f57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610d9491906140cf565b6001600160a01b031614610dba5760405162461bcd60e51b81526004016101df9061477c565b610df6868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b610e547f0000000000000000000000000000000000000000000000000000000000000000898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506133ab92505050565b91508682600081518110610e7857634e487b7160e01b600052603260045260246000fd5b6020026020010151111561084c5760405162461bcd60e51b81526004016101df906147cd565b6000610eac8585858561363c565b95945050505050565b6000610eac85858585613711565b600080610f117f00000000000000000000000000000000000000000000000000000000000000008d7f0000000000000000000000000000000000000000000000000000000000000000612fd3565b9050600086610f20578b610f24565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90610f5f903390309086908e908d908d908d90600401614694565b600060405180830381600087803b158015610f7957600080fd5b505af1158015610f8d573d6000803e3d6000fd5b50505050610f9f8d8d8d8d8d8d611a05565b9d9c50505050505050505050505050565b8042811015610fd15760405162461bcd60e51b81526004016101df906147a7565b61100d858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b6110c88585600081811061103157634e487b7160e01b600052603260045260246000fd5b905060200201602081019061104691906140cf565b336110c27f00000000000000000000000000000000000000000000000000000000000000008989600081811061108c57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906110a191906140cf565b8a8a600181811061090157634e487b7160e01b600052603260045260246000fd5b8a613058565b600085856110d76001826148c9565b8181106110f457634e487b7160e01b600052603260045260246000fd5b905060200201602081019061110991906140cf565b6001600160a01b03166370a08231856040518263ffffffff1660e01b81526004016111349190614680565b60206040518083038186803b15801561114c57600080fd5b505afa158015611160573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061118491906143f8565b90506111c48686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508892506137df915050565b868187876111d36001826148c9565b8181106111f057634e487b7160e01b600052603260045260246000fd5b905060200201602081019061120591906140cf565b6001600160a01b03166370a08231876040518263ffffffff1660e01b81526004016112309190614680565b60206040518083038186803b15801561124857600080fd5b505afa15801561125c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061128091906143f8565b61128a91906148c9565b10156112a85760405162461bcd60e51b81526004016101df90614804565b5050505050505050565b80428110156112d35760405162461bcd60e51b81526004016101df906147a7565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016858561130a6001826148c9565b81811061132757634e487b7160e01b600052603260045260246000fd5b905060200201602081019061133c91906140cf565b6001600160a01b0316146113625760405162461bcd60e51b81526004016101df9061477c565b61139e858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b6113c28585600081811061103157634e487b7160e01b600052603260045260246000fd5b6114008585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152503092506137df915050565b6040516370a0823160e01b81526000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319061144f903090600401614680565b60206040518083038186803b15801561146757600080fd5b505afa15801561147b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061149f91906143f8565b9050868110156114c15760405162461bcd60e51b81526004016101df90614804565b604051632e1a7d4d60e01b8152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561152357600080fd5b505af1158015611537573d6000803e3d6000fd5b505050506112a88482612b4f565b606081428110156115685760405162461bcd60e51b81526004016101df906147a7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316868660008181106115b357634e487b7160e01b600052603260045260246000fd5b90506020020160208101906115c891906140cf565b6001600160a01b0316146115ee5760405162461bcd60e51b81526004016101df9061477c565b61162a868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b6116887f000000000000000000000000000000000000000000000000000000000000000034888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612d5692505050565b915086826001845161169a91906148c9565b815181106116b857634e487b7160e01b600052603260045260246000fd5b602002602001015110156116de5760405162461bcd60e51b81526004016101df90614804565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061172e57634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561176157600080fd5b505af1158015611775573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6117ee7f00000000000000000000000000000000000000000000000000000000000000008989600081811061108c57634e487b7160e01b600052603260045260246000fd5b8460008151811061180f57634e487b7160e01b600052603260045260246000fd5b60200260200101516040518363ffffffff1660e01b81526004016118349291906146d5565b602060405180830381600087803b15801561184e57600080fd5b505af1158015611862573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611886919061438e565b6118a057634e487b7160e01b600052600160045260246000fd5b6118df82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613196915050565b5095945050505050565b6060814281101561190c5760405162461bcd60e51b81526004016101df906147a7565b611948868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b6119a67f0000000000000000000000000000000000000000000000000000000000000000898888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506133ab92505050565b915086826000815181106119ca57634e487b7160e01b600052603260045260246000fd5b60200260200101511115610ca55760405162461bcd60e51b81526004016101df906147cd565b60006119fd848484613bad565b949350505050565b60008142811015611a285760405162461bcd60e51b81526004016101df906147a7565b611a57887f00000000000000000000000000000000000000000000000000000000000000008989893089611f2a565b6040516370a0823160e01b8152909350611ae49150899086906001600160a01b038316906370a0823190611a8f903090600401614680565b60206040518083038186803b158015611aa757600080fd5b505afa158015611abb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611adf91906143f8565b612a1c565b604051632e1a7d4d60e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b158015611b4657600080fd5b505af1158015611b5a573d6000803e3d6000fd5b50505050610a7a8483612b4f565b8042811015611b895760405162461bcd60e51b81526004016101df906147a7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031685856000818110611bd457634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611be991906140cf565b6001600160a01b031614611c0f5760405162461bcd60e51b81526004016101df9061477c565b611c4b858580806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b60003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b158015611cab57600080fd5b505af1158015611cbf573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb611d387f00000000000000000000000000000000000000000000000000000000000000008989600081811061108c57634e487b7160e01b600052603260045260246000fd5b836040518363ffffffff1660e01b8152600401611d569291906146d5565b602060405180830381600087803b158015611d7057600080fd5b505af1158015611d84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da8919061438e565b611dc257634e487b7160e01b600052600160045260246000fd5b60008686611dd16001826148c9565b818110611dee57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611e0391906140cf565b6001600160a01b03166370a08231866040518263ffffffff1660e01b8152600401611e2e9190614680565b60206040518083038186803b158015611e4657600080fd5b505afa158015611e5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e7e91906143f8565b9050611ebe8787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508992506137df915050565b87818888611ecd6001826148c9565b818110611eea57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190611eff91906140cf565b6001600160a01b03166370a08231886040518263ffffffff1660e01b81526004016112309190614680565b6000808242811015611f4e5760405162461bcd60e51b81526004016101df906147a7565b6000611f7b7f00000000000000000000000000000000000000000000000000000000000000008c8c612fd3565b6040516323b872dd60e01b81523360048201526001600160a01b03821660248201819052604482018c90529192506323b872dd90606401602060405180830381600087803b158015611fcc57600080fd5b505af1158015611fe0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612004919061438e565b50600080826001600160a01b03166389afcb44896040518263ffffffff1660e01b81526004016120349190614680565b6040805180830381600087803b15801561204d57600080fd5b505af1158015612061573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120859190614548565b9150915060006120958e8e613c3a565b509050806001600160a01b03168e6001600160a01b0316146120b85781836120bb565b82825b90975095508a87101561210d5760405162461bcd60e51b815260206004820152601a6024820152791514d48e88125394d551919250d251539517d057d05353d5539560321b60448201526064016101df565b8986101561215a5760405162461bcd60e51b815260206004820152601a6024820152791514d48e88125394d551919250d251539517d097d05353d5539560321b60448201526064016101df565b505050505097509795505050505050565b6060610ab27f00000000000000000000000000000000000000000000000000000000000000008484612d56565b60008060006121e87f00000000000000000000000000000000000000000000000000000000000000008e7f0000000000000000000000000000000000000000000000000000000000000000612fd3565b90506000876121f7578c6121fb565b6000195b60405163d505accf60e01b81529091506001600160a01b0383169063d505accf90612236903390309086908f908e908e908e90600401614694565b600060405180830381600087803b15801561225057600080fd5b505af1158015612264573d6000803e3d6000fd5b505050506122768e8e8e8e8e8e6105b7565b909f909e509c50505050505050505050505050565b600080600083428110156122b15760405162461bcd60e51b81526004016101df906147a7565b6122bf8c8c8c8c8c8c613d13565b909450925060006122f17f00000000000000000000000000000000000000000000000000000000000000008e8e612fd3565b90506122ff8d338388613058565b61230b8c338387613058565b6040516335313c2160e11b81526001600160a01b03821690636a62784290612337908a90600401614680565b602060405180830381600087803b15801561235157600080fd5b505af1158015612365573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061238991906143f8565b92505050985098509895505050505050565b600080600083428110156123c15760405162461bcd60e51b81526004016101df906147a7565b6123ef8a7f00000000000000000000000000000000000000000000000000000000000000008b348c8c613d13565b909450925060006124417f00000000000000000000000000000000000000000000000000000000000000008c7f0000000000000000000000000000000000000000000000000000000000000000612fd3565b905061244f8b338388613058565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156124aa57600080fd5b505af11580156124be573d6000803e3d6000fd5b505060405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb92506125119150849088906004016146d5565b602060405180830381600087803b15801561252b57600080fd5b505af115801561253f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612563919061438e565b61257d57634e487b7160e01b600052600160045260246000fd5b6040516335313c2160e11b81526001600160a01b03821690636a627842906125a9908a90600401614680565b602060405180830381600087803b1580156125c357600080fd5b505af11580156125d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125fb91906143f8565b925083341115612618576126183361261386346148c9565b612b4f565b505096509650969350505050565b606081428110156126495760405162461bcd60e51b81526004016101df906147a7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168686600081811061269457634e487b7160e01b600052603260045260246000fd5b90506020020160208101906126a991906140cf565b6001600160a01b0316146126cf5760405162461bcd60e51b81526004016101df9061477c565b61270b868680806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c2e92505050565b6127697f0000000000000000000000000000000000000000000000000000000000000000888888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506133ab92505050565b9150348260008151811061278d57634e487b7160e01b600052603260045260246000fd5b602002602001015111156127b35760405162461bcd60e51b81526004016101df906147cd565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061280357634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561283657600080fd5b505af115801561284a573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6128c37f00000000000000000000000000000000000000000000000000000000000000008989600081811061108c57634e487b7160e01b600052603260045260246000fd5b846000815181106128e457634e487b7160e01b600052603260045260246000fd5b60200260200101516040518363ffffffff1660e01b81526004016129099291906146d5565b602060405180830381600087803b15801561292357600080fd5b505af1158015612937573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061295b919061438e565b61297557634e487b7160e01b600052600160045260246000fd5b6129b482878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613196915050565b816000815181106129d557634e487b7160e01b600052603260045260246000fd5b60200260200101513411156118df576118df3383600081518110612a0957634e487b7160e01b600052603260045260246000fd5b60200260200101513461261391906148c9565b600080846001600160a01b031663a9059cbb8585604051602401612a419291906146d5565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051612a7a9190614664565b6000604051808303816000865af19150503d8060008114612ab7576040519150601f19603f3d011682016040523d82523d6000602084013e612abc565b606091505b5091509150818015612ae6575080511580612ae6575080806020019051810190612ae6919061438e565b612b485760405162461bcd60e51b815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201526c185b9cd9995c8819985a5b1959609a1b60648201526084016101df565b5050505050565b604080516000808252602082019092526001600160a01b038416908390604051612b799190614664565b60006040518083038185875af1925050503d8060008114612bb6576040519150601f19603f3d011682016040523d82523d6000602084013e612bbb565b606091505b5050905080612c295760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527308115512081d1c985b9cd9995c8819985a5b195960621b60648201526084016101df565b505050565b600281511015612c505760405162461bcd60e51b81526004016101df9061477c565b60005b60018251612c6191906148c9565b811015612d5257612ced7f0000000000000000000000000000000000000000000000000000000000000000838381518110612cac57634e487b7160e01b600052603260045260246000fd5b602002602001015184846001612cc29190614872565b81518110612ce057634e487b7160e01b600052603260045260246000fd5b6020026020010151612fd3565b6001600160a01b031663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612d2757600080fd5b505af1158015612d3b573d6000803e3d6000fd5b505050508080612d4a90614923565b915050612c53565b5050565b6060600282511015612d9e5760405162461bcd60e51b81526020600482015260116024820152700a8a6987440929cac82989288bea082a89607b1b60448201526064016101df565b815167ffffffffffffffff811115612dc657634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015612def578160200160208202803683370190505b5090508281600081518110612e1457634e487b7160e01b600052603260045260246000fd5b60200260200101818152505060005b60018351612e3191906148c9565b811015612fcb57600080612ea087868581518110612e5f57634e487b7160e01b600052603260045260246000fd5b602002602001015187866001612e759190614872565b81518110612e9357634e487b7160e01b600052603260045260246000fd5b6020026020010151613f57565b91509150612f80848481518110612ec757634e487b7160e01b600052603260045260246000fd5b60200260200101518383612f0b8b8a8981518110612ef557634e487b7160e01b600052603260045260246000fd5b60200260200101518b8a6001612cc29190614872565b6001600160a01b031663ddca3f436040518163ffffffff1660e01b815260040160206040518083038186803b158015612f4357600080fd5b505afa158015612f57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7b91906143f8565b61363c565b84612f8c856001614872565b81518110612faa57634e487b7160e01b600052603260045260246000fd5b60200260200101818152505050508080612fc390614923565b915050612e23565b509392505050565b60405163e6a4390560e01b81526001600160a01b03838116600483015282811660248301526000919085169063e6a439059060440160206040518083038186803b15801561302057600080fd5b505afa158015613034573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fd91906140eb565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b17905291516000928392908816916130bc9190614664565b6000604051808303816000865af19150503d80600081146130f9576040519150601f19603f3d011682016040523d82523d6000602084013e6130fe565b606091505b5091509150818015613128575080511580613128575080806020019051810190613128919061438e565b61318e5760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a207472604482015270185b9cd9995c919c9bdb4819985a5b1959607a1b60648201526084016101df565b505050505050565b60005b600183516131a791906148c9565b8110156133a5576000808483815181106131d157634e487b7160e01b600052603260045260246000fd5b6020026020010151858460016131e79190614872565b8151811061320557634e487b7160e01b600052603260045260246000fd5b602002602001015191509150600061321d8383613c3a565b50905060008761322e866001614872565b8151811061324c57634e487b7160e01b600052603260045260246000fd5b60200260200101519050600080836001600160a01b0316866001600160a01b03161461327a5782600061327e565b6000835b91509150600060028a5161329291906148c9565b881061329e57886132cf565b6132cf7f0000000000000000000000000000000000000000000000000000000000000000878c612cc28c6002614872565b90506132fc7f00000000000000000000000000000000000000000000000000000000000000008888612fd3565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f191660200182016040528015613339576020820181803683370190505b506040518563ffffffff1660e01b8152600401613359949392919061483b565b600060405180830381600087803b15801561337357600080fd5b505af1158015613387573d6000803e3d6000fd5b5050505050505050505050808061339d90614923565b915050613199565b50505050565b60606002825110156133f35760405162461bcd60e51b81526020600482015260116024820152700a8a6987440929cac82989288bea082a89607b1b60448201526064016101df565b815167ffffffffffffffff81111561341b57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015613444578160200160208202803683370190505b50905082816001835161345791906148c9565b8151811061347557634e487b7160e01b600052603260045260246000fd5b60200260200101818152505060006001835161349191906148c9565b90505b8015612fcb576000806134f387866134ad6001876148c9565b815181106134cb57634e487b7160e01b600052603260045260246000fd5b6020026020010151878681518110612e9357634e487b7160e01b600052603260045260246000fd5b915091506135f184848151811061351a57634e487b7160e01b600052603260045260246000fd5b6020026020010151838361357c8b8a60018a61353691906148c9565b8151811061355457634e487b7160e01b600052603260045260246000fd5b60200260200101518b8a81518110612ce057634e487b7160e01b600052603260045260246000fd5b6001600160a01b031663ddca3f436040518163ffffffff1660e01b815260040160206040518083038186803b1580156135b457600080fd5b505afa1580156135c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135ec91906143f8565b613711565b846135fd6001866148c9565b8151811061361b57634e487b7160e01b600052603260045260246000fd5b602002602001018181525050505080806136349061490c565b915050613494565b600080851161368d5760405162461bcd60e51b815260206004820152601e60248201527f54534c3a20494e53554646494349454e545f494e5055545f414d4f554e54000060448201526064016101df565b60008411801561369d5750600083115b6136b95760405162461bcd60e51b81526004016101df90614745565b60006136d16136ca846127106148c9565b8790614030565b905060006136df8286614030565b905060006136f9836136f389612710614030565b9061403c565b9050613705818361488a565b98975050505050505050565b60008085116137625760405162461bcd60e51b815260206004820152601f60248201527f54534c3a20494e53554646494349454e545f4f55545055545f414d4f554e540060448201526064016101df565b6000841180156137725750600083115b61378e5760405162461bcd60e51b81526004016101df90614745565b60006137a66127106137a08789614030565b90614030565b905060006137c36137b9856127106148c9565b6137a0878a614048565b90506137d460016136f3838561488a565b979650505050505050565b60005b600183516137f091906148c9565b811015612c295760008084838151811061381a57634e487b7160e01b600052603260045260246000fd5b6020026020010151858460016138309190614872565b8151811061384e57634e487b7160e01b600052603260045260246000fd5b60200260200101519150915060006138668383613c3a565b50905060006138967f00000000000000000000000000000000000000000000000000000000000000008585612fd3565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156138d757600080fd5b505afa1580156138eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061390f91906143aa565b506001600160701b031691506001600160701b03169150600080876001600160a01b03168a6001600160a01b03161461394957828461394c565b83835b91509150818a6001600160a01b03166370a08231896040518263ffffffff1660e01b815260040161397d9190614680565b60206040518083038186803b15801561399557600080fd5b505afa1580156139a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139cd91906143f8565b6040516353d7a3cb60e11b81526001600160a01b038a169063a7af4796906139f9908f90600401614680565b60206040518083038186803b158015613a1157600080fd5b505afa158015613a25573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a4991906143f8565b613a539190614872565b613a5d91906148c9565b9550613a9e8683838a6001600160a01b031663ddca3f436040518163ffffffff1660e01b815260040160206040518083038186803b158015612f4357600080fd5b945050505050600080856001600160a01b0316886001600160a01b031614613ac857826000613acc565b6000835b91509150600060028c51613ae091906148c9565b8a10613aec578a613b1d565b613b1d7f0000000000000000000000000000000000000000000000000000000000000000898e612cc28e6002614872565b6040805160008152602081019182905263022c0d9f60e01b9091529091506001600160a01b0387169063022c0d9f90613b5f908690869086906024810161483b565b600060405180830381600087803b158015613b7957600080fd5b505af1158015613b8d573d6000803e3d6000fd5b505050505050505050505050508080613ba590614923565b9150506137e2565b6000808411613bf95760405162461bcd60e51b81526020600482015260186024820152771514d30e88125394d551919250d251539517d05353d5539560421b60448201526064016101df565b600083118015613c095750600082115b613c255760405162461bcd60e51b81526004016101df90614745565b82613c308584614030565b6119fd919061488a565b600080826001600160a01b0316846001600160a01b03161415613c9a5760405162461bcd60e51b815260206004820152601860248201527754534c3a204944454e544943414c5f41444452455353455360401b60448201526064016101df565b826001600160a01b0316846001600160a01b031610613cba578284613cbd565b83835b90925090506001600160a01b038216613d0c5760405162461bcd60e51b815260206004820152601160248201527054534c3a205a45524f5f4144445245535360781b60448201526064016101df565b9250929050565b60405163e6a4390560e01b81526001600160a01b0387811660048301528681166024830152600091829182917f00000000000000000000000000000000000000000000000000000000000000009091169063e6a439059060440160206040518083038186803b158015613d8557600080fd5b505afa158015613d99573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613dbd91906140eb565b6001600160a01b03161415613e0a5760405162461bcd60e51b81526020600482015260136024820152721514d48e8814185a5c881b9bdd08195e1a5cdd606a1b60448201526064016101df565b600080613e387f00000000000000000000000000000000000000000000000000000000000000008b8b613f57565b91509150816000148015613e4a575080155b15613e5a57879350869250613f4a565b6000613e67898484613bad565b9050878111613ec85785811015613ebd5760405162461bcd60e51b815260206004820152601a6024820152791514d48e88125394d551919250d251539517d097d05353d5539560321b60448201526064016101df565b889450925082613f48565b6000613ed5898486613bad565b905089811115613ef557634e487b7160e01b600052600160045260246000fd5b87811015613f425760405162461bcd60e51b815260206004820152601a6024820152791514d48e88125394d551919250d251539517d057d05353d5539560321b60448201526064016101df565b94508793505b505b5050965096945050505050565b6000806000613f668585613c3a565b509050600080613f77888888612fd3565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015613faf57600080fd5b505afa158015613fc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fe791906143aa565b506001600160701b031691506001600160701b03169150826001600160a01b0316876001600160a01b03161461401e578082614021565b81815b90999098509650505050505050565b6000610ab282846148aa565b6000610ab28284614872565b6000610ab282846148c9565b803561405f8161496a565b919050565b60008083601f840112614075578081fd5b50813567ffffffffffffffff81111561408c578182fd5b6020830191508360208260051b8501011115613d0c57600080fd5b80516001600160701b038116811461405f57600080fd5b803560ff8116811461405f57600080fd5b6000602082840312156140e0578081fd5b8135610ab28161496a565b6000602082840312156140fc578081fd5b8151610ab28161496a565b600080600080600080600060e0888a031215614121578283fd5b873561412c8161496a565b9650602088013561413c8161496a565b955060408801359450606088013593506080880135925060a08801356141618161496a565b8092505060c0880135905092959891949750929550565b60008060008060008060008060008060006101608c8e031215614199578384fd5b8b356141a48161496a565b9a5060208c01356141b48161496a565b995060408c0135985060608c0135975060808c0135965060a08c01356141d98161496a565b955060c08c0135945060e08c01356141f081614982565b93506141ff6101008d016140be565b92506101208c013591506101408c013590509295989b509295989b9093969950565b600080600080600080600080610100898b03121561423d578384fd5b88356142488161496a565b975060208901356142588161496a565b965060408901359550606089013594506080890135935060a0890135925060c08901356142848161496a565b8092505060e089013590509295985092959890939650565b60008060008060008060c087890312156142b4578182fd5b86356142bf8161496a565b955060208701359450604087013593506060870135925060808701356142e48161496a565b8092505060a087013590509295509295509295565b6000806000806000806000806000806101408b8d031215614318578384fd5b8a356143238161496a565b995060208b0135985060408b0135975060608b0135965060808b01356143488161496a565b955060a08b0135945060c08b013561435f81614982565b935061436d60e08c016140be565b92506101008b013591506101208b013590509295989b9194979a5092959850565b60006020828403121561439f578081fd5b8151610ab281614982565b6000806000606084860312156143be578081fd5b6143c7846140a7565b92506143d5602085016140a7565b9150604084015163ffffffff811681146143ed578182fd5b809150509250925092565b600060208284031215614409578081fd5b5051919050565b600080600080600060808688031215614427578283fd5b85359450602086013567ffffffffffffffff811115614444578384fd5b61445088828901614064565b90955093505060408601356144648161496a565b949793965091946060013592915050565b60008060408385031215614487578182fd5b8235915060208084013567ffffffffffffffff808211156144a6578384fd5b818601915086601f8301126144b9578384fd5b8135818111156144cb576144cb614954565b8060051b604051601f19603f830116810181811085821117156144f0576144f0614954565b604052828152858101935084860182860187018b101561450e578788fd5b8795505b838610156145375761452381614054565b855260019590950194938601938601614512565b508096505050505050509250929050565b6000806040838503121561455a578182fd5b505080516020909101519092909150565b60008060008060008060a08789031215614583578384fd5b8635955060208701359450604087013567ffffffffffffffff8111156145a7578485fd5b6145b389828a01614064565b90955093505060608701356145c78161496a565b80925050608087013590509295509295509295565b6000806000606084860312156145f0578081fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561461c578182fd5b5050823594602084013594506040840135936060013592509050565b600081518084526146508160208601602086016148e0565b601f01601f19169290920160200192915050565b600082516146768184602087016148e0565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156147265783518352928401929184019160010161470a565b50909695505050505050565b602081526000610ab26020830184614638565b6020808252601b908201527f54534c3a20494e53554646494349454e545f4c49515549444954590000000000604082015260600190565b6020808252601190820152700a8a6a47440929cac82989288bea082a89607b1b604082015260600190565b6020808252600c908201526b1514d48e881156141254915160a21b604082015260600190565b6020808252601b908201527f5453523a204558434553534956455f494e5055545f414d4f554e540000000000604082015260600190565b6020808252601f908201527f5453523a20494e53554646494349454e545f4f55545055545f414d4f554e5400604082015260600190565b84815283602082015260018060a01b03831660408201526080606082015260006148686080830184614638565b9695505050505050565b600082198211156148855761488561493e565b500190565b6000826148a557634e487b7160e01b81526012600452602481fd5b500490565b60008160001904831182151516156148c4576148c461493e565b500290565b6000828210156148db576148db61493e565b500390565b60005b838110156148fb5781810151838201526020016148e3565b838111156133a55750506000910152565b60008161491b5761491b61493e565b506000190190565b60006000198214156149375761493761493e565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461497f57600080fd5b50565b801515811461497f57600080fdfea264697066735822122017bd317e96357d1b36fe5dfd6d9b302d14ab3462a614b5df960974a0cd85841864736f6c63430008040033000000000000000000000000684d8c187be836171a1af8d533e47248930318280000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270

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

000000000000000000000000684d8c187be836171a1af8d533e47248930318280000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270

-----Decoded View---------------
Arg [0] : _factory (address): 0x684d8c187be836171a1af8d533e4724893031828
Arg [1] : _WETH (address): 0x0d500b1d8e8ef31e21c99d1db9a6444d3adf1270

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000684d8c187be836171a1af8d533e4724893031828
Arg [1] : 0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.