Contract 0xc6747954a9b3a074d8e4168b444d7f397fee76aa

 
Txn Hash
Block
From
To
Value [Txn Fee]
0xb5d1711eafa5ca27498d8c98ffcb091e313c00ccbbc9bd5fd94a1e6b7df6a13a84938072021-06-21 15:48:075 mins ago0x680fe8602e15aaf3e6352cb6b70a0817a10cd721 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.002540955
0x301fe09a2cb18552d5d02fb985f56b2edb165d3949992ef454294af9bb4e5dce84937922021-06-21 15:47:226 mins ago0x680fe8602e15aaf3e6352cb6b70a0817a10cd721 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00497758
0x07ff4a283aaaec207e28947e6b54158b6189ea212b796007b338d404d9c6115284937392021-06-21 15:44:439 mins ago0x58fcaa474a64af03f49e1adea4286c7851a0a7c1 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.0006318
0xe0c1fe8fdba62fe063bb0a49993d6a00c3aa604f862d8fc06f7b55b8e457dab884937262021-06-21 15:44:0410 mins ago0x58fcaa474a64af03f49e1adea4286c7851a0a7c1 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.000957615
0x94bb5b4be761c7779d9d6b46d3d3bfee834500c693bf583ca3c0512a24007d7884935942021-06-21 15:37:2816 mins ago0x680fe8602e15aaf3e6352cb6b70a0817a10cd721 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00098351
0x7dc9b4f66921cbfdc5c00f0226965f7dac4b375faacaf2dbbf863ca39d4362c584935862021-06-21 15:37:0417 mins ago0x680fe8602e15aaf3e6352cb6b70a0817a10cd721 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.0007354
0xd7e615a3736238659cde8c81471c166859e5605ef5199ff223a9eae888771a5084934672021-06-21 15:31:0722 mins ago0xc6234ea9efa7073b7f2ce2add48c59f0f583d699 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00111468
0x2869245d1ee75d77179cdeca6277e6871196da4c4a642942b67e0a3b3399b71e84933562021-06-21 15:25:3428 mins ago0x8c5ed76e202ff97ba6cee1659ca7f2e847ecbe91 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.002498435
0x25e7e17d30091b5197342128dd771f2002d8a731a47d647e078765678ec6283684933512021-06-21 15:25:1928 mins ago0x8c5ed76e202ff97ba6cee1659ca7f2e847ecbe91 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00306336
0xc3a3042cc82722608e5d7278857d415f37ee7c5b5fd90abf79b7075a6c47c7fd84931872021-06-21 15:17:0736 mins ago0x8c5ed76e202ff97ba6cee1659ca7f2e847ecbe91 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.0007351
0x8a5ba60ab67f76e1fc2299683e0906bd197877f6983a6f81324bc4a5320eacd184929342021-06-21 15:04:2849 mins ago0x34e88a8b8206b6326925901100daf658d451caa0 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.001320936
0xb175f5f598095c16714fd3fbb07039e3b4b4a0498a21629336a4c75ddd29613084927432021-06-21 14:54:5559 mins ago0xf706366bbc29db2fefda736ffc51db6f288fe96c IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00043417219
0xd7182d6f55684f68f3e438b5efa541c2867cc5a79cb4410a7f9e44d60892935b84925212021-06-21 14:43:491 hr 10 mins ago0x7e459713ac6d9ae684f7b62099be1dab165feb48 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00070674
0x6ed4bb8b3f92936d13e723f91458e2c21ea9105fb51e75f8b34daf92e9d69a3c84923442021-06-21 14:34:581 hr 19 mins ago0xf706366bbc29db2fefda736ffc51db6f288fe96c IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.002812825589
0x7e0b63bff2991705d0fa5e90cd8ddac1148478d993545ba0747e42cdf6ba243684921602021-06-21 14:25:281 hr 28 mins ago0x7e459713ac6d9ae684f7b62099be1dab165feb48 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.000680055
0x797171ed8a9bfb25d31b9709b1ffcfb7d73e947d42ac471554a5d0bc77a185d384921022021-06-21 14:22:341 hr 31 mins ago0xe1d9b961e07625ca94860ecaef2de8016daa0b4e IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.001079155
0x2e522c422ce7be62683d2b524a82f96361eacbed261e800e5bbed56847a6d83b84917932021-06-21 14:07:071 hr 46 mins ago0xd78920bd633b3ca4a17a509834db1d3344a0fd88 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.000679935
0xa241ceb85d4cdfcb63c07c4a83f0ea7812e8dc53627ffec069b2a93c1c7dfb3084917502021-06-21 14:04:581 hr 49 mins ago0x7e459713ac6d9ae684f7b62099be1dab165feb48 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00107056
0x1c102badffff1a72caa2dfbfa9efa2e9d6bfc181b1293bcb2900b777b2ae818384917442021-06-21 14:04:401 hr 49 mins ago0x7e459713ac6d9ae684f7b62099be1dab165feb48 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00113423
0x778bea1c707e648bbaba7a2f3da8fd23b272d0e53cee2ea9b873686df2ffd07284915372021-06-21 13:54:191 hr 59 mins ago0x0804561d4d3cf035c9fe5f8b01a6c5b1f7fc79e1 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.000971745
0x21d5f753fa16f15398c4ab48bed7d7359c2f91cc9443624061e51e5bdd76c57284915282021-06-21 13:53:522 hrs ago0x0804561d4d3cf035c9fe5f8b01a6c5b1f7fc79e1 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00121757
0x4d0df23511f26f33897f9576de65b2a9952e3d35e453d5990695845544f1a8ef84914372021-06-21 13:49:192 hrs 4 mins ago0xa02b2bb2fa12b0ccc1a9928aa700334550ad2e06 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.001633595
0x48f63db9f069fb7d541e8f33aae644f7cd029efa38ad4e18c35e5a4009e9bcc784914282021-06-21 13:48:522 hrs 5 mins ago0x88f1b2d114d5730e246abffa467def7fc7eea649 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.000680055
0x4d9cab6fc103f65854a4a18fa2ad3589cf8e44ee401b64b5911689d6b1c11bb984914242021-06-21 13:48:402 hrs 5 mins ago0x7ace9a7b9cad7ac31a8dee90c24b8fdb477507e3 IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00149419
0x843c41bb25d4c9baf208d384b64a630224650a919ec89f4076a87df08c196e1584913612021-06-21 13:45:312 hrs 8 mins ago0x66a0c5a359fdd60b8a8eb427e95d4b77e159ac4d IN  0xc6747954a9b3a074d8e4168b444d7f397fee76aa0 BNB0.00110066
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x8a5ba60ab67f76e1fc2299683e0906bd197877f6983a6f81324bc4a5320eacd184929342021-06-21 15:04:2849 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0x34e88a8b8206b6326925901100daf658d451caa00.076943901680926688 BNB
0x8a5ba60ab67f76e1fc2299683e0906bd197877f6983a6f81324bc4a5320eacd184929342021-06-21 15:04:2849 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0.076943901680926688 BNB
0x797171ed8a9bfb25d31b9709b1ffcfb7d73e947d42ac471554a5d0bc77a185d384921022021-06-21 14:22:341 hr 31 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0xe1d9b961e07625ca94860ecaef2de8016daa0b4e0.192300488206749201 BNB
0x797171ed8a9bfb25d31b9709b1ffcfb7d73e947d42ac471554a5d0bc77a185d384921022021-06-21 14:22:341 hr 31 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0.192300488206749201 BNB
0x4d0df23511f26f33897f9576de65b2a9952e3d35e453d5990695845544f1a8ef84914372021-06-21 13:49:192 hrs 4 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0xa02b2bb2fa12b0ccc1a9928aa700334550ad2e0638.969972334239401444 BNB
0x4d0df23511f26f33897f9576de65b2a9952e3d35e453d5990695845544f1a8ef84914372021-06-21 13:49:192 hrs 4 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa38.969972334239401444 BNB
0x4d9cab6fc103f65854a4a18fa2ad3589cf8e44ee401b64b5911689d6b1c11bb984914242021-06-21 13:48:402 hrs 5 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0x7ace9a7b9cad7ac31a8dee90c24b8fdb477507e30.472271088680708103 BNB
0x4d9cab6fc103f65854a4a18fa2ad3589cf8e44ee401b64b5911689d6b1c11bb984914242021-06-21 13:48:402 hrs 5 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0.472271088680708103 BNB
0x843c41bb25d4c9baf208d384b64a630224650a919ec89f4076a87df08c196e1584913612021-06-21 13:45:312 hrs 8 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0x66a0c5a359fdd60b8a8eb427e95d4b77e159ac4d0.03295670041759595 BNB
0x843c41bb25d4c9baf208d384b64a630224650a919ec89f4076a87df08c196e1584913612021-06-21 13:45:312 hrs 8 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0.03295670041759595 BNB
0x22fb198f93cfe7626379c3bd57b256ed8de20e48fe5d6fde5046d4c01c5adb6684913372021-06-21 13:44:192 hrs 9 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa Binance: WBNB Token0.03492237164095008 BNB
0xecc7de28699b94271687d869bafac5782fab8974136b1db1125f9e3b1b5fad9d84911442021-06-21 13:34:402 hrs 19 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa Binance: WBNB Token0.034275948803792245 BNB
0xebb9c50dd205c989674bfcb2e5e747522c8d5e9b37486a6e147db7a1891e629184907732021-06-21 13:16:072 hrs 37 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0xdd46509b31b87f05a0da47e6ff9cdaa5563e7a570.051408567652350515 BNB
0xebb9c50dd205c989674bfcb2e5e747522c8d5e9b37486a6e147db7a1891e629184907732021-06-21 13:16:072 hrs 37 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0.051408567652350515 BNB
0xe9013ceaed9082a15f193a9cde6becf6f5e75dbbb294a88f95293688796fcb7884907402021-06-21 13:14:282 hrs 39 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0xdd46509b31b87f05a0da47e6ff9cdaa5563e7a570.050569725219281936 BNB
0xe9013ceaed9082a15f193a9cde6becf6f5e75dbbb294a88f95293688796fcb7884907402021-06-21 13:14:282 hrs 39 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0.050569725219281936 BNB
0x929276c796cdf701800cd1ae303f9ee2efa85071d6dbb01823cb3659746bb13684899862021-06-21 12:36:413 hrs 17 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa Binance: WBNB Token0.007296780235701038 BNB
0xc693c776229b95df0fc2da482cb382e06f90b655922a8668166e80d7f71010c984898932021-06-21 12:32:023 hrs 22 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0x19284ddb440c85085930d30f7062db81beac9e572.547737080941130419 BNB
0xc693c776229b95df0fc2da482cb382e06f90b655922a8668166e80d7f71010c984898932021-06-21 12:32:023 hrs 22 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa2.547737080941130419 BNB
0x20f2dd71d31b789b92b0f3c46df3df83d14cca1022b5243361e31d9b09aed2a884892982021-06-21 12:02:173 hrs 51 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa Binance: WBNB Token20.891998050199323946 BNB
0x95d26a4a189b5e7f5dda9c74f1d51e64689da5898667a84108eb2f0f80dfc1a684890542021-06-21 11:50:054 hrs 4 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa Binance: WBNB Token88.938494377028159978 BNB
0x42396227bb355130ee63945afe131dfa07ec094ee048ce4197939a29b8b7747184889612021-06-21 11:45:264 hrs 8 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0xe1d9b961e07625ca94860ecaef2de8016daa0b4e0.196077142415320808 BNB
0x42396227bb355130ee63945afe131dfa07ec094ee048ce4197939a29b8b7747184889612021-06-21 11:45:264 hrs 8 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0.196077142415320808 BNB
0x9ddee4ca8590504578b3eb22fe2d797ffe4d16a2ab1db25038031b451a28c74284889032021-06-21 11:42:324 hrs 11 mins ago 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0x8f2f44e5b9b70448e72dad1f3b90a1115581c61b0.023909781072772321 BNB
0x9ddee4ca8590504578b3eb22fe2d797ffe4d16a2ab1db25038031b451a28c74284889032021-06-21 11:42:324 hrs 11 mins ago Binance: WBNB Token 0xc6747954a9b3a074d8e4168b444d7f397fee76aa0.023909781072772321 BNB
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
BdexRouter

Compiler Version
v0.6.12+commit.27d51765

Optimization Enabled:
Yes with 8899 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 11 : Initializable.sol
pragma solidity >=0.4.24 <0.7.0;


/**
 * @title Initializable
 *
 * @dev Helper contract to support initializer functions. To use it, replace
 * the constructor with a function that has the `initializer` modifier.
 * WARNING: Unlike constructors, initializer functions must be manually
 * invoked. This applies both to deploying an Initializable contract, as well
 * as extending an Initializable contract via inheritance.
 * WARNING: When used with inheritance, manual care must be taken to not invoke
 * a parent initializer twice, or ensure that all initializers are idempotent,
 * because this is not dealt with automatically as with constructors.
 */
contract Initializable {

  /**
   * @dev Indicates that the contract has been initialized.
   */
  bool private initialized;

  /**
   * @dev Indicates that the contract is in the process of being initialized.
   */
  bool private initializing;

  /**
   * @dev Modifier to use in the initializer function of a contract.
   */
  modifier initializer() {
    require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized");

    bool isTopLevelCall = !initializing;
    if (isTopLevelCall) {
      initializing = true;
      initialized = true;
    }

    _;

    if (isTopLevelCall) {
      initializing = false;
    }
  }

  /// @dev Returns true if and only if the function is running in the constructor
  function isConstructor() private view returns (bool) {
    // extcodesize checks the size of the code stored in an address, and
    // address returns the current address. Since the code is still not
    // deployed when running a constructor, any checks on its code size will
    // yield zero, making it an effective way to detect if a contract is
    // under construction or not.
    address self = address(this);
    uint256 cs;
    assembly { cs := extcodesize(self) }
    return cs == 0;
  }

  // Reserved storage space to allow for layout changes in the future.
  uint256[50] private ______gap;
}

File 2 of 11 : BdexRouter.sol
pragma solidity >=0.6.12;
pragma experimental ABIEncoderV2;

import './interfaces/IBdexFactory.sol';
import './interfaces/IBdexFormula.sol';
import './interfaces/IBdexPair.sol';
import './libraries/TransferHelper.sol';

import './interfaces/IBdexRouter.sol';
import './libraries/SafeMath.sol';
import './interfaces/IWETH.sol';
import './interfaces/IBPool.sol';
import "@openzeppelin/contracts-ethereum-package/contracts/Initializable.sol";
contract BdexRouter is IBdexRouter,Initializable {
    using SafeMath for uint;
    address public override factory;
    address public override formula;
    address public override WETH;
    address private constant ETH_ADDRESS = address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    modifier ensure(uint256 deadline) {
        require(deadline >= block.timestamp, 'Router: EXPIRED');
        _;
    }
    function initialize (address _factory, address _WETH) public initializer{
        factory = _factory;
        formula = IBdexFactory(_factory).formula();
        WETH = _WETH;
    }

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

    // **** ADD LIQUIDITY ****
    function _addLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin
    ) internal virtual returns (uint amountA, uint amountB) {
        (uint reserveA, uint reserveB) = IBdexFormula(formula).getReserves(pair, tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint amountBOptimal = IBdexFormula(formula).quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                require(amountBOptimal >= amountBMin, 'Router: INSUFFICIENT_B_AMOUNT');
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint amountAOptimal = IBdexFormula(formula).quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                require(amountAOptimal >= amountAMin, 'Router: INSUFFICIENT_A_AMOUNT');
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }

    function _addLiquidityToken(
        address pair,
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin
    ) internal returns (uint amountA, uint amountB) {
        (amountA, amountB) = _addLiquidity(pair, tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
    }
    function createPair( address tokenA, address tokenB,uint amountA,uint amountB, uint32 tokenWeightA, uint32 swapFee, address to) public virtual override returns (uint liquidity) {
        address pair = IBdexFactory(factory).createPair(tokenA, tokenB, tokenWeightA, swapFee);
        _addLiquidityToken(pair, tokenA, tokenB, amountA, amountB, 0, 0);
        liquidity = IBdexPair(pair).mint(to);
    }
    function addLiquidity(
        address pair,
        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) = _addLiquidityToken(pair, tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        liquidity = IBdexPair(pair).mint(to);
    }

    function _addLiquidityETH(
        address pair,
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to
    ) internal returns (uint amountToken, uint amountETH, uint liquidity) {
        (amountToken, amountETH) = _addLiquidity(
            pair,
            token,
            WETH,
            amountTokenDesired,
            msg.value,
            amountTokenMin,
            amountETHMin
        );
        TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
        transferETHTo(amountETH, pair);
        liquidity = IBdexPair(pair).mint(to);
        // refund dust eth, if any
        if (msg.value > amountETH) TransferHelper.safeTransferETH(msg.sender, msg.value - amountETH);
    }
    function createPairETH( address token, uint amountToken, uint32 tokenWeight, uint32 swapFee, address to) public virtual override payable returns (uint liquidity) {
        address pair = IBdexFactory(factory).createPair(token, WETH, tokenWeight, swapFee);
        (,,liquidity) = _addLiquidityETH(pair, token, amountToken, 0, 0, to);
    }
    function addLiquidityETH(
        address pair,
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) public virtual override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
        (amountToken, amountETH, liquidity) = _addLiquidityETH(pair, token, amountTokenDesired, amountTokenMin, amountETHMin, to);
    }

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

    function swapExactTokensForTokens(
        address tokenIn,
        address tokenOut,
        uint amountIn,
        uint amountOutMin,
        address[] memory path,
        address to,
        uint deadline
    ) public virtual override ensure(deadline) returns (uint[] memory amounts) {
        amounts = _validateAmountOut(tokenIn, tokenOut, amountIn, amountOutMin, path);

        TransferHelper.safeTransferFrom(
            tokenIn, msg.sender, path[0], amounts[0]
        );
        _swap(tokenIn, amounts, path, to);
    }

    function swapTokensForExactTokens(
        address tokenIn,
        address tokenOut,
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) returns (uint[] memory amounts) {
        amounts = _validateAmountIn(tokenIn, tokenOut, amountOut, amountInMax, path);

        TransferHelper.safeTransferFrom(
            tokenIn, msg.sender, path[0], amounts[0]
        );
        _swap(tokenIn, amounts, path, to);
    }

    function swapExactETHForTokens(address tokenOut, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        virtual
        override
        payable
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        amounts = _validateAmountOut(WETH, tokenOut, msg.value, amountOutMin, path);

        transferETHTo(amounts[0], path[0]);
        _swap(WETH, amounts, path, to);
    }
    function swapTokensForExactETH(address tokenIn, uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        virtual
        override
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        amounts = _validateAmountIn(tokenIn, WETH, amountOut, amountInMax, path);

        TransferHelper.safeTransferFrom(
            tokenIn, msg.sender, path[0], amounts[0]
        );
        _swap(tokenIn, amounts, path, address(this));
        transferAll(ETH_ADDRESS, to, amounts[amounts.length - 1]);
    }
    function swapExactTokensForETH(address tokenIn, uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        virtual
        override
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        amounts = _validateAmountOut(tokenIn, WETH, amountIn, amountOutMin, path);

        TransferHelper.safeTransferFrom(
            tokenIn, msg.sender, path[0], amounts[0]
        );
        _swap(tokenIn, amounts, path, address(this));
        transferAll(ETH_ADDRESS, to, amounts[amounts.length - 1]);
    }
    function swapETHForExactTokens(address tokenOut, uint amountOut, address[] calldata path, address to, uint deadline)
        external
        virtual
        override
        payable
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        amounts = _validateAmountIn(WETH, tokenOut, amountOut, msg.value, path);

        transferETHTo(amounts[0], path[0]);
        _swap(WETH, 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 tokenIn, address[] memory path, address _to) internal virtual {
        address input = tokenIn;
        for (uint i; i < path.length; i++) {
            IBdexPair pair = IBdexPair(path[i]);

            uint amountInput;
            uint amountOutput;
            address currentOutput;
            {
                (address output, uint reserveInput, uint reserveOutput, uint32 tokenWeightInput, uint32 tokenWeightOutput, uint32 swapFee) = IBdexFormula(formula).getFactoryReserveAndWeights(factory, address(pair), input);
                amountInput = IERC20(input).balanceOf(address(pair)).sub(reserveInput);
                amountOutput = IBdexFormula(formula).getAmountOut(amountInput, reserveInput, reserveOutput, tokenWeightInput, tokenWeightOutput, swapFee);
                currentOutput = output;
            }
            (uint amount0Out, uint amount1Out) = input == pair.token0() ? (uint(0), amountOutput) : (amountOutput, uint(0));
            address to = i < path.length - 1 ? path[i + 1] : _to;
            pair.swap(amount0Out, amount1Out, to, new bytes(0));
            emit Exchange(address(pair), amountOutput, currentOutput);
            input = currentOutput;
        }
    }
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        address tokenIn,
        address tokenOut,
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) {
        TransferHelper.safeTransferFrom(
            tokenIn, msg.sender, path[0], amountIn
        );
        uint balanceBefore = IERC20(tokenOut).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(tokenIn, path, to);
        require(
            IERC20(tokenOut).balanceOf(to).sub(balanceBefore) >= amountOutMin,
            'Router: INSUFFICIENT_OUTPUT_AMOUNT'
        );
    }
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        address tokenOut,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    )
        external
        virtual
        override
        payable
        ensure(deadline)
    {
//            require(path[0] == WETH, 'Router: INVALID_PATH');
        uint amountIn = msg.value;
        transferETHTo(amountIn, path[0]);
        uint balanceBefore = IERC20(tokenOut).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(WETH, path, to);
        require(
            IERC20(tokenOut).balanceOf(to).sub(balanceBefore) >= amountOutMin,
            'Router: INSUFFICIENT_OUTPUT_AMOUNT'
        );
    }
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        address tokenIn,
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    )
        external
        virtual
        override
        ensure(deadline)
    {
        TransferHelper.safeTransferFrom(
            tokenIn, msg.sender, path[0], amountIn
        );
        _swapSupportingFeeOnTransferTokens(tokenIn, path, address(this));
        uint amountOut = IERC20(WETH).balanceOf(address(this));
        require(amountOut >= amountOutMin, 'Router: INSUFFICIENT_OUTPUT_AMOUNT');
        transferAll(ETH_ADDRESS, to, amountOut);
    }
    function multihopBatchSwapExactIn(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint totalAmountIn,
        uint minTotalAmountOut,
        uint deadline
    ) public payable override virtual ensure(deadline) returns (uint totalAmountOut) {
        transferFromAll(tokenIn, totalAmountIn);
        uint balanceBefore;
        if (!isETH(tokenOut)) {
            balanceBefore = IERC20(tokenOut).balanceOf(msg.sender);
        }

        for (uint i = 0; i < swapSequences.length; i++) {
            uint tokenAmountOut;
            for (uint k = 0; k < swapSequences[i].length; k++) {
                Swap memory swap = swapSequences[i][k];
                if (k > 0) {
                    // Makes sure that on the second swap the output of the first was used
                    // so there is not intermediate token leftover
                    swap.swapAmount = tokenAmountOut;
                }
                tokenAmountOut = _swapSingleSupportFeeOnTransferTokens(swap.tokenIn, swap.tokenOut, swap.pool, swap.swapAmount, swap.limitReturnAmount);
            }

            // This takes the amountOut of the last swap
            totalAmountOut = tokenAmountOut.add(totalAmountOut);
        }

        transferAll(tokenOut, msg.sender, totalAmountOut);
        transferAll(tokenIn, msg.sender, getBalance(tokenIn));

        if (isETH(tokenOut)) {
            require(totalAmountOut >= minTotalAmountOut, "ERR_LIMIT_OUT");
        } else {
            require(IERC20(tokenOut).balanceOf(msg.sender).sub(balanceBefore) >= minTotalAmountOut, '<minTotalAmountOut');
        }
    }

    function multihopBatchSwapExactOut(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint maxTotalAmountIn,
        uint deadline
    ) public payable override virtual ensure(deadline) returns (uint totalAmountIn) {
        transferFromAll(tokenIn, maxTotalAmountIn);

        for (uint i = 0; i < swapSequences.length; i++) {
            uint tokenAmountInFirstSwap;
            // Specific code for a simple swap and a multihop (2 swaps in sequence)
            if (swapSequences[i].length == 1) {
                Swap memory swap = swapSequences[i][0];
                tokenAmountInFirstSwap = _swapSingleMixOut(swap.tokenIn, swap.tokenOut, swap.pool, swap.swapAmount, swap.limitReturnAmount, swap.maxPrice);

            } else {
                // Consider we are swapping A -> B and B -> C. The goal is to buy a given amount
                // of token C. But first we need to buy B with A so we can then buy C with B
                // To get the exact amount of C we then first need to calculate how much B we'll need:
                uint intermediateTokenAmount;
                // This would be token B as described above
                Swap memory secondSwap = swapSequences[i][1];
                {
                    address[] memory paths = new address[](1);
                    paths[0] = secondSwap.pool;
                    uint[] memory amounts = IBdexFormula(formula).getFactoryAmountsIn(factory, secondSwap.tokenIn, secondSwap.tokenOut, secondSwap.swapAmount, paths);
                    intermediateTokenAmount = amounts[0];
                    require(intermediateTokenAmount <= secondSwap.limitReturnAmount, 'Router: EXCESSIVE_INPUT_AMOUNT');
                }

                //// Buy intermediateTokenAmount of token B with A in the first pool
                Swap memory firstSwap = swapSequences[i][0];
                tokenAmountInFirstSwap = _swapSingleMixOut(firstSwap.tokenIn, firstSwap.tokenOut, firstSwap.pool, intermediateTokenAmount, firstSwap.limitReturnAmount, firstSwap.maxPrice);

                //// Buy the final amount of token C desired
                _swapSingle(secondSwap.tokenIn, secondSwap.pool, intermediateTokenAmount, secondSwap.swapAmount);
            }

            totalAmountIn = tokenAmountInFirstSwap.add(totalAmountIn);
        }

        require(totalAmountIn <= maxTotalAmountIn, "ERR_LIMIT_IN");

        transferAll(tokenOut, msg.sender, getBalance(tokenOut));
        transferAll(tokenIn, msg.sender, getBalance(tokenIn));
    }

    function transferFromAll(address token, uint amount) internal returns (bool) {
        if (isETH(token)) {
            IWETH(WETH).deposit{value : msg.value}();
        } else {
            TransferHelper.safeTransferFrom(token, msg.sender, address(this), amount);
        }
        return true;
    }

    function getBalance(address token) internal view returns (uint) {
        if (isETH(token)) {
            return IWETH(WETH).balanceOf(address(this));
        } else {
            return IERC20(token).balanceOf(address(this));
        }
    }

    function _swapSingleMixOut(address tokenIn, address tokenOut, address pool, uint swapAmount, uint limitReturnAmount, uint maxPrice) internal returns (uint tokenAmountIn) {
        address[] memory paths = new address[](1);
        paths[0] = pool;
        uint[] memory amounts = IBdexFormula(formula).getFactoryAmountsIn(factory, tokenIn, tokenOut, swapAmount, paths);
        tokenAmountIn = amounts[0];
        require(tokenAmountIn <= limitReturnAmount, 'Router: EXCESSIVE_INPUT_AMOUNT');
        _swapSingle(tokenIn, pool, tokenAmountIn, amounts[1]);
    }

    function _swapSingle(address tokenIn, address pair, uint targetSwapAmount, uint targetOutAmount) internal {
        TransferHelper.safeTransfer(tokenIn, pair, targetSwapAmount);
        IBdexPair pairV2 = IBdexPair(pair);
        address token0 = pairV2.token0();

        (uint amount0Out, uint amount1Out, address output) = tokenIn == token0 ? (uint(0), targetOutAmount, pairV2.token1()) : (targetOutAmount, uint(0), token0);
        pairV2.swap(amount0Out, amount1Out, address(this), new bytes(0));

        emit Exchange(pair, targetOutAmount, output);
    }

    function _swapSingleSupportFeeOnTransferTokens(address tokenIn, address tokenOut, address pool, uint swapAmount, uint limitReturnAmount) internal returns(uint tokenAmountOut) {
        TransferHelper.safeTransfer(tokenIn, pool, swapAmount);

        uint amountOutput;
        {
            (, uint reserveInput, uint reserveOutput, uint32 tokenWeightInput, uint32 tokenWeightOutput, uint32 swapFee) = IBdexFormula(formula).getFactoryReserveAndWeights(factory, pool, tokenIn);
            uint amountInput = IERC20(tokenIn).balanceOf(pool).sub(reserveInput);
            amountOutput = IBdexFormula(formula).getAmountOut(amountInput, reserveInput, reserveOutput, tokenWeightInput, tokenWeightOutput, swapFee);
        }
        uint balanceBefore = IERC20(tokenOut).balanceOf(address(this));
        (uint amount0Out, uint amount1Out) = tokenIn == IBdexPair(pool).token0() ? (uint(0), amountOutput) : (amountOutput, uint(0));
        IBdexPair(pool).swap(amount0Out, amount1Out, address(this), new bytes(0));
        emit Exchange(pool, amountOutput, tokenOut);

        tokenAmountOut = IERC20(tokenOut).balanceOf(address(this)).sub(balanceBefore);
        require(tokenAmountOut >= limitReturnAmount,'Router: INSUFFICIENT_OUTPUT_AMOUNT');
    }

    function _validateAmountOut(
        address tokenIn,
        address tokenOut,
        uint amountIn,
        uint amountOutMin,
        address[] memory path
    ) internal view returns (uint[] memory amounts) {
        amounts = IBdexFormula(formula).getFactoryAmountsOut(factory, tokenIn, tokenOut, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'Router: INSUFFICIENT_OUTPUT_AMOUNT');
    }

    function _validateAmountIn(
        address tokenIn,
        address tokenOut,
        uint amountOut,
        uint amountInMax,
        address[] calldata path
    ) internal view returns (uint[] memory amounts) {
        amounts = IBdexFormula(formula).getFactoryAmountsIn(factory, tokenIn, tokenOut, amountOut, path);
        require(amounts[0] <= amountInMax, 'Router: EXCESSIVE_INPUT_AMOUNT');
    }

    function transferETHTo(uint amount, address to) internal {
        IWETH(WETH).deposit{value: amount}();
        assert(IWETH(WETH).transfer(to, amount));
    }

    function transferAll(address token, address to, uint amount) internal returns (bool) {
        if (amount == 0) {
            return true;
        }

        if (isETH(token)) {
            IWETH(WETH).withdraw(amount);
            TransferHelper.safeTransferETH(to, amount);
        } else {
            TransferHelper.safeTransfer(token, to, amount);
        }
        return true;
    }

    function isETH(address token) internal pure returns (bool) {
        return (token == ETH_ADDRESS);
    }
// **** REMOVE LIQUIDITY ****
    function _removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to
    ) internal  returns (uint amountA, uint amountB) {
        require(IBdexFactory(factory).isPair(pair), "Router: Invalid pair");
        IBdexPair(pair).transferFrom(msg.sender, pair, liquidity);
        // send liquidity to pair
        (uint amount0, uint amount1) = IBdexPair(pair).burn(to);
        (address token0,) = IBdexFormula(formula).sortTokens(tokenA, tokenB);
        (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
        require(amountA >= amountAMin, 'Router: INSUFFICIENT_A_AMOUNT');
        require(amountB >= amountBMin, 'Router: INSUFFICIENT_B_AMOUNT');
    }
    function removeLiquidity(
        address pair,
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) {
        (amountA, amountB) = _removeLiquidity(pair, tokenA, tokenB, liquidity, amountAMin, amountBMin, to);
    }

    function removeLiquidityETH(
        address pair,
        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(
            pair,
            token,
            WETH,
            liquidity,
            amountTokenMin,
            amountETHMin,
            address(this)
        );
        TransferHelper.safeTransfer(token, to, amountToken);
        transferAll(ETH_ADDRESS, to, amountETH);
    }

    function removeLiquidityWithPermit(
        address pair,
        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 ensure(deadline) returns (uint amountA, uint amountB) {
        {
            uint value = approveMax ? uint(- 1) : liquidity;
            IBdexPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        }
        (amountA, amountB) = _removeLiquidity(pair, tokenA, tokenB, liquidity, amountAMin, amountBMin, to);
    }

    function removeLiquidityETHWithPermit(
        address pair,
        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) {
        uint value = approveMax ? uint(- 1) : liquidity;
        IBdexPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        (amountToken, amountETH) = removeLiquidityETH(pair, token, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }

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

    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address pair,
        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) {
        uint value = approveMax ? uint(- 1) : liquidity;
        IBdexPair(pair).permit(msg.sender, address(this), value, deadline, v, r, s);
        amountETH = removeLiquidityETHSupportingFeeOnTransferTokens(
            pair, token, liquidity, amountTokenMin, amountETHMin, to, deadline
        );
    }
}

File 3 of 11 : IBPool.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.12;

import "./IERC20.sol";

interface IBPool is IERC20 {
    function version() external view returns(uint);
    function swapExactAmountIn(address, uint, address, uint, uint) external returns (uint, uint);

    function swapExactAmountOut(address, uint, address, uint, uint) external returns (uint, uint);

    function calcInGivenOut(uint, uint, uint, uint, uint, uint) external pure returns (uint);

    function calcOutGivenIn(uint, uint, uint, uint, uint, uint) external pure returns (uint);

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

    function swapFee() external view returns (uint);

    function setSwapFee(uint _swapFee) external;

    function bind(address token, uint balance, uint denorm) external;

    function rebind(address token, uint balance, uint denorm) external;

    function finalize(
        uint _swapFee,
        uint _initPoolSupply,
        address[] calldata _bindTokens,
        uint[] calldata _bindDenorms
    ) external;

    function setPublicSwap(bool _publicSwap) external;
    function setController(address _controller) external;
    function setExchangeProxy(address _exchangeProxy) external;
    function getFinalTokens() external view returns (address[] memory tokens);


    function getTotalDenormalizedWeight() external view returns (uint);

    function getBalance(address token) external view returns (uint);


    function joinPool(uint poolAmountOut, uint[] calldata maxAmountsIn) external;
    function joinPoolFor(address account, uint rewardAmountOut, uint[] calldata maxAmountsIn) external;
    function joinswapPoolAmountOut(address tokenIn, uint poolAmountOut, uint maxAmountIn) external returns (uint tokenAmountIn);

    function exitPool(uint poolAmountIn, uint[] calldata minAmountsOut) external;
    function exitswapPoolAmountIn(address tokenOut, uint poolAmountIn, uint minAmountOut) external returns (uint tokenAmountOut);
    function exitswapExternAmountOut(address tokenOut, uint tokenAmountOut, uint maxPoolAmountIn) external returns (uint poolAmountIn);
    function joinswapExternAmountIn(
        address tokenIn,
        uint tokenAmountIn,
        uint minPoolAmountOut
    ) external returns (uint poolAmountOut);
    function finalizeRewardFundInfo(address _rewardFund, uint _unstakingFrozenTime) external;
    function addRewardPool(IERC20 _rewardToken, uint256 _startBlock, uint256 _endRewardBlock, uint256 _rewardPerBlock,
        uint256 _lockRewardPercent, uint256 _startVestingBlock, uint256 _endVestingBlock) external;
    function isBound(address t) external view returns (bool);
    function getSpotPrice(address tokenIn, address tokenOut) external view returns (uint spotPrice);
}

File 4 of 11 : IBdexFactory.sol
pragma solidity >=0.5.16;

interface IBdexFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint32 tokenWeight0, uint32 swapFee, uint);
    function feeTo() external view returns (address);
    function formula() external view returns (address);
    function protocolFee() external view returns (uint);
    function feeToSetter() external view returns (address);

    function getPair(address tokenA, address tokenB, uint32 tokenWeightA, uint32 swapFee) external view returns (address pair);
    function allPairs(uint) external view returns (address pair);
    function isPair(address) external view returns (bool);
    function allPairsLength() external view returns (uint);

    function createPair(address tokenA, address tokenB, uint32 tokenWeightA, uint32 swapFee) external returns (address pair);
    function getWeightsAndSwapFee(address pair) external view returns (uint32 tokenWeight0, uint32 tokenWeight1, uint32 swapFee);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
    function setProtocolFee(uint) external;
}

File 5 of 11 : IBdexFormula.sol
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
pragma solidity >=0.5.16;

/*
    Bancor Formula interface
*/
interface IBdexFormula {

    function getReserveAndWeights(address pair, address tokenA) external view returns (
        address tokenB,
        uint reserveA,
        uint reserveB,
        uint32 tokenWeightA,
        uint32 tokenWeightB,
        uint32 swapFee
    );

    function getFactoryReserveAndWeights(address factory, address pair, address tokenA) external view returns (
        address tokenB,
        uint reserveA,
        uint reserveB,
        uint32 tokenWeightA,
        uint32 tokenWeightB,
        uint32 swapFee
    );

    function getAmountIn(
        uint amountOut,
        uint reserveIn, uint reserveOut,
        uint32 tokenWeightIn, uint32 tokenWeightOut,
        uint32 swapFee
    ) external view returns (uint amountIn);

    function getPairAmountIn(address pair, address tokenIn, uint amountOut) external view returns (uint amountIn);

    function getAmountOut(
        uint amountIn,
        uint reserveIn, uint reserveOut,
        uint32 tokenWeightIn, uint32 tokenWeightOut,
        uint32 swapFee
    ) external view returns (uint amountOut);

    function getPairAmountOut(address pair, address tokenIn, uint amountIn) external view returns (uint amountOut);

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

    function getFactoryAmountsIn(
        address factory,
        address tokenIn,
        address tokenOut,
        uint amountOut,
        address[] calldata path
    ) external view returns (uint[] memory amounts);

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

    function getFactoryAmountsOut(
        address factory,
        address tokenIn,
        address tokenOut,
        uint amountIn,
        address[] calldata path
    ) external view returns (uint[] memory amounts);

    function ensureConstantValue(uint reserve0, uint reserve1, uint balance0Adjusted, uint balance1Adjusted, uint32 tokenWeight0) external view returns (bool);
    function getReserves(address pair, address tokenA, address tokenB) external view returns (uint reserveA, uint reserveB);
    function getOtherToken(address pair, address tokenA) external view returns (address tokenB);
    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function sortTokens(address tokenA, address tokenB) external pure returns (address token0, address token1);
    function mintLiquidityFee(
        uint totalLiquidity,
        uint112 reserve0,
        uint112  reserve1,
        uint32 tokenWeight0,
        uint32 tokenWeight1,
        uint112  collectedFee0,
        uint112 collectedFee1) external view returns (uint amount);
}

File 6 of 11 : IBdexPair.sol
pragma solidity >=0.5.16;
interface IBdexPair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external view returns (string memory);
    function symbol() external view 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;


    event PaidProtocolFee(uint112 collectedFee0, uint112 collectedFee1);
    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function getCollectedFees() external view returns (uint112 _collectedFee0, uint112 _collectedFee1);
    function getTokenWeights() external view returns (uint32 tokenWeight0, uint32 tokenWeight1);
    function getSwapFee() external view returns (uint32);
    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 skim(address to) external;
    function sync() external;

    function initialize(address, address, uint32, uint32) external;
}

File 7 of 11 : IBdexRouter.sol
pragma solidity >=0.6.12;
pragma experimental ABIEncoderV2;

interface IBdexRouter {
    event Exchange(
        address pair,
        uint amountOut,
        address output
    );
    struct Swap {
        address pool;
        address tokenIn;
        address tokenOut;
        uint swapAmount; // tokenInAmount / tokenOutAmount
        uint limitReturnAmount; // minAmountOut / maxAmountIn
        uint maxPrice;
    }
    function factory() external view returns (address);
    function formula() external view returns (address);

    function WETH() external view returns (address);

    function addLiquidity(
        address pair,
        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 pair,
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);


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

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

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

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

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

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

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

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

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


    function multihopBatchSwapExactIn(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint totalAmountIn,
        uint minTotalAmountOut,
        uint deadline
    )
    external payable returns (uint totalAmountOut);
    function multihopBatchSwapExactOut(
        Swap[][] memory swapSequences,
        address tokenIn,
        address tokenOut,
        uint maxTotalAmountIn,
        uint deadline
    ) external payable returns (uint totalAmountIn);

    function createPair( address tokenA, address tokenB,uint amountA,uint amountB, uint32 tokenWeightA, uint32 swapFee, address to) external returns (uint liquidity);
    function createPairETH( address token, uint amountToken, uint32 tokenWeight, uint32 swapFee, address to) external payable returns (uint liquidity);

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

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

    function removeLiquidityWithPermit(
        address pair,
        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 pair,
        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 removeLiquidityETHSupportingFeeOnTransferTokens(
        address pair,
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);

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

File 8 of 11 : IERC20.sol
pragma solidity >=0.5.16;

interface IERC20 {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function decimals() external view 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);
}

File 9 of 11 : IWETH.sol
pragma solidity >=0.5.0;

interface IWETH {
    function deposit() external payable;
    function transfer(address to, uint value) external returns (bool);
    function withdraw(uint) external;
    function balanceOf(address account) external view returns (uint256);
}

File 10 of 11 : SafeMath.sol
pragma solidity >=0.5.16;

// a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)

library SafeMath {
    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x, 'ds-math-add-overflow');
    }

    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x, 'ds-math-sub-underflow');
    }

    function mul(uint x, uint y) internal pure returns (uint z) {
        require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
    }
    function div(uint a, uint b) internal pure returns (uint c) {
        require(b > 0, 'ds-math-division-by-zero');
        c = a / b;
    }
}

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

pragma solidity >=0.5.16;

// 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, uint 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: APPROVE_FAILED');
    }

    function safeTransfer(address token, address to, uint 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: TRANSFER_FAILED');
    }

    function safeTransferFrom(address token, address from, address to, uint 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: TRANSFER_FROM_FAILED');
    }

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

Settings
{
  "evmVersion": "istanbul",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 8899
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"address","name":"output","type":"address"}],"name":"Exchange","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"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":"pair","type":"address"},{"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":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint32","name":"tokenWeightA","type":"uint32"},{"internalType":"uint32","name":"swapFee","type":"uint32"},{"internalType":"address","name":"to","type":"address"}],"name":"createPair","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint32","name":"tokenWeight","type":"uint32"},{"internalType":"uint32","name":"swapFee","type":"uint32"},{"internalType":"address","name":"to","type":"address"}],"name":"createPairETH","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"formula","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"swapAmount","type":"uint256"},{"internalType":"uint256","name":"limitReturnAmount","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"internalType":"struct IBdexRouter.Swap[][]","name":"swapSequences","type":"tuple[][]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"totalAmountIn","type":"uint256"},{"internalType":"uint256","name":"minTotalAmountOut","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"multihopBatchSwapExactIn","outputs":[{"internalType":"uint256","name":"totalAmountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"swapAmount","type":"uint256"},{"internalType":"uint256","name":"limitReturnAmount","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"internalType":"struct IBdexRouter.Swap[][]","name":"swapSequences","type":"tuple[][]"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"maxTotalAmountIn","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"multihopBatchSwapExactOut","outputs":[{"internalType":"uint256","name":"totalAmountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"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":"pair","type":"address"},{"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":"pair","type":"address"},{"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":"pair","type":"address"},{"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":"pair","type":"address"},{"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":"pair","type":"address"},{"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":"address","name":"tokenOut","type":"address"},{"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":"address","name":"tokenOut","type":"address"},{"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":"address","name":"tokenOut","type":"address"},{"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":"address","name":"tokenIn","type":"address"},{"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":"address","name":"tokenIn","type":"address"},{"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":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"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":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"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":"address","name":"tokenIn","type":"address"},{"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":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"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"}]

608060405234801561001057600080fd5b50614b90806100206000396000f3fe60806040526004361061019a5760003560e01c8063ad5c4648116100e1578063d0f2c82a1161008a578063ebb5d2e911610064578063ebb5d2e914610438578063fa3219d514610458578063fbf4513514610478578063fde1adda14610498576101b5565b8063d0f2c82a146103d8578063d59e44ee146103f8578063e1f4a78414610418576101b5565b8063bff51d71116100bb578063bff51d7114610390578063c45a0155146103b0578063ce819632146103c5576101b5565b8063ad5c464814610348578063b05f579e1461035d578063b56b681d14610370576101b5565b8063674ee80b116101435780639c91fcb51161011d5780639c91fcb5146102db578063a4aabb0814610308578063a67d0e3c14610328576101b5565b8063674ee80b146102a25780636cb49428146102b5578063840c34d0146102c8576101b5565b80634b75f54f116101745780634b75f54f146102325780634c17fd7c146102545780635cae031014610282576101b5565b80630e2f024c146101ba5780633990ba54146101f0578063485cc95514610212576101b5565b366101b5576035546001600160a01b031633146101b357fe5b005b600080fd5b3480156101c657600080fd5b506101da6101d5366004613ee3565b6104ab565b6040516101e79190614a1c565b60405180910390f35b6102036101fe366004613e72565b610581565b6040516101e793929190614a61565b34801561021e57600080fd5b506101b361022d366004613ab9565b6105d2565b34801561023e57600080fd5b506102476107b3565b6040516101e791906143fa565b34801561026057600080fd5b5061027461026f366004613ba3565b6107c2565b6040516101e7929190614a25565b34801561028e57600080fd5b506101b361029d36600461408a565b6108ab565b6101b36102b0366004614010565b610a1f565b6101da6102c3366004614182565b610c08565b6101da6102d63660046141e9565b610cd0565b3480156102e757600080fd5b506102fb6102f636600461408a565b610ff3565b6040516101e79190614607565b34801561031457600080fd5b50610274610323366004613ee3565b611131565b34801561033457600080fd5b506101b3610343366004613ced565b61120d565b34801561035457600080fd5b50610247611368565b6102fb61036b366004614010565b611377565b34801561037c57600080fd5b5061027461038b366004613e72565b61146e565b34801561039c57600080fd5b506102fb6103ab366004613d84565b6114ec565b3480156103bc57600080fd5b5061024761155d565b6101da6103d336600461425b565b61156c565b3480156103e457600080fd5b506101da6103f3366004613f8d565b61179b565b34801561040457600080fd5b506102fb610413366004613ced565b6118ec565b34801561042457600080fd5b50610274610433366004613b1f565b61197e565b34801561044457600080fd5b506101da610453366004613e72565b6119c3565b34801561046457600080fd5b506102fb61047336600461408a565b611ac9565b34801561048457600080fd5b50610203610493366004613c5f565b611b07565b6102fb6104a6366004614010565b611bea565b600080856104b9578a6104db565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf0000000000000000000000000000000000000000000000000000000081529091506001600160a01b038e169063d505accf9061052f903390309086908d908c908c908c9060040161440e565b600060405180830381600087803b15801561054957600080fd5b505af115801561055d573d6000803e3d6000fd5b505050506105708d8d8d8d8d8d8d6119c3565b9d9c50505050505050505050505050565b600080600083428110156105b05760405162461bcd60e51b81526004016105a79061483a565b60405180910390fd5b6105be8b8b8b8b8b8b611cb7565b919d909c50909a5098505050505050505050565b600054610100900460ff16806105eb57506105eb611daf565b806105f9575060005460ff16155b6106155760405162461bcd60e51b81526004016105a790614871565b600054610100900460ff1615801561067b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff909116610100171660011790555b603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b038516908117909155604080517f4b75f54f0000000000000000000000000000000000000000000000000000000081529051634b75f54f91600480820192602092909190829003018186803b15801561070057600080fd5b505afa158015610714573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107389190613a9d565b603480547fffffffffffffffffffffffff00000000000000000000000000000000000000009081166001600160a01b03938416179091556035805490911691841691909117905580156107ae57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b505050565b6034546001600160a01b031681565b60008086428110156107e65760405162461bcd60e51b81526004016105a79061483a565b6000876107f3578c610815565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b90508f6001600160a01b031663d505accf3330848d8c8c8c6040518863ffffffff1660e01b815260040161084f979695949392919061440e565b600060405180830381600087803b15801561086957600080fd5b505af115801561087d573d6000803e3d6000fd5b50505050506108918f8f8f8f8f8f8f611db5565b8093508194505050509c509c9a5050505050505050505050565b80428110156108cc5760405162461bcd60e51b81526004016105a79061483a565b6108f98833878760008181106108de57fe5b90506020020160208101906108f39190613a81565b8a6120a8565b610938888686808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152503092506121ae915050565b6035546040517f70a082310000000000000000000000000000000000000000000000000000000081526000916001600160a01b0316906370a08231906109829030906004016143fa565b60206040518083038186803b15801561099a57600080fd5b505afa1580156109ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d29190614377565b9050868110156109f45760405162461bcd60e51b81526004016105a7906148ce565b610a1373eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8583612521565b50505050505050505050565b8042811015610a405760405162461bcd60e51b81526004016105a79061483a565b34610a6a818787600081610a5057fe5b9050602002016020810190610a659190613a81565b6125de565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526000906001600160a01b038a16906370a0823190610ab29088906004016143fa565b60206040518083038186803b158015610aca57600080fd5b505afa158015610ade573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b029190614377565b9050610b58603560009054906101000a90046001600160a01b03168888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a92506121ae915050565b87610bdf828b6001600160a01b03166370a08231896040518263ffffffff1660e01b8152600401610b8991906143fa565b60206040518083038186803b158015610ba157600080fd5b505afa158015610bb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd99190614377565b906126ee565b1015610bfd5760405162461bcd60e51b81526004016105a7906148ce565b505050505050505050565b6033546035546040517f14572adb00000000000000000000000000000000000000000000000000000000815260009283926001600160a01b03918216926314572adb92610c60928c929116908a908a9060040161459a565b602060405180830381600087803b158015610c7a57600080fd5b505af1158015610c8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cb29190613a9d565b9050610cc381888860008088611cb7565b9998505050505050505050565b60008142811015610cf35760405162461bcd60e51b81526004016105a79061483a565b610cfd8685612717565b5060005b8751811015610fa5576000888281518110610d1857fe5b60200260200101515160011415610d8957610d31613885565b898381518110610d3d57fe5b6020026020010151600081518110610d5157fe5b60200260200101519050610d81816020015182604001518360000151846060015185608001518660a001516127aa565b915050610f90565b6000610d93613885565b8a8481518110610d9f57fe5b6020026020010151600181518110610db357fe5b602002602001015190506060600167ffffffffffffffff81118015610dd757600080fd5b50604051908082528060200260200182016040528015610e01578160200160208202803683370190505b509050816000015181600081518110610e1657fe5b6001600160a01b039283166020918202929092018101919091526034546033549185015160408087015160608881015192517f67f84adc0000000000000000000000000000000000000000000000000000000081529096948516956367f84adc95610e8b959116939092918990600401614527565b60006040518083038186803b158015610ea357600080fd5b505afa158015610eb7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610edf91908101906142d7565b905080600081518110610eee57fe5b602002602001015193508260800151841115610f1c5760405162461bcd60e51b81526004016105a7906146f0565b5050610f26613885565b8b8581518110610f3257fe5b6020026020010151600081518110610f4657fe5b60200260200101519050610f728160200151826040015183600001518685608001518660a001516127aa565b9350610f8c826020015183600001518585606001516128ed565b5050505b610f9a8185612ae5565b935050600101610d01565b5083821115610fc65760405162461bcd60e51b81526004016105a790614803565b610fd98533610fd488612b08565b612521565b50610fe88633610fd489612b08565b505095945050505050565b606081428110156110165760405162461bcd60e51b81526004016105a79061483a565b61106b89603560009054906101000a90046001600160a01b03168a8a8a8a80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250612c0292505050565b91506110ae89338888600081811061107f57fe5b90506020020160208101906110949190613a81565b856000815181106110a157fe5b60200260200101516120a8565b6110ee8983888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250612cf1915050565b61112473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee858460018651038151811061111757fe5b6020026020010151612521565b5050979650505050505050565b600080600086611141578b611163565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff5b6040517fd505accf0000000000000000000000000000000000000000000000000000000081529091506001600160a01b038f169063d505accf906111b7903390309086908e908d908d908d9060040161440e565b600060405180830381600087803b1580156111d157600080fd5b505af11580156111e5573d6000803e3d6000fd5b505050506111f88e8e8e8e8e8e8e61146e565b909f909e509c50505050505050505050505050565b804281101561122e5760405162461bcd60e51b81526004016105a79061483a565b6112408933878760008181106108de57fe5b6040517f70a082310000000000000000000000000000000000000000000000000000000081526000906001600160a01b038a16906370a08231906112889087906004016143fa565b60206040518083038186803b1580156112a057600080fd5b505afa1580156112b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112d89190614377565b90506113198a8787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508992506121ae915050565b8661134a828b6001600160a01b03166370a08231886040518263ffffffff1660e01b8152600401610b8991906143fa565b1015610a135760405162461bcd60e51b81526004016105a7906148ce565b6035546001600160a01b031681565b6060814281101561139a5760405162461bcd60e51b81526004016105a79061483a565b6035546113b4906001600160a01b03168989348a8a612f4e565b91506113db826000815181106113c657fe5b602002602001015187876000818110610a5057fe5b6035546040805160208089028281018201909352888252611427936001600160a01b0316928692918b918b918291908501908490808284376000920191909152508a9250612cf1915050565b8160008151811061143457fe5b602002602001015134111561146357611463338360008151811061145457fe5b6020026020010151340361303d565b509695505050505050565b60008082428110156114925760405162461bcd60e51b81526004016105a79061483a565b6035546114af908b908b906001600160a01b03168b8b8b30611db5565b90935091506114bf8986856130ca565b6114de73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8684612521565b505097509795505050505050565b6060814281101561150f5760405162461bcd60e51b81526004016105a79061483a565b61151c8989898989612c02565b915061154589338760008151811061153057fe5b6020026020010151856000815181106110a157fe5b61155189838787612cf1565b50979650505050505050565b6033546001600160a01b031681565b6000814281101561158f5760405162461bcd60e51b81526004016105a79061483a565b6115998786612717565b5060006115a5876131c6565b611641576040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038816906370a08231906115ee9033906004016143fa565b60206040518083038186803b15801561160657600080fd5b505afa15801561161a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061163e9190614377565b90505b60005b89518110156116f1576000805b8b838151811061165d57fe5b6020026020010151518110156116db57611675613885565b8c848151811061168157fe5b6020026020010151828151811061169457fe5b6020026020010151905060008211156116af57606081018390525b6116d0816020015182604001518360000151846060015185608001516131eb565b925050600101611651565b506116e68186612ae5565b945050600101611644565b506116fd873385612521565b5061170c8833610fd48b612b08565b50611716876131c6565b15611740578483101561173b5760405162461bcd60e51b81526004016105a7906147cc565b61178f565b8461177182896001600160a01b03166370a08231336040518263ffffffff1660e01b8152600401610b8991906143fa565b101561178f5760405162461bcd60e51b81526004016105a7906146b9565b50509695505050505050565b6033546040517f14572adb00000000000000000000000000000000000000000000000000000000815260009182916001600160a01b03909116906314572adb906117ef908c908c908a908a9060040161459a565b602060405180830381600087803b15801561180957600080fd5b505af115801561181d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118419190613a9d565b9050611853818a8a8a8a6000806135d5565b50506040517f6a6278420000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636a6278429061189a9086906004016143fa565b602060405180830381600087803b1580156118b457600080fd5b505af11580156118c8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc39190614377565b6060814281101561190f5760405162461bcd60e51b81526004016105a79061483a565b61191d8a8a8a8a8a8a612f4e565b91506119318a338888600081811061107f57fe5b6119718a838888808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152508a9250612cf1915050565b5098975050505050505050565b60008082428110156119a25760405162461bcd60e51b81526004016105a79061483a565b6119b18b8b8b8b8b8b8b611db5565b909c909b509950505050505050505050565b600081428110156119e65760405162461bcd60e51b81526004016105a79061483a565b603554611a04908a908a906001600160a01b03168a8a8a308a61197e565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152909350611aaa9150899086906001600160a01b038316906370a0823190611a559030906004016143fa565b60206040518083038186803b158015611a6d57600080fd5b505afa158015611a81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa59190614377565b6130ca565b61112473eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee8584612521565b60608142811015611aec5760405162461bcd60e51b81526004016105a79061483a565b60355461106b908a906001600160a01b03168a8a8a8a612f4e565b60008060008342811015611b2d5760405162461bcd60e51b81526004016105a79061483a565b611b3c8d8d8d8d8d8d8d6135d5565b6040517f6a62784200000000000000000000000000000000000000000000000000000000815291955093506001600160a01b038e1690636a62784290611b869089906004016143fa565b602060405180830381600087803b158015611ba057600080fd5b505af1158015611bb4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bd89190614377565b91505099509950999650505050505050565b60608142811015611c0d5760405162461bcd60e51b81526004016105a79061483a565b6035546040805160208089028281018201909352888252611c59936001600160a01b0316928c9234928d928d918d918291850190849080828437600092019190915250612c0292505050565b9150611c6b826000815181106113c657fe5b6035546040805160208089028281018201909352888252611463936001600160a01b0316928692918b918b918291908501908490808284376000920191909152508a9250612cf1915050565b60355460009081908190611cdb908a908a906001600160a01b03168a348b8b613610565b9093509150611cec88338b866120a8565b611cf6828a6125de565b6040517f6a6278420000000000000000000000000000000000000000000000000000000081526001600160a01b038a1690636a62784290611d3b9087906004016143fa565b602060405180830381600087803b158015611d5557600080fd5b505af1158015611d69573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d8d9190614377565b905081341115611da357611da33383340361303d565b96509650969350505050565b303b1590565b6033546040517fe5e31b1300000000000000000000000000000000000000000000000000000000815260009182916001600160a01b039091169063e5e31b1390611e03908c906004016143fa565b60206040518083038186803b158015611e1b57600080fd5b505afa158015611e2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e53919061435b565b611e6f5760405162461bcd60e51b81526004016105a7906149e5565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b038a16906323b872dd90611eb89033908d908b9060040161444f565b602060405180830381600087803b158015611ed257600080fd5b505af1158015611ee6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f0a919061435b565b506000808a6001600160a01b03166389afcb44866040518263ffffffff1660e01b8152600401611f3a91906143fa565b6040805180830381600087803b158015611f5357600080fd5b505af1158015611f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8b919061438f565b6034546040517f544caa560000000000000000000000000000000000000000000000000000000081529294509092506000916001600160a01b039091169063544caa5690611fdf908e908e90600401614473565b604080518083038186803b158015611ff657600080fd5b505afa15801561200a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061202e9190613af1565b509050806001600160a01b03168b6001600160a01b031614612051578183612054565b82825b9095509350878510156120795760405162461bcd60e51b81526004016105a790614795565b868410156120995760405162461bcd60e51b81526004016105a790614727565b50505097509795505050505050565b60006060856001600160a01b03166323b872dd8686866040516024016120d09392919061444f565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161211e91906143de565b6000604051808303816000865af19150503d806000811461215b576040519150601f19603f3d011682016040523d82523d6000602084013e612160565b606091505b509150915081801561218a57508051158061218a57508080602001905181019061218a919061435b565b6121a65760405162461bcd60e51b81526004016105a790614988565b505050505050565b8260005b835181101561251a5760008482815181106121c957fe5b602002602001015190506000806000806000806000806000603460009054906101000a90046001600160a01b03166001600160a01b031663b33d96b0603360009054906101000a90046001600160a01b03168c8f6040518463ffffffff1660e01b815260040161223b9392919061448d565b60c06040518083038186803b15801561225357600080fd5b505afa158015612267573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228b919061410f565b9550955095509550955095506122c7858d6001600160a01b03166370a082318d6040518263ffffffff1660e01b8152600401610b8991906143fa565b6034546040517f671a11b5000000000000000000000000000000000000000000000000000000008152919a506001600160a01b03169063671a11b59061231b908c9089908990899089908990600401614a77565b60206040518083038186803b15801561233357600080fd5b505afa158015612347573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061236b9190614377565b9750859650505050505050600080856001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156123b257600080fd5b505afa1580156123c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ea9190613a9d565b6001600160a01b0316886001600160a01b03161461240a5783600061240e565b6000845b91509150600060018b51038810612425578961243d565b8a886001018151811061243457fe5b60200260200101515b604080516000815260208101918290527f022c0d9f000000000000000000000000000000000000000000000000000000009091529091506001600160a01b0388169063022c0d9f906124989086908690869060248101614a33565b600060405180830381600087803b1580156124b257600080fd5b505af11580156124c6573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c488786866040516124fd939291906145e4565b60405180910390a15091965050600190940193506121b292505050565b5050505050565b600081612530575060016125d7565b612539846131c6565b156125c8576035546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e1a7d4d90612587908590600401614a1c565b600060405180830381600087803b1580156125a157600080fd5b505af11580156125b5573d6000803e3d6000fd5b505050506125c3838361303d565b6125d3565b6125d38484846130ca565b5060015b9392505050565b603560009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561262e57600080fd5b505af1158015612642573d6000803e3d6000fd5b50506035546040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116935063a9059cbb92506126929150849086906004016145cb565b602060405180830381600087803b1580156126ac57600080fd5b505af11580156126c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126e4919061435b565b6126ea57fe5b5050565b808203828111156127115760405162461bcd60e51b81526004016105a79061464b565b92915050565b6000612722836131c6565b1561279557603560009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561277757600080fd5b505af115801561278b573d6000803e3d6000fd5b50505050506127a1565b6127a1833330856120a8565b50600192915050565b604080516001808252818301909252600091606091906020808301908036833701905050905085816000815181106127de57fe5b6001600160a01b0392831660209182029290920101526034546033546040517f67f84adc000000000000000000000000000000000000000000000000000000008152606093928316926367f84adc92612844929116908d908d908c908990600401614527565b60006040518083038186803b15801561285c57600080fd5b505afa158015612870573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261289891908101906142d7565b9050806000815181106128a757fe5b60200260200101519250848311156128d15760405162461bcd60e51b81526004016105a7906146f0565b61178f898885846001815181106128e457fe5b60200260200101515b6128f88484846130ca565b60008390506000816001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561293857600080fd5b505afa15801561294c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129709190613a9d565b90506000806000836001600160a01b0316896001600160a01b0316146129995785600085612a0d565b600086866001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156129d557600080fd5b505afa1580156129e9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a0d9190613a9d565b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915292955090935091506001600160a01b0386169063022c0d9f90612a6d9086908690309060248101614a33565b600060405180830381600087803b158015612a8757600080fd5b505af1158015612a9b573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c48888783604051612ad2939291906145e4565b60405180910390a1505050505050505050565b808201828110156127115760405162461bcd60e51b81526004016105a79061475e565b6000612b13826131c6565b15612bb8576035546040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b03909116906370a0823190612b619030906004016143fa565b60206040518083038186803b158015612b7957600080fd5b505afa158015612b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bb19190614377565b9050612bfd565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038316906370a0823190612b619030906004016143fa565b919050565b6034546033546040517f119220a50000000000000000000000000000000000000000000000000000000081526060926001600160a01b039081169263119220a592612c5b92909116908a908a908a908990600401614527565b60006040518083038186803b158015612c7357600080fd5b505afa158015612c87573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612caf91908101906142d7565b90508281600183510381518110612cc257fe5b60200260200101511015612ce85760405162461bcd60e51b81526004016105a7906148ce565b95945050505050565b8360005b83518110156121a6576000848281518110612d0c57fe5b602002602001015190506000816001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015612d5157600080fd5b505afa158015612d65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d899190613a9d565b90506000878460010181518110612d9c57fe5b602002602001015190506000806000846001600160a01b0316886001600160a01b031614612dcd5783600086612e41565b600084876001600160a01b031663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015612e0957600080fd5b505afa158015612e1d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e419190613a9d565b925092509250600060018b51038810612e5a5789612e72565b8a8860010181518110612e6957fe5b60200260200101515b604080516000815260208101918290527f022c0d9f000000000000000000000000000000000000000000000000000000009091529091506001600160a01b0388169063022c0d9f90612ecd9087908790869060248101614a33565b600060405180830381600087803b158015612ee757600080fd5b505af1158015612efb573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c48878684604051612f32939291906145e4565b60405180910390a15096505060019094019350612cf592505050565b6034546033546040517f67f84adc0000000000000000000000000000000000000000000000000000000081526060926001600160a01b03908116926367f84adc92612fa992909116908b908b908b908a908a906004016144b0565b60006040518083038186803b158015612fc157600080fd5b505afa158015612fd5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612ffd91908101906142d7565b9050838160008151811061300d57fe5b602002602001015111156130335760405162461bcd60e51b81526004016105a7906146f0565b9695505050505050565b604080516000808252602082019092526001600160a01b03841690839060405161306791906143de565b60006040518083038185875af1925050503d80600081146130a4576040519150601f19603f3d011682016040523d82523d6000602084013e6130a9565b606091505b50509050806107ae5760405162461bcd60e51b81526004016105a79061492b565b60006060846001600160a01b031663a9059cbb85856040516024016130f09291906145cb565b6040516020818303038152906040529060e01b6020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161313e91906143de565b6000604051808303816000865af19150503d806000811461317b576040519150601f19603f3d011682016040523d82523d6000602084013e613180565b606091505b50915091508180156131aa5750805115806131aa5750808060200190518101906131aa919061435b565b61251a5760405162461bcd60e51b81526004016105a790614682565b6001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14919050565b60006131f88685856130ca565b600080600080600080603460009054906101000a90046001600160a01b03166001600160a01b031663b33d96b0603360009054906101000a90046001600160a01b03168c8f6040518463ffffffff1660e01b815260040161325b9392919061448d565b60c06040518083038186803b15801561327357600080fd5b505afa158015613287573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132ab919061410f565b955095509550955095505060006132e8868e6001600160a01b03166370a082318e6040518263ffffffff1660e01b8152600401610b8991906143fa565b6034546040517f671a11b50000000000000000000000000000000000000000000000000000000081529192506001600160a01b03169063671a11b59061333c9084908a908a908a908a908a90600401614a77565b60206040518083038186803b15801561335457600080fd5b505afa158015613368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061338c9190614377565b96505050505050506000866001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016133c291906143fa565b60206040518083038186803b1580156133da57600080fd5b505afa1580156133ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134129190614377565b9050600080876001600160a01b0316630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561345057600080fd5b505afa158015613464573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134889190613a9d565b6001600160a01b03168a6001600160a01b0316146134a8578360006134ac565b6000845b604080516000815260208101918290527f022c0d9f0000000000000000000000000000000000000000000000000000000090915291935091506001600160a01b0389169063022c0d9f906135099085908590309060248101614a33565b600060405180830381600087803b15801561352357600080fd5b505af1158015613537573d6000803e3d6000fd5b505050507fddac40937f35385a34f721af292e5a83fc5b840f722bff57c2fc71adba708c4888858b60405161356e939291906145e4565b60405180910390a16135a6838a6001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401610b8991906143fa565b9450858510156135c85760405162461bcd60e51b81526004016105a7906148ce565b5050505095945050505050565b6000806135e789898989898989613610565b90925090506135f888338b856120a8565b61360487338b846120a8565b97509795505050505050565b6034546040517f327494610000000000000000000000000000000000000000000000000000000081526000918291829182916001600160a01b0390911690633274946190613666908e908e908e9060040161448d565b604080518083038186803b15801561367d57600080fd5b505afa158015613691573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136b5919061438f565b915091508160001480156136c7575080155b156136d7578793508692506114de565b6034546040517fad615dec0000000000000000000000000000000000000000000000000000000081526000916001600160a01b03169063ad615dec90613725908c9087908790600401614a61565b60206040518083038186803b15801561373d57600080fd5b505afa158015613751573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137759190614377565b90508781116137a9578581101561379e5760405162461bcd60e51b81526004016105a790614727565b889450925082612099565b6034546040517fad615dec0000000000000000000000000000000000000000000000000000000081526000916001600160a01b03169063ad615dec906137f7908c9087908990600401614a61565b60206040518083038186803b15801561380f57600080fd5b505afa158015613823573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138479190614377565b90508981111561385357fe5b878110156138735760405162461bcd60e51b81526004016105a790614795565b9c979b50969950505050505050505050565b6040518060c0016040528060006001600160a01b0316815260200160006001600160a01b0316815260200160006001600160a01b031681526020016000815260200160008152602001600081525090565b803561271181614b22565b60008083601f8401126138f2578182fd5b50813567ffffffffffffffff811115613909578182fd5b602083019150836020808302850101111561392357600080fd5b9250929050565b600082601f83011261393a578081fd5b813561394d61394882614ad2565b614aab565b818152915060208083019084810160005b848110156139ef578135870188603f82011261397957600080fd5b8381013561398961394882614ad2565b81815285810190604084810160c0808602870183018f10156139aa57600080fd5b600096505b858710156139d7576139c18f836139fa565b85526001969096019593890193908101906139af565b5050508752505050928201929082019060010161395e565b505050505092915050565b600060c08284031215613a0b578081fd5b613a1560c0614aab565b90508135613a2281614b22565b81526020820135613a3281614b22565b60208201526040820135613a4581614b22565b80604083015250606082013560608201526080820135608082015260a082013560a082015292915050565b803560ff8116811461271157600080fd5b600060208284031215613a92578081fd5b81356125d781614b22565b600060208284031215613aae578081fd5b81516125d781614b22565b60008060408385031215613acb578081fd5b8235613ad681614b22565b91506020830135613ae681614b22565b809150509250929050565b60008060408385031215613b03578182fd5b8251613b0e81614b22565b6020840151909250613ae681614b22565b600080600080600080600080610100898b031215613b3b578384fd5b8835613b4681614b22565b97506020890135613b5681614b22565b96506040890135613b6681614b22565b9550606089013594506080890135935060a0890135925060c0890135613b8b81614b22565b8092505060e089013590509295985092959890939650565b6000806000806000806000806000806000806101808d8f031215613bc5578586fd5b8c35613bd081614b22565b9b5060208d0135613be081614b22565b9a5060408d0135613bf081614b22565b995060608d0135985060808d0135975060a08d0135965060c08d0135613c1581614b22565b955060e08d013594506101008d0135613c2d81614b3a565b9350613c3d8e6101208f01613a70565b92506101408d013591506101608d013590509295989b509295989b509295989b565b60008060008060008060008060006101208a8c031215613c7d578283fd5b8935613c8881614b22565b985060208a0135613c9881614b22565b975060408a0135613ca881614b22565b965060608a0135955060808a0135945060a08a0135935060c08a0135925060e08a0135613cd481614b22565b809250506101008a013590509295985092959850929598565b60008060008060008060008060e0898b031215613d08578182fd5b8835613d1381614b22565b97506020890135613d2381614b22565b96506040890135955060608901359450608089013567ffffffffffffffff811115613d4c578283fd5b613d588b828c016138e1565b90955093505060a0890135613d6c81614b22565b8092505060c089013590509295985092959890939650565b600080600080600080600060e0888a031215613d9e578081fd5b8735613da981614b22565b9650602088810135613dba81614b22565b96506040890135955060608901359450608089013567ffffffffffffffff811115613de3578283fd5b8901601f81018b13613df3578283fd5b8035613e0161394882614ad2565b81815283810190838501858402850186018f1015613e1d578687fd5b8694505b83851015613e4757613e338f826138d6565b835260019490940193918501918501613e21565b508097505050505050613e5d8960a08a016138d6565b915060c0880135905092959891949750929550565b600080600080600080600060e0888a031215613e8c578081fd5b8735613e9781614b22565b96506020880135613ea781614b22565b955060408801359450606088013593506080880135925060a0880135613ecc81614b22565b8092505060c0880135905092959891949750929550565b60008060008060008060008060008060006101608c8e031215613f04578485fd5b8b35613f0f81614b22565b9a5060208c0135613f1f81614b22565b995060408c0135985060608c0135975060808c0135965060a08c0135613f4481614b22565b955060c08c0135945060e08c0135613f5b81614b3a565b9350613f6b8d6101008e01613a70565b92506101208c013591506101408c013590509295989b509295989b9093969950565b600080600080600080600060e0888a031215613fa7578081fd5b8735613fb281614b22565b96506020880135613fc281614b22565b955060408801359450606088013593506080880135613fe081614b48565b925060a0880135613ff081614b48565b915060c088013561400081614b22565b8091505092959891949750929550565b60008060008060008060a08789031215614028578384fd5b863561403381614b22565b955060208701359450604087013567ffffffffffffffff811115614055578485fd5b61406189828a016138e1565b909550935050606087013561407581614b22565b80925050608087013590509295509295509295565b600080600080600080600060c0888a0312156140a4578081fd5b87356140af81614b22565b96506020880135955060408801359450606088013567ffffffffffffffff8111156140d8578182fd5b6140e48a828b016138e1565b90955093505060808801356140f881614b22565b8092505060a0880135905092959891949750929550565b60008060008060008060c08789031215614127578384fd5b865161413281614b22565b809650506020870151945060408701519350606087015161415281614b48565b608088015190935061416381614b48565b60a088015190925061417481614b48565b809150509295509295509295565b600080600080600060a08688031215614199578283fd5b85356141a481614b22565b94506020860135935060408601356141bb81614b48565b925060608601356141cb81614b48565b915060808601356141db81614b22565b809150509295509295909350565b600080600080600060a08688031215614200578283fd5b853567ffffffffffffffff811115614216578384fd5b6142228882890161392a565b955050602086013561423381614b22565b9350604086013561424381614b22565b94979396509394606081013594506080013592915050565b60008060008060008060c08789031215614273578384fd5b863567ffffffffffffffff811115614289578485fd5b61429589828a0161392a565b96505060208701356142a681614b22565b945060408701356142b681614b22565b959894975094956060810135955060808101359460a0909101359350915050565b600060208083850312156142e9578182fd5b825167ffffffffffffffff8111156142ff578283fd5b8301601f8101851361430f578283fd5b805161431d61394882614ad2565b8181528381019083850185840285018601891015614339578687fd5b8694505b8385101561155157805183526001949094019391850191850161433d565b60006020828403121561436c578081fd5b81516125d781614b3a565b600060208284031215614388578081fd5b5051919050565b600080604083850312156143a1578182fd5b505080516020909101519092909150565b600081518084526143ca816020860160208601614af2565b601f01601f19169290920160200192915050565b600082516143f0818460208701614af2565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0397881681529590961660208601526040850193909352606084019190915260ff16608083015260a082015260c081019190915260e00190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b0393841681529183166020830152909116604082015260600190565b600060a082016001600160a01b03808a1684526020818a1681860152818916604086015287606086015260a060808601528286845260c086019050879350845b8781101561451757843561450381614b22565b8416825293820193908201906001016144f0565b509b9a5050505050505050505050565b600060a082016001600160a01b038089168452602081891681860152818816604086015286606086015260a0608086015282865180855260c0870191508288019450855b8181101561458957855185168352948301949183019160010161456b565b50909b9a5050505050505050505050565b6001600160a01b03948516815292909316602083015263ffffffff9081166040830152909116606082015260800190565b6001600160a01b03929092168252602082015260400190565b6001600160a01b0393841681526020810192909252909116604082015260600190565b6020808252825182820181905260009190848201906040850190845b8181101561463f57835183529284019291840191600101614623565b50909695505050505050565b60208082526015908201527f64732d6d6174682d7375622d756e646572666c6f770000000000000000000000604082015260600190565b6020808252601f908201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604082015260600190565b60208082526012908201527f3c6d696e546f74616c416d6f756e744f75740000000000000000000000000000604082015260600190565b6020808252601e908201527f526f757465723a204558434553534956455f494e5055545f414d4f554e540000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f425f414d4f554e54000000604082015260600190565b60208082526014908201527f64732d6d6174682d6164642d6f766572666c6f77000000000000000000000000604082015260600190565b6020808252601d908201527f526f757465723a20494e53554646494349454e545f415f414d4f554e54000000604082015260600190565b6020808252600d908201527f4552525f4c494d49545f4f555400000000000000000000000000000000000000604082015260600190565b6020808252600c908201527f4552525f4c494d49545f494e0000000000000000000000000000000000000000604082015260600190565b6020808252600f908201527f526f757465723a20455850495245440000000000000000000000000000000000604082015260600190565b6020808252602e908201527f436f6e747261637420696e7374616e63652068617320616c726561647920626560408201527f656e20696e697469616c697a6564000000000000000000000000000000000000606082015260800190565b60208082526022908201527f526f757465723a20494e53554646494349454e545f4f55545055545f414d4f5560408201527f4e54000000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526023908201527f5472616e7366657248656c7065723a204554485f5452414e534645525f46414960408201527f4c45440000000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526024908201527f5472616e7366657248656c7065723a205452414e534645525f46524f4d5f464160408201527f494c454400000000000000000000000000000000000000000000000000000000606082015260800190565b60208082526014908201527f526f757465723a20496e76616c69642070616972000000000000000000000000604082015260600190565b90815260200190565b918252602082015260400190565b60008582528460208301526001600160a01b03841660408301526080606083015261303360808301846143b2565b9283526020830191909152604082015260600190565b9586526020860194909452604085019290925263ffffffff908116606085015290811660808401521660a082015260c00190565b60405181810167ffffffffffffffff81118282101715614aca57600080fd5b604052919050565b600067ffffffffffffffff821115614ae8578081fd5b5060209081020190565b60005b83811015614b0d578181015183820152602001614af5565b83811115614b1c576000848401525b50505050565b6001600160a01b0381168114614b3757600080fd5b50565b8015158114614b3757600080fd5b63ffffffff81168114614b3757600080fdfea26469706673582212201adf749c483785f5e6b736c7f2a592310afcb0c0a731e70fce7cc95b8a37940b64736f6c634300060c0033

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.