Contract 0xBd13225f0a45BEad8510267B4D6a7c78146Be459 1

 
Ad
Ad
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x1f22263ccdca3bf88297df5b8cc39e202341c035592a225e391ba7c5d97c56d8Swap Exact Token...221753802021-12-05 19:50:0048 mins ago0x4e6903a8636a902a31e97121664d4ba55d66490e IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.003960608
0xe21731561e89ec5d30f7ef15bc7818bb6d9719352176cd15ff232dd22ae926c9Swap Exact ETH F...221742652021-12-05 19:07:221 hr 30 mins ago0x3652e8dde9bdba935fcc417a5735e9c258da8e41 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4597 MATIC0.00763168
0x29c2a1c1700bb71ab8fc21e505cd6eb72a48d554e0c1af1eb72ed3a9b6e816bdSwap ETH For Exa...221739252021-12-05 18:53:341 hr 44 mins ago0x908656245538dd99f8b1523225042d012ed10499 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590.769015095191654 MATIC0.003669376
0xa6adb03c2f1fb373ab57ab16238ef20e7e5f45ad432a6ba98d6887cfff7ea7fcSwap ETH For Exa...221739062021-12-05 18:52:561 hr 45 mins ago0x908656245538dd99f8b1523225042d012ed10499 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590.645971184758676 MATIC0.003669376
0x467a12c50b01e4b82f006e594492afc1550fae0d12dc08faa25ac8a309023730Swap Tokens For ...221733532021-12-05 18:31:592 hrs 6 mins ago0x908656245538dd99f8b1523225042d012ed10499 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.003623936
0x9f4c20fe652513c22db7833d44f8b9a2aac149cde3ea3f3c56ea11cb94512151Remove Liquidity...221732972021-12-05 18:29:352 hrs 8 mins ago0x908656245538dd99f8b1523225042d012ed10499 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.005233248
0x8dbf6b9ee92bf69d056931598717ca18aa1b83a9ea30b1807d0676efe72af090Swap Exact ETH F...221732502021-12-05 18:26:272 hrs 11 mins ago0x3652e8dde9bdba935fcc417a5735e9c258da8e41 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4597.5 MATIC0.005957728
0x9dbcb3cff431348df2c49d0f93cfadad6f1379af3478fe7f54c88e47503a42c5Execute Meta Tra...221732432021-12-05 18:26:032 hrs 11 mins ago0xb5dad764c4ad8f2b1a99d330046bdf71fbab1a9f IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.0182052
0x4ff9acfd56c4843460ec62f7b2b85436af50541e0da7e84ba91827787c53420dSwap Exact ETH F...221717502021-12-05 17:31:183 hrs 6 mins ago0x62a893ffc25f30e5b69c856433d953c8c25bc818 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4592.2 MATIC0.009372441
0x6e0c121e4c4ddfe299a75b334ff7e069425e89fa4feb5734516ffff5b98b0bdbSwap Exact ETH F...221716202021-12-05 17:25:023 hrs 12 mins ago0x62a893ffc25f30e5b69c856433d953c8c25bc818 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4592 MATIC0.00638703
0x60445ed2f09de32a1b42a8c66d9c8f7262767c301b98a80614028a306712a202Add Liquidity221702272021-12-05 16:32:324 hrs 5 mins ago0x76afd1f84eda8b262cd61996efcce78323be7c2e IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.005783712
0xc4113dedd21245916d81f6a7db4765d057bfae5699d5486c2197abe49c974e91Swap Exact ETH F...221702082021-12-05 16:31:544 hrs 6 mins ago0x76afd1f84eda8b262cd61996efcce78323be7c2e IN  0xbd13225f0a45bead8510267b4d6a7c78146be459191.678 MATIC0.003430752
0xb3528f4eeb2bdcbd574b60968ec841975e8f5d583b3f54097a8c5353ae9f6ea6Swap Exact Token...221701882021-12-05 16:31:144 hrs 6 mins ago0xf9069093d5cb0ca6c9b6c0e3138fbb6b6c734821 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.006228576
0x034fa432944b0c8321984cc158af52e29678f5935cc6927b7a609b81b8eeb1e8Swap Exact Token...221701762021-12-05 16:30:504 hrs 7 mins ago0xf9069093d5cb0ca6c9b6c0e3138fbb6b6c734821 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.00590416
0xdef5ace66ea899f48bd6575598fa0a80bfc7fef3bd36357137f496d3280dcbc0Swap Exact ETH F...221701372021-12-05 16:29:284 hrs 8 mins ago0xf9069093d5cb0ca6c9b6c0e3138fbb6b6c734821 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4597 MATIC0.00543568
0x145c90239298b06a0813066c2f0e832bca6e6efff16fc599cbfd4d3f04b76244Swap Exact Token...221701112021-12-05 16:28:324 hrs 9 mins ago0xf9069093d5cb0ca6c9b6c0e3138fbb6b6c734821 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.006228576
0xee82427127416381219229bc677651e521946c25adf7d0e8eb32c140b48aff46Swap Exact ETH F...221700812021-12-05 16:27:324 hrs 10 mins ago0xf9069093d5cb0ca6c9b6c0e3138fbb6b6c734821 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4597 MATIC0.003687072
0x1520a626152f6b7c4895b02011ca38ac1fd785ef4368ae06a0031d122de758a9Execute Meta Tra...221698182021-12-05 16:12:064 hrs 25 mins ago0x07c58a7fae9978ad9f0ac270ddaedc88e878f4ef IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.020585474
0xb4ed351f1094f6c9be658d9787576168cc725189c67526f82fece19620ecf469Execute Meta Tra...221697612021-12-05 16:10:084 hrs 27 mins ago0x4dad1f578aa8ee05a2aa343f9b158da5df060865 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.01922249
0xb77f531d8ee345b1a082a20a8be7ba5889f54450bb28d17a44a4977c2732055aAdd Liquidity221697592021-12-05 16:10:044 hrs 27 mins ago0x76afd1f84eda8b262cd61996efcce78323be7c2e IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.005558592
0x6f1b435c875b83489d7c328dd8a2302404c3717995e3349f83ec8dbf83773dadSwap Exact Token...221697172021-12-05 16:08:364 hrs 29 mins ago0x76afd1f84eda8b262cd61996efcce78323be7c2e IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.003960224
0xe2948acf0b7c254465f88f95e012ece318c18463faea16747b7b2bb2b6c3ed6cSwap Exact Token...221696302021-12-05 16:05:384 hrs 32 mins ago0x816ae4dcfa8e7177ebd22e530ffde887069a991a IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.004110016
0xec40d89c368a22bb7d8f8e62b59a4775d0ecca992aaa7bed89c6b24b7adb504fRemove Liquidity...221695462021-12-05 16:00:004 hrs 38 mins ago0x816ae4dcfa8e7177ebd22e530ffde887069a991a IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.00633056
0x0f164f8a11b7be7c6c7f3483ec32e55c76a8e66079fcc33020d67bc2fcdc6718Add Liquidity221687792021-12-05 15:30:465 hrs 7 mins ago0x047b8bce5f0472f3738f6c27443c7191145a3905 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590 MATIC0.01536568
0xee7b48df873d9e9ea026e2b5c94b2c90b2e62cb34dfea235ec1700a5bfcf5e40Swap Exact ETH F...221686402021-12-05 15:26:005 hrs 12 mins ago0x047b8bce5f0472f3738f6c27443c7191145a3905 IN  0xbd13225f0a45bead8510267b4d6a7c78146be4590.12 MATIC0.003429984
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x1f22263ccdca3bf88297df5b8cc39e202341c035592a225e391ba7c5d97c56d8221753802021-12-05 19:50:0048 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590x4e6903a8636a902a31e97121664d4ba55d66490e260.250409809659014427 MATIC
0x1f22263ccdca3bf88297df5b8cc39e202341c035592a225e391ba7c5d97c56d8221753802021-12-05 19:50:0048 mins ago Polygon: WMATIC Token 0xbd13225f0a45bead8510267b4d6a7c78146be459260.250409809659014427 MATIC
0xe21731561e89ec5d30f7ef15bc7818bb6d9719352176cd15ff232dd22ae926c9221742652021-12-05 19:07:221 hr 30 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token7 MATIC
0x29c2a1c1700bb71ab8fc21e505cd6eb72a48d554e0c1af1eb72ed3a9b6e816bd221739252021-12-05 18:53:341 hr 44 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590x908656245538dd99f8b1523225042d012ed104990.005319498518816262 MATIC
0x29c2a1c1700bb71ab8fc21e505cd6eb72a48d554e0c1af1eb72ed3a9b6e816bd221739252021-12-05 18:53:341 hr 44 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token0.763695596672838112 MATIC
0xa6adb03c2f1fb373ab57ab16238ef20e7e5f45ad432a6ba98d6887cfff7ea7fc221739062021-12-05 18:52:561 hr 45 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590x908656245538dd99f8b1523225042d012ed104990.004483982687025889 MATIC
0xa6adb03c2f1fb373ab57ab16238ef20e7e5f45ad432a6ba98d6887cfff7ea7fc221739062021-12-05 18:52:561 hr 45 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token0.641487202071651087 MATIC
0x467a12c50b01e4b82f006e594492afc1550fae0d12dc08faa25ac8a309023730221733532021-12-05 18:31:592 hrs 6 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590x908656245538dd99f8b1523225042d012ed1049930 MATIC
0x467a12c50b01e4b82f006e594492afc1550fae0d12dc08faa25ac8a309023730221733532021-12-05 18:31:592 hrs 6 mins ago Polygon: WMATIC Token 0xbd13225f0a45bead8510267b4d6a7c78146be45930 MATIC
0x9f4c20fe652513c22db7833d44f8b9a2aac149cde3ea3f3c56ea11cb94512151221732972021-12-05 18:29:352 hrs 8 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590x908656245538dd99f8b1523225042d012ed1049937.337424901640556444 MATIC
0x9f4c20fe652513c22db7833d44f8b9a2aac149cde3ea3f3c56ea11cb94512151221732972021-12-05 18:29:352 hrs 8 mins ago Polygon: WMATIC Token 0xbd13225f0a45bead8510267b4d6a7c78146be45937.337424901640556444 MATIC
0x8dbf6b9ee92bf69d056931598717ca18aa1b83a9ea30b1807d0676efe72af090221732502021-12-05 18:26:272 hrs 11 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token7.5 MATIC
0x4ff9acfd56c4843460ec62f7b2b85436af50541e0da7e84ba91827787c53420d221717502021-12-05 17:31:183 hrs 6 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token2.2 MATIC
0x6e0c121e4c4ddfe299a75b334ff7e069425e89fa4feb5734516ffff5b98b0bdb221716202021-12-05 17:25:023 hrs 12 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token2 MATIC
0xc4113dedd21245916d81f6a7db4765d057bfae5699d5486c2197abe49c974e91221702082021-12-05 16:31:544 hrs 6 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token191.678 MATIC
0xb3528f4eeb2bdcbd574b60968ec841975e8f5d583b3f54097a8c5353ae9f6ea6221701882021-12-05 16:31:144 hrs 6 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590xf9069093d5cb0ca6c9b6c0e3138fbb6b6c7348217.065858146845883064 MATIC
0xb3528f4eeb2bdcbd574b60968ec841975e8f5d583b3f54097a8c5353ae9f6ea6221701882021-12-05 16:31:144 hrs 6 mins ago Polygon: WMATIC Token 0xbd13225f0a45bead8510267b4d6a7c78146be4597.065858146845883064 MATIC
0xdef5ace66ea899f48bd6575598fa0a80bfc7fef3bd36357137f496d3280dcbc0221701372021-12-05 16:29:284 hrs 8 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token7 MATIC
0x145c90239298b06a0813066c2f0e832bca6e6efff16fc599cbfd4d3f04b76244221701112021-12-05 16:28:324 hrs 9 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590xf9069093d5cb0ca6c9b6c0e3138fbb6b6c7348216.971569693531551096 MATIC
0x145c90239298b06a0813066c2f0e832bca6e6efff16fc599cbfd4d3f04b76244221701112021-12-05 16:28:324 hrs 9 mins ago Polygon: WMATIC Token 0xbd13225f0a45bead8510267b4d6a7c78146be4596.971569693531551096 MATIC
0xee82427127416381219229bc677651e521946c25adf7d0e8eb32c140b48aff46221700812021-12-05 16:27:324 hrs 10 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be459 Polygon: WMATIC Token7 MATIC
0x6f1b435c875b83489d7c328dd8a2302404c3717995e3349f83ec8dbf83773dad221697172021-12-05 16:08:364 hrs 29 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590x76afd1f84eda8b262cd61996efcce78323be7c2e20.660206343488502545 MATIC
0x6f1b435c875b83489d7c328dd8a2302404c3717995e3349f83ec8dbf83773dad221697172021-12-05 16:08:364 hrs 29 mins ago Polygon: WMATIC Token 0xbd13225f0a45bead8510267b4d6a7c78146be45920.660206343488502545 MATIC
0xec40d89c368a22bb7d8f8e62b59a4775d0ecca992aaa7bed89c6b24b7adb504f221695462021-12-05 16:00:004 hrs 38 mins ago 0xbd13225f0a45bead8510267b4d6a7c78146be4590x816ae4dcfa8e7177ebd22e530ffde887069a991a84.640573152532693702 MATIC
0xec40d89c368a22bb7d8f8e62b59a4775d0ecca992aaa7bed89c6b24b7adb504f221695462021-12-05 16:00:004 hrs 38 mins ago Polygon: WMATIC Token 0xbd13225f0a45bead8510267b4d6a7c78146be45984.640573152532693702 MATIC
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PolydexRouter

Compiler Version
v0.7.6+commit.7338295f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 12 : PolydexRouter.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.7.6;


import './libraries/PolydexLibrary.sol';
import './libraries/SafeMath.sol';
import './libraries/TransferHelper.sol';
import './interfaces/IPolydexRouter.sol';
import './interfaces/IPolydexFactory.sol';
import './interfaces/IERC20.sol';
import './interfaces/IWETH.sol';
import './libraries/NativeMetaTransaction.sol';

contract PolydexRouter is IPolydexRouter, NativeMetaTransaction{
    using SafeMathPolydex for uint;

    address public immutable override factory;
    address public immutable override WETH;

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

    constructor(address _factory, address _WETH) {
        factory = _factory;
        WETH = _WETH;
        _initializeEIP712("PolydexRouter");
    }

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

    // **** ADD LIQUIDITY ****
    function _addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin
    ) internal virtual returns (uint amountA, uint amountB) {
        // create the pair if it doesn't exist yet
        if (IPolydexFactory(factory).getPair(tokenA, tokenB) == address(0)) {
            IPolydexFactory(factory).createPair(tokenA, tokenB);
        }
        (uint reserveA, uint reserveB) = PolydexLibrary.getReserves(factory, tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint amountBOptimal = PolydexLibrary.quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                require(amountBOptimal >= amountBMin, 'PolydexRouter: INSUFFICIENT_B_AMOUNT');
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint amountAOptimal = PolydexLibrary.quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                require(amountAOptimal >= amountAMin, 'PolydexRouter: INSUFFICIENT_A_AMOUNT');
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }
    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
        address sender = _msgSender();
        (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        address pair = PolydexLibrary.pairFor(factory, tokenA, tokenB);
        TransferHelper.safeTransferFrom(tokenA, sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, sender, pair, amountB);
        liquidity = IPolydexPair(pair).mint(to);
    }
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external virtual override payable ensure(deadline) returns (uint amountToken, uint amountETH, uint liquidity) {
        (amountToken, amountETH) = _addLiquidity(
            token,
            WETH,
            amountTokenDesired,
            msg.value,
            amountTokenMin,
            amountETHMin
        );
        address sender = _msgSender();
        address pair = PolydexLibrary.pairFor(factory, token, WETH);
        TransferHelper.safeTransferFrom(token, sender, pair, amountToken);
        IWETH(WETH).deposit{value: amountETH}();
        assert(IWETH(WETH).transfer(pair, amountETH));
        liquidity = IPolydexPair(pair).mint(to);
        // refund dust eth, if any
        if (msg.value > amountETH) TransferHelper.safeTransferETH(sender, msg.value - amountETH);
    }

    // **** REMOVE LIQUIDITY ****
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) public virtual override ensure(deadline) returns (uint amountA, uint amountB) {
        address pair = PolydexLibrary.pairFor(factory, tokenA, tokenB);
        IPolydexPair(pair).transferFrom(_msgSender(), pair, liquidity); // send liquidity to pair
        (uint amount0, uint amount1) = IPolydexPair(pair).burn(to);
        (address token0,) = PolydexLibrary.sortTokens(tokenA, tokenB);
        (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
        require(amountA >= amountAMin, 'PolydexRouter: INSUFFICIENT_A_AMOUNT');
        require(amountB >= amountBMin, 'PolydexRouter: INSUFFICIENT_B_AMOUNT');
    }
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) public virtual override ensure(deadline) returns (uint amountToken, uint amountETH) {
        (amountToken, amountETH) = removeLiquidity(
            token,
            WETH,
            liquidity,
            amountTokenMin,
            amountETHMin,
            address(this),
            deadline
        );
        TransferHelper.safeTransfer(token, to, amountToken);
        IWETH(WETH).withdraw(amountETH);
        TransferHelper.safeTransferETH(to, amountETH);
    }
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external virtual override returns (uint amountA, uint amountB) {
        address pair = PolydexLibrary.pairFor(factory, tokenA, tokenB);
        uint value = approveMax ? uint(-1) : liquidity;
        IPolydexPair(pair).permit(_msgSender(), address(this), value, deadline, v, r, s);
        (amountA, amountB) = removeLiquidity(tokenA, tokenB, liquidity, amountAMin, amountBMin, to, deadline);
    }
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external virtual override returns (uint amountToken, uint amountETH) {
        address pair = PolydexLibrary.pairFor(factory, token, WETH);
        uint value = approveMax ? uint(-1) : liquidity;
        IPolydexPair(pair).permit(_msgSender(), address(this), value, deadline, v, r, s);
        (amountToken, amountETH) = removeLiquidityETH(token, liquidity, amountTokenMin, amountETHMin, to, deadline);
    }

    // **** REMOVE LIQUIDITY (supporting fee-on-transfer tokens) ****
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) public virtual override ensure(deadline) returns (uint amountETH) {
        (, amountETH) = removeLiquidity(
            token,
            WETH,
            liquidity,
            amountTokenMin,
            amountETHMin,
            address(this),
            deadline
        );
        TransferHelper.safeTransfer(token, to, IERC20Polydex(token).balanceOf(address(this)));
        IWETH(WETH).withdraw(amountETH);
        TransferHelper.safeTransferETH(to, amountETH);
    }
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external virtual override returns (uint amountETH) {
        address pair = PolydexLibrary.pairFor(factory, token, WETH);
        uint value = approveMax ? uint(-1) : liquidity;
        IPolydexPair(pair).permit(_msgSender(), address(this), value, deadline, v, r, s);
        amountETH = removeLiquidityETHSupportingFeeOnTransferTokens(
            token, liquidity, amountTokenMin, amountETHMin, to, deadline
        );
    }

    // **** SWAP ****
    // requires the initial amount to have already been sent to the first pair
    function _swap(uint[] memory amounts, address[] memory path, address _to) internal virtual {
        for (uint i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = PolydexLibrary.sortTokens(input, output);
            uint amountOut = amounts[i + 1];
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0));
            address to = i < path.length - 2 ? PolydexLibrary.pairFor(factory, output, path[i + 2]) : _to;
            IPolydexPair(PolydexLibrary.pairFor(factory, input, output)).swap(
                amount0Out, amount1Out, to, new bytes(0)
            );
        }
    }
    
    
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) returns (uint[] memory amounts) {
        amounts = PolydexLibrary.getAmountsOut(factory, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'PolydexRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], _msgSender(), PolydexLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, to);
    }
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) returns (uint[] memory amounts) {
        amounts = PolydexLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= amountInMax, 'PolydexRouter: EXCESSIVE_INPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], _msgSender(), PolydexLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, to);
    }
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        virtual
        override
        payable
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[0] == WETH, 'PolydexRouter: INVALID_PATH');
        amounts = PolydexLibrary.getAmountsOut(factory, msg.value, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'PolydexRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(IWETH(WETH).transfer(PolydexLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
        _swap(amounts, path, to);
    }
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        virtual
        override
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[path.length - 1] == WETH, 'PolydexRouter: INVALID_PATH');
        amounts = PolydexLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= amountInMax, 'PolydexRouter: EXCESSIVE_INPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], _msgSender(), PolydexLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, address(this));
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
    }
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        virtual
        override
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[path.length - 1] == WETH, 'PolydexRouter: INVALID_PATH');
        amounts = PolydexLibrary.getAmountsOut(factory, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, 'PolydexRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        TransferHelper.safeTransferFrom(
            path[0], _msgSender(), PolydexLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, address(this));
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferETH(to, amounts[amounts.length - 1]);
    }
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        virtual
        override
        payable
        ensure(deadline)
        returns (uint[] memory amounts)
    {
        require(path[0] == WETH, 'PolydexRouter: INVALID_PATH');
        amounts = PolydexLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= msg.value, 'PolydexRouter: EXCESSIVE_INPUT_AMOUNT');
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(IWETH(WETH).transfer(PolydexLibrary.pairFor(factory, path[0], path[1]), amounts[0]));
        _swap(amounts, path, to);
        // refund dust eth, if any
        if (msg.value > amounts[0]) TransferHelper.safeTransferETH(_msgSender(), msg.value - amounts[0]);
    }

    // **** SWAP (supporting fee-on-transfer tokens) ****
    // requires the initial amount to have already been sent to the first pair
    function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to) internal virtual {
        for (uint i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = PolydexLibrary.sortTokens(input, output);
            IPolydexPair pair = IPolydexPair(PolydexLibrary.pairFor(factory, input, output));
            uint amountInput;
            uint amountOutput;
            { // scope to avoid stack too deep errors
            (uint reserve0, uint reserve1,) = pair.getReserves();
            (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
            amountInput = IERC20Polydex(input).balanceOf(address(pair)).sub(reserveInput);
            amountOutput = PolydexLibrary.getAmountOut(amountInput, reserveInput, reserveOutput);
            }
            (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0));
            address to = i < path.length - 2 ? PolydexLibrary.pairFor(factory, output, path[i + 2]) : _to;
            pair.swap(amount0Out, amount1Out, to, new bytes(0));
        }
    }
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external virtual override ensure(deadline) {
        TransferHelper.safeTransferFrom(
            path[0], _msgSender(), PolydexLibrary.pairFor(factory, path[0], path[1]), amountIn
        );
        uint balanceBefore = IERC20Polydex(path[path.length - 1]).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(path, to);
        require(
            IERC20Polydex(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin,
            'PolydexRouter: INSUFFICIENT_OUTPUT_AMOUNT'
        );
    }
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    )
        external
        virtual
        override
        payable
        ensure(deadline)
    {
        require(path[0] == WETH, 'PolydexRouter: INVALID_PATH');
        uint amountIn = msg.value;
        IWETH(WETH).deposit{value: amountIn}();
        assert(IWETH(WETH).transfer(PolydexLibrary.pairFor(factory, path[0], path[1]), amountIn));
        uint balanceBefore = IERC20Polydex(path[path.length - 1]).balanceOf(to);
        _swapSupportingFeeOnTransferTokens(path, to);
        require(
            IERC20Polydex(path[path.length - 1]).balanceOf(to).sub(balanceBefore) >= amountOutMin,
            'PolydexRouter: INSUFFICIENT_OUTPUT_AMOUNT'
        );
    }
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    )
        external
        virtual
        override
        ensure(deadline)
    {
        require(path[path.length - 1] == WETH, 'PolydexRouter: INVALID_PATH');
        TransferHelper.safeTransferFrom(
            path[0], _msgSender(), PolydexLibrary.pairFor(factory, path[0], path[1]), amountIn
        );
        _swapSupportingFeeOnTransferTokens(path, address(this));
        uint amountOut = IERC20Polydex(WETH).balanceOf(address(this));
        require(amountOut >= amountOutMin, 'PolydexRouter: INSUFFICIENT_OUTPUT_AMOUNT');
        IWETH(WETH).withdraw(amountOut);
        TransferHelper.safeTransferETH(to, amountOut);
    }

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

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

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

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

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

File 2 of 12 : PolydexLibrary.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

import '../interfaces/IPolydexPair.sol';

import "./SafeMath.sol";

library PolydexLibrary {
    using SafeMathPolydex for uint;

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

    // calculates the CREATE2 address for a pair without making any external calls
    function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
        (address token0, address token1) = sortTokens(tokenA, tokenB);
        pair = address(uint(keccak256(abi.encodePacked(
                hex'ff',
                factory,
                keccak256(abi.encodePacked(token0, token1)),
                hex'8cb41b27c88f8934c0773207afb757d84c4baa607990ad4a30505e42438d999a' // init code hash
            ))));
    }

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

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

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

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

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

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

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

pragma solidity =0.7.6;

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

library SafeMathPolydex {
    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');
    }
}

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

pragma solidity >=0.6.0;

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

File 5 of 12 : IPolydexRouter.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

interface IPolydexRouter {
    function factory() external view returns (address);
    function WETH() external view returns (address);

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    function addLiquidityETH(
        address token,
        uint amountTokenDesired,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETH(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityWithPermit(
        address tokenA,
        address tokenB,
        uint liquidity,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountA, uint amountB);
    function removeLiquidityETHWithPermit(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountToken, uint amountETH);
    function removeLiquidityETHSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline
    ) external returns (uint amountETH);
    function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
        address token,
        uint liquidity,
        uint amountTokenMin,
        uint amountETHMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external returns (uint amountETH);
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
        external
        returns (uint[] memory amounts);
    function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
        external
        payable
        returns (uint[] memory amounts);
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable;
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint amountIn,
        uint amountOutMin,
        address[] calldata path,
        address to,
        uint deadline
    ) external;

    function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
    function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
    function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
    function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}

File 6 of 12 : IPolydexFactory.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

interface IPolydexFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);
    function migrator() external view returns (address);

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

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

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
    function setMigrator(address) external;
}

File 7 of 12 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

interface IERC20Polydex {
    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 8 of 12 : IWETH.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

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

File 9 of 12 : NativeMetaTransaction.sol
pragma solidity >= 0.6.6;

import './EIP712Base.sol';
import './SafeMath.sol';


contract NativeMetaTransaction is EIP712Base {
    using SafeMathPolydex for uint;
    bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256(
        bytes(
            "MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
        )
    );
    event MetaTransactionExecuted(
        address userAddress,
        address payable relayerAddress,
        bytes functionSignature
    );
    mapping(address => uint256) nonces;

    /*
     * Meta transaction structure.
     * No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
     * He should call the desired function directly in that case.
     */
    struct MetaTransaction {
        uint256 nonce;
        address from;
        bytes functionSignature;
    }

    function executeMetaTransaction(
        address userAddress,
        bytes memory functionSignature,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) public payable returns (bytes memory) {
        MetaTransaction memory metaTx = MetaTransaction({
            nonce: nonces[userAddress],
            from: userAddress,
            functionSignature: functionSignature
        });

        require(
            verify(userAddress, metaTx, sigR, sigS, sigV),
            "Signer and signature do not match"
        );

        // increase nonce for user (to avoid re-use)
        nonces[userAddress] = nonces[userAddress].add(1);

        emit MetaTransactionExecuted(
            userAddress,
            msg.sender,
            functionSignature
        );

        // Append userAddress and relayer address at the end to extract it from calling context
        (bool success, bytes memory returnData) = address(this).call(
            abi.encodePacked(functionSignature, userAddress)
        );
        require(success, "Function call not successful");

        return returnData;
    }

    function hashMetaTransaction(MetaTransaction memory metaTx)
        internal
        pure
        returns (bytes32)
    {
        return
            keccak256(
                abi.encode(
                    META_TRANSACTION_TYPEHASH,
                    metaTx.nonce,
                    metaTx.from,
                    keccak256(metaTx.functionSignature)
                )
            );
    }

    function getNonce(address user) public view returns (uint256 nonce) {
        nonce = nonces[user];
    }

    function verify(
        address signer,
        MetaTransaction memory metaTx,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) internal view returns (bool) {
        require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER");
        return
            signer ==
            ecrecover(
                toTypedMessageHash(hashMetaTransaction(metaTx)),
                sigV,
                sigR,
                sigS
            );
    }

    function _msgSender() internal view returns (address payable sender) {
        if(msg.sender == address(this)) {
            bytes memory array = msg.data;
            uint256 index = msg.data.length;
            assembly {
                // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
                sender := and(mload(add(array, index)), 0xffffffffffffffffffffffffffffffffffffffff)
            }
        } else {
            sender = msg.sender;
        }
        return sender;
    }

}

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

pragma solidity >=0.6.0 <0.8.0;

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

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

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

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

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

    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 price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() 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) external;
}

File 11 of 12 : EIP712Base.sol
pragma solidity >= 0.6.6;

import './Initializable.sol';

contract EIP712Base is Initializable {
    struct EIP712Domain {
        string name;
        string version;
        address verifyingContract;
        uint256 chainId;
    }

    string constant public ERC712_VERSION = "1";

    bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(
        bytes(
            "EIP712Domain(string name,string version,address verifyingContract,uint256 chainId)"
        )
    );
    bytes32 internal domainSeperator;

    // supposed to be called once while initializing.
    // one of the contractsa that inherits this contract follows proxy pattern
    // so it is not possible to do this in a constructor
    function _initializeEIP712(
        string memory name
    )
        internal
        initializer
    {
        _setDomainSeperator(name);
    }

    function _setDomainSeperator(string memory name) internal {
        domainSeperator = keccak256(
            abi.encode(
                EIP712_DOMAIN_TYPEHASH,
                keccak256(bytes(name)),
                keccak256(bytes(ERC712_VERSION)),
                address(this),
                getChainId()
            )
        );
    }

    function getDomainSeperator() public view returns (bytes32) {
        return domainSeperator;
    }

    function getChainId() public pure returns (uint256) {
        uint256 id;
        assembly {
            id := chainid()
        }
        return id;
    }

    /**
     * Accept message hash and returns hash message in EIP712 compatible form
     * So that it can be used to recover signer from signature signed using EIP712 formatted data
     * https://eips.ethereum.org/EIPS/eip-712
     * "\\x19" makes the encoding deterministic
     * "\\x01" is the version byte to make it compatible to EIP-191
     */
    function toTypedMessageHash(bytes32 messageHash)
        internal
        view
        returns (bytes32)
    {
        return
            keccak256(
                abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash)
            );
    }
}

File 12 of 12 : Initializable.sol
pragma solidity >= 0.6.6;

contract Initializable {
    bool inited = false;

    modifier initializer() {
        require(!inited, "already inited");
        _;
        inited = true;
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address payable","name":"relayerAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","type":"event"},{"inputs":[],"name":"ERC712_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes","name":"functionSignature","type":"bytes"},{"internalType":"bytes32","name":"sigR","type":"bytes32"},{"internalType":"bytes32","name":"sigS","type":"bytes32"},{"internalType":"uint8","name":"sigV","type":"uint8"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getDomainSeperator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermit","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityWithPermit","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040526000805460ff191690553480156200001b57600080fd5b506040516200511c3803806200511c833981810160405260408110156200004157600080fd5b5080516020918201516001600160601b0319606083811b821660805282901b1660a05260408051808201909152600d81526c2837b63cb232bc2937baba32b960991b93810193909352909162000097906200009f565b5050620001ca565b60005460ff1615620000e9576040805162461bcd60e51b815260206004820152600e60248201526d185b1c9958591e481a5b9a5d195960921b604482015290519081900360640190fd5b620000f48162000104565b506000805460ff19166001179055565b604051806080016040528060528152602001620050ca6052913980516020918201208251838301206040805180820190915260018152603160f81b930192909252907fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc63062000172620001c6565b60405160200180868152602001858152602001848152602001836001600160a01b03168152602001828152602001955050505050506040516020818303038152906040528051906020012060018190555050565b4690565b60805160601c60a05160601c614dd2620002f8600039806101cd5280610f715280610fac52806113c252806115e752806119aa5280611b105280611eda5280611fb5528061208f528061215d52806122a3528061232b528061256752806125e25280612696528061276252806127f7528061286b5280612d645280612fef5280613051528061308552806130f9528061328852806133cb5280613453525080611450528061152e52806116ad52806116ec528061185a5280611a385280611aee5280611c7952806121f0528061235d52806124b7528061289d5280612adb5280612ce95280612d125280612d425280612ecf528061302f528061331b52806134855280613e395280613e7c528061415652806142cc52806146bd528061477652806148295250614dd26000f3fe6080604052600436106101c65760003560e01c8063791ac947116100f7578063b6f9de9511610095578063ded9382a11610064578063ded9382a14610d0a578063e8e3370014610d7d578063f305d71914610dfd578063fb3bdb4114610e435761020f565b8063b6f9de9514610b5f578063baa2abde14610be3578063c45a015514610c40578063d06ca61f14610c555761020f565b80638803dbee116100d15780638803dbee14610a0f578063ad5c464814610aa5578063ad615dec14610ad6578063af2979eb14610b0c5761020f565b8063791ac947146108bf5780637ff36ab51461095557806385f8c259146109d95761020f565b80632195995c1161016457806338ed17391161013e57806338ed17391461068a5780634a25d94a146107205780635b0d5984146107b65780635c11d795146108295761020f565b80632195995c146105c45780632d0335ab146106425780633408e470146106755761020f565b80630f7e5970116101a05780630f7e5970146103ff57806318cbafe5146104145780631f00ca74146104fa57806320379ee5146105af5761020f565b806302751cec14610214578063054d50d4146102805780630c53c51c146102c85761020f565b3661020f577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166101fd610ec7565b6001600160a01b03161461020d57fe5b005b600080fd5b34801561022057600080fd5b50610267600480360360c081101561023757600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135610f24565b6040805192835260208301919091528051918290030190f35b34801561028c57600080fd5b506102b6600480360360608110156102a357600080fd5b508035906020810135906040013561103e565b60408051918252519081900360200190f35b61038a600480360360a08110156102de57600080fd5b6001600160a01b038235169190810190604081016020820135600160201b81111561030857600080fd5b82018360208201111561031a57600080fd5b803590602001918460018302840111600160201b8311171561033b57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550508235935050506020810135906040013560ff16611053565b6040805160208082528351818301528351919283929083019185019080838360005b838110156103c45781810151838201526020016103ac565b50505050905090810190601f1680156103f15780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561040b57600080fd5b5061038a611355565b34801561042057600080fd5b506104aa600480360360a081101561043757600080fd5b813591602081013591810190606081016040820135600160201b81111561045d57600080fd5b82018360208201111561046f57600080fd5b803590602001918460208302840111600160201b8311171561049057600080fd5b91935091506001600160a01b038135169060200135611372565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156104e65781810151838201526020016104ce565b505050509050019250505060405180910390f35b34801561050657600080fd5b506104aa6004803603604081101561051d57600080fd5b81359190810190604081016020820135600160201b81111561053e57600080fd5b82018360208201111561055057600080fd5b803590602001918460208302840111600160201b8311171561057157600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506116a6945050505050565b3480156105bb57600080fd5b506102b66116dc565b3480156105d057600080fd5b5061026760048036036101608110156105e857600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c08101359060e081013515159060ff61010082013516906101208101359061014001356116e2565b34801561064e57600080fd5b506102b66004803603602081101561066557600080fd5b50356001600160a01b03166117f0565b34801561068157600080fd5b506102b661180b565b34801561069657600080fd5b506104aa600480360360a08110156106ad57600080fd5b813591602081013591810190606081016040820135600160201b8111156106d357600080fd5b8201836020820111156106e557600080fd5b803590602001918460208302840111600160201b8311171561070657600080fd5b91935091506001600160a01b03813516906020013561180f565b34801561072c57600080fd5b506104aa600480360360a081101561074357600080fd5b813591602081013591810190606081016040820135600160201b81111561076957600080fd5b82018360208201111561077b57600080fd5b803590602001918460208302840111600160201b8311171561079c57600080fd5b91935091506001600160a01b03813516906020013561195a565b3480156107c257600080fd5b506102b660048036036101408110156107da57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e08201351690610100810135906101200135611ae6565b34801561083557600080fd5b5061020d600480360360a081101561084c57600080fd5b813591602081013591810190606081016040820135600160201b81111561087257600080fd5b82018360208201111561088457600080fd5b803590602001918460208302840111600160201b831117156108a557600080fd5b91935091506001600160a01b038135169060200135611c08565b3480156108cb57600080fd5b5061020d600480360360a08110156108e257600080fd5b813591602081013591810190606081016040820135600160201b81111561090857600080fd5b82018360208201111561091a57600080fd5b803590602001918460208302840111600160201b8311171561093b57600080fd5b91935091506001600160a01b038135169060200135611e8c565b6104aa6004803603608081101561096b57600080fd5b81359190810190604081016020820135600160201b81111561098c57600080fd5b82018360208201111561099e57600080fd5b803590602001918460208302840111600160201b831117156109bf57600080fd5b91935091506001600160a01b038135169060200135612115565b3480156109e557600080fd5b506102b6600480360360608110156109fc57600080fd5b508035906020810135906040013561245f565b348015610a1b57600080fd5b506104aa600480360360a0811015610a3257600080fd5b813591602081013591810190606081016040820135600160201b811115610a5857600080fd5b820183602082011115610a6a57600080fd5b803590602001918460208302840111600160201b83111715610a8b57600080fd5b91935091506001600160a01b03813516906020013561246c565b348015610ab157600080fd5b50610aba612565565b604080516001600160a01b039092168252519081900360200190f35b348015610ae257600080fd5b506102b660048036036060811015610af957600080fd5b5080359060208101359060400135612589565b348015610b1857600080fd5b506102b6600480360360c0811015610b2f57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135612596565b61020d60048036036080811015610b7557600080fd5b81359190810190604081016020820135600160201b811115610b9657600080fd5b820183602082011115610ba857600080fd5b803590602001918460208302840111600160201b83111715610bc957600080fd5b91935091506001600160a01b03813516906020013561271c565b348015610bef57600080fd5b50610267600480360360e0811015610c0657600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359091169060c00135612a8d565b348015610c4c57600080fd5b50610aba612ce7565b348015610c6157600080fd5b506104aa60048036036040811015610c7857600080fd5b81359190810190604081016020820135600160201b811115610c9957600080fd5b820183602082011115610cab57600080fd5b803590602001918460208302840111600160201b83111715610ccc57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550612d0b945050505050565b348015610d1657600080fd5b506102676004803603610140811015610d2e57600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a08101359060c081013515159060ff60e08201351690610100810135906101200135612d38565b348015610d8957600080fd5b50610ddf6004803603610100811015610da157600080fd5b506001600160a01b038135811691602081013582169160408201359160608101359160808201359160a08101359160c0820135169060e00135612e60565b60408051938452602084019290925282820152519081900360600190f35b610ddf600480360360c0811015610e1357600080fd5b506001600160a01b0381358116916020810135916040820135916060810135916080820135169060a00135612fa0565b6104aa60048036036080811015610e5957600080fd5b81359190810190604081016020820135600160201b811115610e7a57600080fd5b820183602082011115610e8c57600080fd5b803590602001918460208302840111600160201b83111715610ead57600080fd5b91935091506001600160a01b038135169060200135613240565b600033301415610f1e57600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b03169150610f219050565b50335b90565b6000808242811015610f6b576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b610f9a897f00000000000000000000000000000000000000000000000000000000000000008a8a8a308a612a8d565b9093509150610faa8986856135c0565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561101057600080fd5b505af1158015611024573d6000803e3d6000fd5b505050506110328583613729565b50965096945050505050565b600061104b848484613821565b949350505050565b60408051606081810183526001600160a01b0388166000818152600260209081529085902054845283015291810186905261109187828787876138f9565b6110cc5760405162461bcd60e51b8152600401808060200182810382526021815260200180614ca86021913960400191505060405180910390fd5b6001600160a01b0387166000908152600260205260409020546110f09060016139d3565b60026000896001600160a01b03166001600160a01b03168152602001908152602001600020819055507f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b87338860405180846001600160a01b03168152602001836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611198578181015183820152602001611180565b50505050905090810190601f1680156111c55780820380516001836020036101000a031916815260200191505b5094505050505060405180910390a1600080306001600160a01b0316888a6040516020018083805190602001908083835b602083106112155780518252601f1990920191602091820191016111f6565b6001836020036101000a038019825116818451168082178552505050505050905001826001600160a01b031660601b8152601401925050506040516020818303038152906040526040518082805190602001908083835b6020831061128b5780518252601f19909201916020918201910161126c565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146112ed576040519150601f19603f3d011682016040523d82523d6000602084013e6112f2565b606091505b509150915081611349576040805162461bcd60e51b815260206004820152601c60248201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604482015290519081900360640190fd5b98975050505050505050565b604051806040016040528060018152602001603160f81b81525081565b606081428110156113b8576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016868660001981018181106113f257fe5b905060200201356001600160a01b03166001600160a01b03161461144b576040805162461bcd60e51b815260206004820152601b6024820152600080516020614d39833981519152604482015290519081900360640190fd5b6114a97f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613a2292505050565b915086826001845103815181106114bc57fe5b602002602001015110156115015760405162461bcd60e51b8152600401808060200182810382526029815260200180614b5e6029913960400191505060405180910390fd5b6115a68686600081811061151157fe5b905060200201356001600160a01b0316611529610ec7565b61158c7f00000000000000000000000000000000000000000000000000000000000000008a8a600081811061155a57fe5b905060200201356001600160a01b03168b8b600181811061157757fe5b905060200201356001600160a01b0316613b6e565b8560008151811061159957fe5b6020026020010151613c2e565b6115e582878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613d8a915050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d8360018551038151811061162457fe5b60200260200101516040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561166257600080fd5b505af1158015611676573d6000803e3d6000fd5b5050505061169b848360018551038151811061168e57fe5b6020026020010151613729565b509695505050505050565b60606116d37f00000000000000000000000000000000000000000000000000000000000000008484613fc7565b90505b92915050565b60015490565b60008060006117127f00000000000000000000000000000000000000000000000000000000000000008f8f613b6e565b9050600087611721578c611725565b6000195b9050816001600160a01b031663d505accf61173e610ec7565b604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015230602483015260448201859052606482018d905260ff8b16608483015260a482018a905260c482018990525160e480830192600092919082900301818387803b1580156117af57600080fd5b505af11580156117c3573d6000803e3d6000fd5b505050506117d68f8f8f8f8f8f8f612a8d565b809450819550505050509b509b9950505050505050505050565b6001600160a01b031660009081526002602052604090205490565b4690565b60608142811015611855576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b6118b37f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613a2292505050565b915086826001845103815181106118c657fe5b6020026020010151101561190b5760405162461bcd60e51b8152600401808060200182810382526029815260200180614b5e6029913960400191505060405180910390fd5b61191b8686600081811061151157fe5b61169b82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d8a915050565b606081428110156119a0576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016868660001981018181106119da57fe5b905060200201356001600160a01b03166001600160a01b031614611a33576040805162461bcd60e51b815260206004820152601b6024820152600080516020614d39833981519152604482015290519081900360640190fd5b611a917f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613fc792505050565b91508682600081518110611aa157fe5b602002602001015111156115015760405162461bcd60e51b8152600401808060200182810382526025815260200180614bed6025913960400191505060405180910390fd5b600080611b347f00000000000000000000000000000000000000000000000000000000000000008d7f0000000000000000000000000000000000000000000000000000000000000000613b6e565b9050600086611b43578b611b47565b6000195b9050816001600160a01b031663d505accf611b60610ec7565b604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015230602483015260448201859052606482018c905260ff8a16608483015260a4820189905260c482018890525160e480830192600092919082900301818387803b158015611bd157600080fd5b505af1158015611be5573d6000803e3d6000fd5b50505050611bf78d8d8d8d8d8d612596565b9d9c50505050505050505050505050565b8042811015611c4c576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b611cc885856000818110611c5c57fe5b905060200201356001600160a01b0316611c74610ec7565b611cc27f000000000000000000000000000000000000000000000000000000000000000089896000818110611ca557fe5b905060200201356001600160a01b03168a8a600181811061157757fe5b8a613c2e565b600085856000198101818110611cda57fe5b905060200201356001600160a01b03166001600160a01b03166370a08231856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611d3657600080fd5b505afa158015611d4a573d6000803e3d6000fd5b505050506040513d6020811015611d6057600080fd5b50516040805160208881028281018201909352888252929350611da29290918991899182918501908490808284376000920191909152508892506140ff915050565b86611e458288886000198101818110611db757fe5b905060200201356001600160a01b03166001600160a01b03166370a08231886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611e1357600080fd5b505afa158015611e27573d6000803e3d6000fd5b505050506040513d6020811015611e3d57600080fd5b505190614401565b1015611e825760405162461bcd60e51b8152600401808060200182810382526029815260200180614b5e6029913960400191505060405180910390fd5b5050505050505050565b8042811015611ed0576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001685856000198101818110611f0a57fe5b905060200201356001600160a01b03166001600160a01b031614611f63576040805162461bcd60e51b815260206004820152601b6024820152600080516020614d39833981519152604482015290519081900360640190fd5b611f7385856000818110611c5c57fe5b611fb18585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152503092506140ff915050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561202057600080fd5b505afa158015612034573d6000803e3d6000fd5b505050506040513d602081101561204a57600080fd5b505190508681101561208d5760405162461bcd60e51b8152600401808060200182810382526029815260200180614b5e6029913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156120f357600080fd5b505af1158015612107573d6000803e3d6000fd5b50505050611e828482613729565b6060814281101561215b576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168686600081811061219257fe5b905060200201356001600160a01b03166001600160a01b0316146121eb576040805162461bcd60e51b815260206004820152601b6024820152600080516020614d39833981519152604482015290519081900360640190fd5b6122497f000000000000000000000000000000000000000000000000000000000000000034888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613a2292505050565b9150868260018451038151811061225c57fe5b602002602001015110156122a15760405162461bcd60e51b8152600401808060200182810382526029815260200180614b5e6029913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0836000815181106122dd57fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561231057600080fd5b505af1158015612324573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6123897f000000000000000000000000000000000000000000000000000000000000000089896000818110611ca557fe5b8460008151811061239657fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b1580156123e457600080fd5b505af11580156123f8573d6000803e3d6000fd5b505050506040513d602081101561240e57600080fd5b505161241657fe5b61245582878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d8a915050565b5095945050505050565b600061104b848484614451565b606081428110156124b2576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b6125107f000000000000000000000000000000000000000000000000000000000000000089888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613fc792505050565b9150868260008151811061252057fe5b6020026020010151111561190b5760405162461bcd60e51b8152600401808060200182810382526025815260200180614bed6025913960400191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000081565b600061104b848484614529565b600081428110156125dc576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b61260b887f00000000000000000000000000000000000000000000000000000000000000008989893089612a8d565b90508092505061269488858a6001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561266357600080fd5b505afa158015612677573d6000803e3d6000fd5b505050506040513d602081101561268d57600080fd5b50516135c0565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b1580156126fa57600080fd5b505af115801561270e573d6000803e3d6000fd5b5050505061169b8483613729565b8042811015612760576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168585600081811061279757fe5b905060200201356001600160a01b03166001600160a01b0316146127f0576040805162461bcd60e51b815260206004820152601b6024820152600080516020614d39833981519152604482015290519081900360640190fd5b60003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561285057600080fd5b505af1158015612864573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6128c97f000000000000000000000000000000000000000000000000000000000000000089896000818110611ca557fe5b836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561291057600080fd5b505af1158015612924573d6000803e3d6000fd5b505050506040513d602081101561293a57600080fd5b505161294257fe5b60008686600019810181811061295457fe5b905060200201356001600160a01b03166001600160a01b03166370a08231866040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156129b057600080fd5b505afa1580156129c4573d6000803e3d6000fd5b505050506040513d60208110156129da57600080fd5b50516040805160208981028281018201909352898252929350612a1c9290918a918a9182918501908490808284376000920191909152508992506140ff915050565b87611e458289896000198101818110612a3157fe5b905060200201356001600160a01b03166001600160a01b03166370a08231896040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611e1357600080fd5b6000808242811015612ad4576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b6000612b017f00000000000000000000000000000000000000000000000000000000000000008c8c613b6e565b9050806001600160a01b03166323b872dd612b1a610ec7565b838c6040518463ffffffff1660e01b815260040180846001600160a01b03168152602001836001600160a01b031681526020018281526020019350505050602060405180830381600087803b158015612b7257600080fd5b505af1158015612b86573d6000803e3d6000fd5b505050506040513d6020811015612b9c57600080fd5b50506040805163226bf2d160e21b81526001600160a01b03888116600483015282516000938493928616926389afcb44926024808301939282900301818787803b158015612be957600080fd5b505af1158015612bfd573d6000803e3d6000fd5b505050506040513d6040811015612c1357600080fd5b50805160209091015190925090506000612c2d8e8e6145cf565b509050806001600160a01b03168e6001600160a01b031614612c50578183612c53565b82825b90975095508a871015612c975760405162461bcd60e51b8152600401808060200182810382526024815260200180614c846024913960400191505060405180910390fd5b89861015612cd65760405162461bcd60e51b8152600401808060200182810382526024815260200180614c126024913960400191505060405180910390fd5b505050505097509795505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60606116d37f00000000000000000000000000000000000000000000000000000000000000008484613a22565b6000806000612d887f00000000000000000000000000000000000000000000000000000000000000008e7f0000000000000000000000000000000000000000000000000000000000000000613b6e565b9050600087612d97578c612d9b565b6000195b9050816001600160a01b031663d505accf612db4610ec7565b604080516001600160e01b031960e085901b1681526001600160a01b03909216600483015230602483015260448201859052606482018d905260ff8b16608483015260a482018a905260c482018990525160e480830192600092919082900301818387803b158015612e2557600080fd5b505af1158015612e39573d6000803e3d6000fd5b50505050612e4b8e8e8e8e8e8e610f24565b909f909e509c50505050505050505050505050565b60008060008342811015612ea9576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b6000612eb3610ec7565b9050612ec38d8d8d8d8d8d6146ad565b90955093506000612ef57f00000000000000000000000000000000000000000000000000000000000000008f8f613b6e565b9050612f038e838389613c2e565b612f0f8d838388613c2e565b806001600160a01b0316636a627842896040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b158015612f5e57600080fd5b505af1158015612f72573d6000803e3d6000fd5b505050506040513d6020811015612f8857600080fd5b5051959e949d50949b50929950505050505050505050565b60008060008342811015612fe9576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b6130178a7f00000000000000000000000000000000000000000000000000000000000000008b348c8c6146ad565b90945092506000613026610ec7565b905060006130757f00000000000000000000000000000000000000000000000000000000000000008d7f0000000000000000000000000000000000000000000000000000000000000000613b6e565b90506130838c838389613c2e565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0866040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130de57600080fd5b505af11580156130f2573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb82876040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561316e57600080fd5b505af1158015613182573d6000803e3d6000fd5b505050506040513d602081101561319857600080fd5b50516131a057fe5b806001600160a01b0316636a627842896040518263ffffffff1660e01b815260040180826001600160a01b03168152602001915050602060405180830381600087803b1580156131ef57600080fd5b505af1158015613203573d6000803e3d6000fd5b505050506040513d602081101561321957600080fd5b50519350348510156132315761323182863403613729565b50505096509650969350505050565b60608142811015613286576040805162461bcd60e51b81526020600482015260166024820152600080516020614d7d833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316868660008181106132bd57fe5b905060200201356001600160a01b03166001600160a01b031614613316576040805162461bcd60e51b815260206004820152601b6024820152600080516020614d39833981519152604482015290519081900360640190fd5b6133747f000000000000000000000000000000000000000000000000000000000000000088888880806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613fc792505050565b9150348260008151811061338457fe5b602002602001015111156133c95760405162461bcd60e51b8152600401808060200182810382526025815260200180614bed6025913960400191505060405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061340557fe5b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561343857600080fd5b505af115801561344c573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6134b17f000000000000000000000000000000000000000000000000000000000000000089896000818110611ca557fe5b846000815181106134be57fe5b60200260200101516040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561350c57600080fd5b505af1158015613520573d6000803e3d6000fd5b505050506040513d602081101561353657600080fd5b505161353e57fe5b61357d82878780806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250899250613d8a915050565b8160008151811061358a57fe5b6020026020010151341115612455576124556135a4610ec7565b836000815181106135b157fe5b60200260200101513403613729565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1781529251825160009485949389169392918291908083835b6020831061363c5780518252601f19909201916020918201910161361d565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461369e576040519150601f19603f3d011682016040523d82523d6000602084013e6136a3565b606091505b50915091508180156136d15750805115806136d157508080602001905160208110156136ce57600080fd5b50515b613722576040805162461bcd60e51b815260206004820152601f60248201527f5472616e7366657248656c7065723a205452414e534645525f4641494c454400604482015290519081900360640190fd5b5050505050565b604080516000808252602082019092526001600160a01b0384169083906040518082805190602001908083835b602083106137755780518252601f199092019160209182019101613756565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146137d7576040519150601f19603f3d011682016040523d82523d6000602084013e6137dc565b606091505b505090508061381c5760405162461bcd60e51b8152600401808060200182810382526023815260200180614cec6023913960400191505060405180910390fd5b505050565b60008084116138615760405162461bcd60e51b8152600401808060200182810382526029815260200180614c366029913960400191505060405180910390fd5b6000831180156138715750600082115b6138ac5760405162461bcd60e51b8152600401808060200182810382526026815260200180614b386026913960400191505060405180910390fd5b60006138ba856103e561493e565b905060006138c8828561493e565b905060006138e2836138dc886103e861493e565b906139d3565b90508082816138ed57fe5b04979650505050505050565b60006001600160a01b0386166139405760405162461bcd60e51b8152600401808060200182810382526025815260200180614c5f6025913960400191505060405180910390fd5b600161395361394e876149a1565b614a24565b83868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156139aa573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b808201828110156116d6576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b604482015290519081900360640190fd5b6060600282511015613a7b576040805162461bcd60e51b815260206004820152601c60248201527f506f6c796465784c6962726172793a20494e56414c49445f5041544800000000604482015290519081900360640190fd5b815167ffffffffffffffff81118015613a9357600080fd5b50604051908082528060200260200182016040528015613abd578160200160208202803683370190505b5090508281600081518110613ace57fe5b60200260200101818152505060005b6001835103811015613b6657600080613b2087868581518110613afc57fe5b6020026020010151878660010181518110613b1357fe5b6020026020010151614a70565b91509150613b42848481518110613b3357fe5b60200260200101518383613821565b848460010181518110613b5157fe5b60209081029190910101525050600101613add565b509392505050565b6000806000613b7d85856145cf565b604080516bffffffffffffffffffffffff19606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501206001600160f81b031960688401529a90941b9093166069840152607d8301989098527f8cb41b27c88f8934c0773207afb757d84c4baa607990ad4a30505e42438d999a609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b178152925182516000948594938a169392918291908083835b60208310613cb25780518252601f199092019160209182019101613c93565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114613d14576040519150601f19603f3d011682016040523d82523d6000602084013e613d19565b606091505b5091509150818015613d47575080511580613d475750808060200190516020811015613d4457600080fd5b50515b613d825760405162461bcd60e51b8152600401808060200182810382526024815260200180614d596024913960400191505060405180910390fd5b505050505050565b60005b6001835103811015613fc157600080848381518110613da857fe5b6020026020010151858460010181518110613dbf57fe5b6020026020010151915091506000613dd783836145cf565b5090506000878560010181518110613deb57fe5b60200260200101519050600080836001600160a01b0316866001600160a01b031614613e1957826000613e1d565b6000835b91509150600060028a51038810613e345788613e75565b613e757f0000000000000000000000000000000000000000000000000000000000000000878c8b60020181518110613e6857fe5b6020026020010151613b6e565b9050613ea27f00000000000000000000000000000000000000000000000000000000000000008888613b6e565b6001600160a01b031663022c0d9f84848460006040519080825280601f01601f191660200182016040528015613edf576020820181803683370190505b506040518563ffffffff1660e01b815260040180858152602001848152602001836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613f47578181015183820152602001613f2f565b50505050905090810190601f168015613f745780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b158015613f9657600080fd5b505af1158015613faa573d6000803e3d6000fd5b505060019099019850613d8d975050505050505050565b50505050565b6060600282511015614020576040805162461bcd60e51b815260206004820152601c60248201527f506f6c796465784c6962726172793a20494e56414c49445f5041544800000000604482015290519081900360640190fd5b815167ffffffffffffffff8111801561403857600080fd5b50604051908082528060200260200182016040528015614062578160200160208202803683370190505b509050828160018351038151811061407657fe5b60209081029190910101528151600019015b8015613b66576000806140b8878660018603815181106140a457fe5b6020026020010151878681518110613b1357fe5b915091506140da8484815181106140cb57fe5b60200260200101518383614451565b8460018503815181106140e957fe5b6020908102919091010152505060001901614088565b60005b600183510381101561381c5760008084838151811061411d57fe5b602002602001015185846001018151811061413457fe5b602002602001015191509150600061414c83836145cf565b509050600061417c7f00000000000000000000000000000000000000000000000000000000000000008585613b6e565b9050600080600080846001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156141bd57600080fd5b505afa1580156141d1573d6000803e3d6000fd5b505050506040513d60608110156141e757600080fd5b5080516020909101516001600160701b0391821693501690506000806001600160a01b038a81169089161461421d578284614220565b83835b91509150614275828b6001600160a01b03166370a082318a6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611e1357600080fd5b9550614282868383613821565b945050505050600080856001600160a01b0316886001600160a01b0316146142ac578260006142b0565b6000835b91509150600060028c51038a106142c7578a6142fb565b6142fb7f0000000000000000000000000000000000000000000000000000000000000000898e8d60020181518110613e6857fe5b604080516000808252602082019283905263022c0d9f60e01b835260248201878152604483018790526001600160a01b038086166064850152608060848501908152845160a48601819052969750908c169563022c0d9f958a958a958a9591949193919260c486019290918190849084905b8381101561438557818101518382015260200161436d565b50505050905090810190601f1680156143b25780820380516001836020036101000a031916815260200191505b5095505050505050600060405180830381600087803b1580156143d457600080fd5b505af11580156143e8573d6000803e3d6000fd5b50506001909b019a506141029950505050505050505050565b808203828111156116d6576040805162461bcd60e51b815260206004820152601560248201527464732d6d6174682d7375622d756e646572666c6f7760581b604482015290519081900360640190fd5b60008084116144915760405162461bcd60e51b815260040180806020018281038252602a815260200180614d0f602a913960400191505060405180910390fd5b6000831180156144a15750600082115b6144dc5760405162461bcd60e51b8152600401808060200182810382526026815260200180614b386026913960400191505060405180910390fd5b60006144f46103e86144ee868861493e565b9061493e565b905060006145086103e56144ee8689614401565b905061451f600182848161451857fe5b04906139d3565b9695505050505050565b60008084116145695760405162461bcd60e51b8152600401808060200182810382526023815260200180614bca6023913960400191505060405180910390fd5b6000831180156145795750600082115b6145b45760405162461bcd60e51b8152600401808060200182810382526026815260200180614b386026913960400191505060405180910390fd5b826145bf858461493e565b816145c657fe5b04949350505050565b600080826001600160a01b0316846001600160a01b031614156146235760405162461bcd60e51b8152600401808060200182810382526023815260200180614cc96023913960400191505060405180910390fd5b826001600160a01b0316846001600160a01b031610614643578284614646565b83835b90925090506001600160a01b0382166146a6576040805162461bcd60e51b815260206004820152601c60248201527f506f6c796465784c6962726172793a205a45524f5f4144445245535300000000604482015290519081900360640190fd5b9250929050565b60008060006001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e6a439058a8a6040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b031681526020019250505060206040518083038186803b15801561473957600080fd5b505afa15801561474d573d6000803e3d6000fd5b505050506040513d602081101561476357600080fd5b50516001600160a01b03161415614821577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c9c6539689896040518363ffffffff1660e01b815260040180836001600160a01b03168152602001826001600160a01b0316815260200192505050602060405180830381600087803b1580156147f457600080fd5b505af1158015614808573d6000803e3d6000fd5b505050506040513d602081101561481e57600080fd5b50505b60008061484f7f00000000000000000000000000000000000000000000000000000000000000008b8b614a70565b91509150816000148015614861575080155b1561487157879350869250614931565b600061487e898484614529565b90508781116148d157858110156148c65760405162461bcd60e51b8152600401808060200182810382526024815260200180614c126024913960400191505060405180910390fd5b88945092508261492f565b60006148de898486614529565b9050898111156148ea57fe5b878110156149295760405162461bcd60e51b8152600401808060200182810382526024815260200180614c846024913960400191505060405180910390fd5b94508793505b505b5050965096945050505050565b60008115806149595750508082028282828161495657fe5b04145b6116d6576040805162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b604482015290519081900360640190fd5b6000604051806080016040528060438152602001614b8760439139805190602001208260000151836020015184604001518051906020012060405160200180858152602001848152602001836001600160a01b03168152602001828152602001945050505050604051602081830303815290604052805190602001209050919050565b6000614a2e6116dc565b82604051602001808061190160f01b81525060020183815260200182815260200192505050604051602081830303815290604052805190602001209050919050565b6000806000614a7f85856145cf565b509050600080614a90888888613b6e565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015614ac857600080fd5b505afa158015614adc573d6000803e3d6000fd5b505050506040513d6060811015614af257600080fd5b5080516020909101516001600160701b0391821693501690506001600160a01b0387811690841614614b25578082614b28565b81815b9099909850965050505050505056fe506f6c796465784c6962726172793a20494e53554646494349454e545f4c4951554944495459506f6c79646578526f757465723a20494e53554646494349454e545f4f55545055545f414d4f554e544d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529506f6c796465784c6962726172793a20494e53554646494349454e545f414d4f554e54506f6c79646578526f757465723a204558434553534956455f494e5055545f414d4f554e54506f6c79646578526f757465723a20494e53554646494349454e545f425f414d4f554e54506f6c796465784c6962726172793a20494e53554646494349454e545f494e5055545f414d4f554e544e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5349474e4552506f6c79646578526f757465723a20494e53554646494349454e545f415f414d4f554e545369676e657220616e64207369676e617475726520646f206e6f74206d61746368506f6c796465784c6962726172793a204944454e544943414c5f4144445245535345535472616e7366657248656c7065723a204554485f5452414e534645525f4641494c4544506f6c796465784c6962726172793a20494e53554646494349454e545f4f55545055545f414d4f554e54506f6c79646578526f757465723a20494e56414c49445f5041544800000000005472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c4544506f6c79646578526f757465723a204558504952454400000000000000000000a2646970667358221220218ba39fa5a31e45dc860826ba2604033a6be6a6db6eb798a209a6debe846ad564736f6c63430007060033454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c75696e7432353620636861696e4964290000000000000000000000005bdd1cd910e3307582f213b33699e676e61dead90000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270

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

0000000000000000000000005bdd1cd910e3307582f213b33699e676e61dead90000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270

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

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000005bdd1cd910e3307582f213b33699e676e61dead9
Arg [1] : 0000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf1270


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