Contract 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a5

Txn Hash Method
Block
From
To
Value [Txn Fee]
0xeed0fed03f79dd03cc23c4e2537cad69debe4c65fc82925bedd0222ccc5eb19aSwap Exact Token...5008992023-05-28 19:12:5847 secs ago0x04d6876d077c59d96ac5b20feb762f52ffad1d00 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00021549438
0x5715a868102c935bd4c426e517e9cc50e872afd8b6dc843b8277a4b881294741Swap Exact Token...5008612023-05-28 19:09:224 mins ago0xc6ca1635ed896ec64c8ede61be18436adf88db24 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00027694005
0xb405f520fad48fb28123292878d0d63d80839fb749cfab57457a9ffe61767f47Swap Tokens For ...5008342023-05-28 19:09:224 mins ago0x04d6876d077c59d96ac5b20feb762f52ffad1d00 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00024644412
0x592f29fba621ceb20596f3658a3433ae13967972aa227da07c805df640e50dc9Swap ETH For Exa...5008332023-05-28 19:09:224 mins ago0xc6ca1635ed896ec64c8ede61be18436adf88db24 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.000702582056385 ETH0.00025459512
0xfb65595f74dfdfb06d5f769019a5004be5dfd390f6d051e344f1ba89e73f82f8Swap Exact Token...5007842023-05-28 19:05:497 mins ago0xcb54ebf9e208ce6b09d6a2512227a7546fbd035f IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00023712152
0x90b799813cea50e65c112cb80866ad00dd1ca7653a1f956ab63799a7b4d645feSwap Exact Token...5007082023-05-28 19:02:2811 mins ago0x07c8ac06709fbe949a3060d7164667254251c5bf IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.0001950464
0x4d523aad36a901fad96b8b85d308e016e885fc30b55bb97d6a4829c3fec7a992Swap Exact Token...5007012023-05-28 19:02:2811 mins ago0xd2578c95c2daf87e7542d4c305c95cef01295877 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00026208168
0xf5de66a94e235b8a17d56de3d678149d8c9d65899c8f32be5b266e54a86232daSwap Exact ETH F...5006252023-05-28 18:58:2415 mins ago0x07c8ac06709fbe949a3060d7164667254251c5bf IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0001 ETH0.00019469312
0xd1ca001cc6cc3dbbb50e0f666725ad7481ef20b0f5da3e3b216db69459040316Swap Exact ETH F...5006202023-05-28 18:58:2415 mins ago0x377cef280a120bc364abe40ebfe9540154a9ead3 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH0.00020858877
0x068888d8671a15dc823cf71ab386857991132bbf27967f741da972ddfaf82f5fSwap Exact ETH F...5006032023-05-28 18:56:3417 mins ago0x377cef280a120bc364abe40ebfe9540154a9ead3 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0005 ETH0.00018844177
0xfbc6f30fba797d3c1788220b4754c490f23581228b0ddfa5ab75a556e4343e3bSwap Exact ETH F...5005612023-05-28 18:55:1018 mins ago0x5f7003d0c8168c97cafaa850525b6c2b10bbeecb IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.001 ETH0.00021793389
0x6aa30d8497a3b4728816e4a6f63cecd389184d96cfdeba8eeadce81c20dd5abaSwap Exact Token...5004492023-05-28 18:49:4823 mins ago0x90e55017dd13061fe5d5abd10ad2fb413a5eced5 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00018583875
0x38597110fae51e762303a3ebbb392b26afa637eb57a9fe58244394f9a41af495Swap Exact Token...5004132023-05-28 18:48:0425 mins ago0x97c3aeb16f36decbcd248aec2c9d38d7da095a7e IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.000212226
0x7c566a4b9ea419bf3bfbb3e583fe7a798366b20a0af4ed5506aefbdbc871f597Swap Exact ETH F...5004062023-05-28 18:48:0425 mins ago0x90e55017dd13061fe5d5abd10ad2fb413a5eced5 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH0.00021750282
0xdd67c23907eba0ab2596f110d1fdbfbc2a60c5c0f76ed8eb090dfbc70a6885c1Swap Exact ETH F...5003622023-05-28 18:46:1327 mins ago0x90e55017dd13061fe5d5abd10ad2fb413a5eced5 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0005 ETH0.0001977352
0xe6a1e10a3fd61364e55532258343e0d808ad7581a319eb2129e4497dc7b47914Swap Exact ETH F...5003612023-05-28 18:46:1327 mins ago0xa46a97e97fa367c64ca903e66f16f476b673695b IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.001 ETH0.00020403119
0x67641c8bdacdc0ec02055785b3e0bec57815a44a3812b3b09a7ca29dc2f32491Swap Exact ETH F...5003552023-05-28 18:44:1929 mins ago0x97c3aeb16f36decbcd248aec2c9d38d7da095a7e IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0072 ETH0.00017471286
0x2597aeea6f8987a8cb728eac2cd8ed74fac0a070895b75709d69c2c0f36bc360Swap Exact Token...5001712023-05-28 18:34:4539 mins ago0x8dac0b5ebf7f543a1ee7be63d0e741f150ba1c97 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00022709984
0xb7e579d629d9f4daab9792f83a35fd71c7b1a4b99190fbc40b44e459cb4edfe3Swap Exact ETH F...5001642023-05-28 18:34:4539 mins ago0x8dac0b5ebf7f543a1ee7be63d0e741f150ba1c97 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.037449999999999 ETH0.00020560452
0xa0a0f91bd191cd52f6960fae7e22c42fd4a79f1d51ff7f02683574a06a770139Swap Exact ETH F...5001062023-05-28 18:30:1443 mins ago0xc984c92296cb3e333b3c8f30672010463a789dda IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.001 ETH0.00019166616
0x3e439f7b782c7e1861b3398843df080e8f4994d3ff868737d5dd34d578669125Swap Exact Token...5001012023-05-28 18:30:1443 mins ago0x657340f8f3187bb251700ede07140aaa93c08c35 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00004751472
0xab1e336cff1e9c41adf92d657b0ef7399f07c2e677415ff5673d2d19a5aae536Swap Exact Token...5000932023-05-28 18:30:1443 mins ago0x657340f8f3187bb251700ede07140aaa93c08c35 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50 ETH0.00020913782
0x4cb2d43eb0322fbcce19b7c8a0f240d8316599ccb3f084060aea07e0e68dddf5Swap Exact ETH F...5000692023-05-28 18:29:1744 mins ago0x657340f8f3187bb251700ede07140aaa93c08c35 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.2 ETH0.00022587085
0x3d768d37fdccdf5415bb74ec6a968c282dfde526aad69075fc484d8c74d30efeSwap Exact ETH F...4999712023-05-28 18:23:3650 mins ago0xc984c92296cb3e333b3c8f30672010463a789dda IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.001 ETH0.00027323672
0x092fa8cd47f0c712c079530ab8f09d913b45886cf8d8cca36ad4671514412e27Swap Exact ETH F...4998802023-05-28 18:16:5756 mins ago0x1e3a8b5b603fb9a14e90a63a3fecc70032005958 IN  0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0001 ETH0.00023512663
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x592f29fba621ceb20596f3658a3433ae13967972aa227da07c805df640e50dc95008332023-05-28 19:09:224 mins ago 0xc6ca1635ed896ec64c8ede61be18436adf88db24 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.000702582056385775 ETH
0x592f29fba621ceb20596f3658a3433ae13967972aa227da07c805df640e50dc95008332023-05-28 19:09:224 mins ago 0xc6ca1635ed896ec64c8ede61be18436adf88db24 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.000702582056385775 ETH
0x592f29fba621ceb20596f3658a3433ae13967972aa227da07c805df640e50dc95008332023-05-28 19:09:224 mins ago 0xc6ca1635ed896ec64c8ede61be18436adf88db24 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.000702582056385775 ETH
0x592f29fba621ceb20596f3658a3433ae13967972aa227da07c805df640e50dc95008332023-05-28 19:09:224 mins ago 0xc6ca1635ed896ec64c8ede61be18436adf88db24 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.000702582056385775 ETH
0x592f29fba621ceb20596f3658a3433ae13967972aa227da07c805df640e50dc95008332023-05-28 19:09:224 mins ago 0xc6ca1635ed896ec64c8ede61be18436adf88db24 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.000702582056385775 ETH
0xf5de66a94e235b8a17d56de3d678149d8c9d65899c8f32be5b266e54a86232da5006252023-05-28 18:58:2415 mins ago 0x07c8ac06709fbe949a3060d7164667254251c5bf 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0001 ETH
0xf5de66a94e235b8a17d56de3d678149d8c9d65899c8f32be5b266e54a86232da5006252023-05-28 18:58:2415 mins ago 0x07c8ac06709fbe949a3060d7164667254251c5bf 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0001 ETH
0xf5de66a94e235b8a17d56de3d678149d8c9d65899c8f32be5b266e54a86232da5006252023-05-28 18:58:2415 mins ago 0x07c8ac06709fbe949a3060d7164667254251c5bf 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0001 ETH
0xf5de66a94e235b8a17d56de3d678149d8c9d65899c8f32be5b266e54a86232da5006252023-05-28 18:58:2415 mins ago 0x07c8ac06709fbe949a3060d7164667254251c5bf 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0001 ETH
0xd1ca001cc6cc3dbbb50e0f666725ad7481ef20b0f5da3e3b216db694590403165006202023-05-28 18:58:2415 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH
0xd1ca001cc6cc3dbbb50e0f666725ad7481ef20b0f5da3e3b216db694590403165006202023-05-28 18:58:2415 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH
0xd1ca001cc6cc3dbbb50e0f666725ad7481ef20b0f5da3e3b216db694590403165006202023-05-28 18:58:2415 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH
0xd1ca001cc6cc3dbbb50e0f666725ad7481ef20b0f5da3e3b216db694590403165006202023-05-28 18:58:2415 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH
0xd1ca001cc6cc3dbbb50e0f666725ad7481ef20b0f5da3e3b216db694590403165006202023-05-28 18:58:2415 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH
0xd1ca001cc6cc3dbbb50e0f666725ad7481ef20b0f5da3e3b216db694590403165006202023-05-28 18:58:2415 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH
0x068888d8671a15dc823cf71ab386857991132bbf27967f741da972ddfaf82f5f5006032023-05-28 18:56:3417 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0005 ETH
0x068888d8671a15dc823cf71ab386857991132bbf27967f741da972ddfaf82f5f5006032023-05-28 18:56:3417 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0005 ETH
0x068888d8671a15dc823cf71ab386857991132bbf27967f741da972ddfaf82f5f5006032023-05-28 18:56:3417 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0005 ETH
0x068888d8671a15dc823cf71ab386857991132bbf27967f741da972ddfaf82f5f5006032023-05-28 18:56:3417 mins ago 0x377cef280a120bc364abe40ebfe9540154a9ead3 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.0005 ETH
0xfbc6f30fba797d3c1788220b4754c490f23581228b0ddfa5ab75a556e4343e3b5005612023-05-28 18:55:1018 mins ago 0x5f7003d0c8168c97cafaa850525b6c2b10bbeecb 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.001 ETH
0xfbc6f30fba797d3c1788220b4754c490f23581228b0ddfa5ab75a556e4343e3b5005612023-05-28 18:55:1018 mins ago 0x5f7003d0c8168c97cafaa850525b6c2b10bbeecb 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.001 ETH
0xfbc6f30fba797d3c1788220b4754c490f23581228b0ddfa5ab75a556e4343e3b5005612023-05-28 18:55:1018 mins ago 0x5f7003d0c8168c97cafaa850525b6c2b10bbeecb 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.001 ETH
0xfbc6f30fba797d3c1788220b4754c490f23581228b0ddfa5ab75a556e4343e3b5005612023-05-28 18:55:1018 mins ago 0x5f7003d0c8168c97cafaa850525b6c2b10bbeecb 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.001 ETH
0x7c566a4b9ea419bf3bfbb3e583fe7a798366b20a0af4ed5506aefbdbc871f5975004062023-05-28 18:48:0425 mins ago 0x90e55017dd13061fe5d5abd10ad2fb413a5eced5 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH
0x7c566a4b9ea419bf3bfbb3e583fe7a798366b20a0af4ed5506aefbdbc871f5975004062023-05-28 18:48:0425 mins ago 0x90e55017dd13061fe5d5abd10ad2fb413a5eced5 0x61f4ecd130291e5d5d7809a112f9f9081b8ed3a50.006 ETH
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
AntfarmRouter

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion
File 1 of 19 : AntfarmOracle.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "../libraries/fixedpoint/FixedPoint.sol";

error InvalidToken();

/// @title Antfarm Oracle for AntfarmPair
/// @notice Fixed window oracle that recomputes the average price for the entire period once every period
contract AntfarmOracle {
    using FixedPoint for *;

    uint256 public constant PERIOD = 1 hours;

    address public token1;
    address public pair;

    uint256 public price1CumulativeLast;
    uint32 public blockTimestampLast;
    FixedPoint.uq112x112 public price1Average;

    bool public firstUpdateCall;

    constructor(
        address _token1,
        uint256 _price1CumulativeLast,
        uint32 _blockTimestampLast
    ) {
        token1 = _token1;
        pair = msg.sender;
        price1CumulativeLast = _price1CumulativeLast; // fetch the current accumulated price value (1 / 0)
        blockTimestampLast = _blockTimestampLast;
        firstUpdateCall = true;
    }

    /// @notice Average price update
    /// @param price1Cumulative Price cumulative for the associated AntfarmPair's token1
    /// @param blockTimestamp Last block timestamp for the associated AntfarmPair
    /// @dev Only usable by the associated AntfarmPair
    function update(uint256 price1Cumulative, uint32 blockTimestamp) external {
        require(msg.sender == pair);
        unchecked {
            uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
            // ensure that at least one full period has passed since the last update
            if (timeElapsed >= PERIOD || firstUpdateCall) {
                // overflow is desired, casting never truncates
                // cumulative price is in (uq112x112 price * seconds) units so we simply wrap it after division by time elapsed
                price1Average = FixedPoint.uq112x112(
                    uint224(
                        (price1Cumulative - price1CumulativeLast) / timeElapsed
                    )
                );
                price1CumulativeLast = price1Cumulative;
                blockTimestampLast = blockTimestamp;
                if (firstUpdateCall) {
                    firstUpdateCall = false;
                }
            }
        }
    }

    /// @notice Consult the average price for a given token
    /// @param token Price cumulative for the associated AntfarmPair's token
    /// @param amountIn The amount to get the value of
    /// @return amountOut Return the calculated amount (always return 0 before update has been called successfully for the first time)
    function consult(address token, uint256 amountIn)
        external
        view
        returns (uint256 amountOut)
    {
        if (token == token1) {
            amountOut = price1Average.mul(amountIn).decode144();
        } else {
            revert InvalidToken();
        }
    }
}

File 2 of 19 : AntfarmRouter.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "../interfaces/IAntfarmRouter.sol";
import "../interfaces/IAntfarmPair.sol";
import "../interfaces/IAntfarmFactory.sol";
import "../interfaces/IERC20.sol";
import "../interfaces/IWETH.sol";
import "../libraries/TransferHelper.sol";
import "./AntfarmOracle.sol";
import "../utils/AntfarmRouterErrors.sol";

/// @title Antfarm Router for AntFarmPair
/// @notice High-level contract that serves as the entrypoint for swapping
contract AntfarmRouter is IAntfarmRouter {
    address public immutable factory;
    address public immutable WETH;
    address public immutable antfarmToken;

    modifier ensure(uint256 deadline) {
        if (deadline < block.timestamp) revert Expired();
        _;
    }

    constructor(
        address _factory,
        address _WETH,
        address _antfarmToken
    ) {
        require(_factory != address(0), "NULL_FACTORY_ADDRESS");
        require(_WETH != address(0), "NULL_WETH_ADDRESS");
        require(_antfarmToken != address(0), "NULL_ATF_ADDRESS");
        factory = _factory;
        WETH = _WETH;
        antfarmToken = _antfarmToken;
    }

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

    /// @notice Swaps an exact amount of input tokens for as many output tokens as possible
    /// @param params The parameters necessary for the swap, encoded as `swapExactTokensForTokensParams` in calldata
    // @param amountIn The amount of input tokens to send
    // @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert
    // @param maxFee Maximum fees to be paid
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    /// @return amounts The input token amount and all subsequent output token amounts
    function swapExactTokensForTokens(
        swapExactTokensForTokensParams calldata params
    )
        external
        virtual
        ensure(params.deadline)
        returns (uint256[] memory amounts)
    {
        uint256 amountIn = params.path[0] == antfarmToken
            ? (params.amountIn * (1000 + params.fees[0])) / 1000
            : params.amountIn;
        amounts = getAmountsOut(amountIn, params.path, params.fees);
        if (amounts[amounts.length - 1] < params.amountOutMin) {
            revert InsufficientOutputAmount();
        }
        TransferHelper.safeTransferFrom(
            params.path[0],
            msg.sender,
            pairFor(params.path[0], params.path[1], params.fees[0]),
            amounts[0]
        );
        if (
            _swap(amounts, params.path, params.fees, params.to) > params.maxFee
        ) {
            revert InsufficientMaxFee();
        }
    }

    /// @notice Receive an exact amount of output tokens for as few input tokens as possible
    /// @param params The parameters necessary for the swap, encoded as `swapTokensForExactTokensParams` in calldata
    // @param amountOut The amount of output tokens to receive
    // @param amountInMax The maximum amount of input tokens that can be required before the transaction reverts
    // @param maxFee Maximum fees to be paid
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    /// @return amounts The input token amount and all subsequent output token amounts
    function swapTokensForExactTokens(
        swapTokensForExactTokensParams calldata params
    )
        external
        virtual
        ensure(params.deadline)
        returns (uint256[] memory amounts)
    {
        uint256 amountInMax = params.path[0] == antfarmToken
            ? (params.amountInMax * (1000 + params.fees[0])) / 1000
            : params.amountInMax;
        amounts = getAmountsIn(params.amountOut, params.path, params.fees);
        if (amounts[0] > amountInMax) revert ExcessiveInputAmount();
        TransferHelper.safeTransferFrom(
            params.path[0],
            msg.sender,
            pairFor(params.path[0], params.path[1], params.fees[0]),
            amounts[0]
        );
        if (
            _swap(amounts, params.path, params.fees, params.to) > params.maxFee
        ) {
            revert InsufficientMaxFee();
        }
    }

    /// @notice Swaps an exact amount of ETH for as many output tokens as possible
    /// @param params The parameters necessary for the swap, encoded as `swapExactETHForTokensParams` in calldata
    // @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert
    // @param maxFee Maximum fees to be paid
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    /// @return amounts The input token amount and all subsequent output token amounts
    function swapExactETHForTokens(swapExactETHForTokensParams calldata params)
        external
        payable
        virtual
        ensure(params.deadline)
        returns (uint256[] memory amounts)
    {
        if (params.path[0] != WETH) revert InvalidPath();
        amounts = getAmountsOut(msg.value, params.path, params.fees);
        if (amounts[amounts.length - 1] < params.amountOutMin) {
            revert InsufficientOutputAmount();
        }
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(
            IWETH(WETH).transfer(
                pairFor(params.path[0], params.path[1], params.fees[0]),
                amounts[0]
            )
        );
        if (
            _swap(amounts, params.path, params.fees, params.to) > params.maxFee
        ) {
            revert InsufficientMaxFee();
        }
    }

    /// @notice Receive an exact amount of ETH for as few input tokens as possible
    /// @param params The parameters necessary for the swap, encoded as `swapTokensForExactETHParams` in calldata
    // @param amountOut The amount of ETH to receive
    // @param amountInMax The maximum amount of input tokens that can be required before the transaction reverts
    // @param maxFee Maximum fees to be paid
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    /// @return amounts The input token amount and all subsequent output token amounts
    function swapTokensForExactETH(swapTokensForExactETHParams calldata params)
        external
        virtual
        ensure(params.deadline)
        returns (uint256[] memory amounts)
    {
        if (params.path[params.path.length - 1] != WETH) revert InvalidPath();
        uint256 amountInMax = params.path[0] == antfarmToken
            ? (params.amountInMax * (1000 + params.fees[0])) / 1000
            : params.amountInMax;
        amounts = getAmountsIn(params.amountOut, params.path, params.fees);
        if (amounts[0] > amountInMax) revert ExcessiveInputAmount();
        TransferHelper.safeTransferFrom(
            params.path[0],
            msg.sender,
            pairFor(params.path[0], params.path[1], params.fees[0]),
            amounts[0]
        );
        if (
            _swap(amounts, params.path, params.fees, address(this)) >
            params.maxFee
        ) {
            revert InsufficientMaxFee();
        }
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferETH(params.to, amounts[amounts.length - 1]);
    }

    /// @notice Swaps an exact amount of tokens for as much ETH as possible
    /// @param params The parameters necessary for the swap, encoded as `swapExactTokensForETHParams` in calldata
    // @param amountIn The amount of input tokens to send
    // @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert
    // @param maxFee Maximum fees to be paid
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    /// @return amounts The input token amount and all subsequent output token amounts
    function swapExactTokensForETH(swapExactTokensForETHParams calldata params)
        external
        virtual
        ensure(params.deadline)
        returns (uint256[] memory amounts)
    {
        uint256 amountIn = params.path[0] == antfarmToken
            ? (params.amountIn * (1000 + params.fees[0])) / 1000
            : params.amountIn;
        if (params.path[params.path.length - 1] != WETH) revert InvalidPath();
        amounts = getAmountsOut(amountIn, params.path, params.fees);
        if (amounts[amounts.length - 1] < params.amountOutMin) {
            revert InsufficientOutputAmount();
        }
        TransferHelper.safeTransferFrom(
            params.path[0],
            msg.sender,
            pairFor(params.path[0], params.path[1], params.fees[0]),
            amounts[0]
        );
        if (
            _swap(amounts, params.path, params.fees, address(this)) >
            params.maxFee
        ) {
            revert InsufficientMaxFee();
        }
        IWETH(WETH).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferETH(params.to, amounts[amounts.length - 1]);
    }

    /// @notice Receive an exact amount of tokens for as little ETH as possible
    /// @param params The parameters necessary for the swap, encoded as `swapETHForExactTokensParams` in calldata
    // @param amountOut The amount of tokens to receive
    // @param maxFee Maximum fees to be paid
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    /// @return amounts The input token amount and all subsequent output token amounts
    function swapETHForExactTokens(swapETHForExactTokensParams calldata params)
        external
        payable
        virtual
        ensure(params.deadline)
        returns (uint256[] memory amounts)
    {
        if (params.path[0] != WETH) revert InvalidPath();
        amounts = getAmountsIn(params.amountOut, params.path, params.fees);
        if (amounts[0] > msg.value) revert ExcessiveInputAmount();
        IWETH(WETH).deposit{value: amounts[0]}();
        assert(
            IWETH(WETH).transfer(
                pairFor(params.path[0], params.path[1], params.fees[0]),
                amounts[0]
            )
        );
        if (
            _swap(amounts, params.path, params.fees, params.to) > params.maxFee
        ) {
            revert InsufficientMaxFee();
        }
        // refund dust ETH if any
        if (msg.value > amounts[0])
            TransferHelper.safeTransferETH(msg.sender, msg.value - amounts[0]);
    }

    /// @notice Identical to swapExactTokensForTokens, but succeeds for tokens that take a fee on transfer
    /// @param params The parameters necessary for the swap, encoded as `swapExactTokensForTokensParams` in calldata
    // @param amountIn The amount of input tokens to send
    // @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        swapExactTokensForTokensParams calldata params
    ) external virtual ensure(params.deadline) {
        TransferHelper.safeTransferFrom(
            params.path[0],
            msg.sender,
            pairFor(params.path[0], params.path[1], params.fees[0]),
            params.amountIn
        );
        uint256 balanceBefore = IERC20(params.path[params.path.length - 1])
            .balanceOf(params.to);
        swapParams memory sParams = swapParams(
            params.path,
            params.fees,
            params.to
        );
        if (_swapSupportingFeeOnTransferTokens(sParams) > params.maxFee) {
            revert InsufficientMaxFee();
        }
        if (
            IERC20(params.path[params.path.length - 1]).balanceOf(params.to) -
                balanceBefore <
            params.amountOutMin
        ) {
            revert InsufficientOutputAmount();
        }
    }

    /// @notice Identical to swapExactETHForTokens, but succeeds for tokens that take a fee on transfer
    /// @param params The parameters necessary for the swap, encoded as `swapExactETHForTokensParams` in calldata
    // @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        swapExactETHForTokensParams calldata params
    ) external payable virtual ensure(params.deadline) {
        if (params.path[0] != WETH) revert InvalidPath();
        uint256 amountIn = msg.value;
        IWETH(WETH).deposit{value: amountIn}();
        assert(
            IWETH(WETH).transfer(
                pairFor(params.path[0], params.path[1], params.fees[0]),
                amountIn
            )
        );
        uint256 balanceBefore = IERC20(params.path[params.path.length - 1])
            .balanceOf(params.to);
        swapParams memory sParams = swapParams(
            params.path,
            params.fees,
            params.to
        );
        if (_swapSupportingFeeOnTransferTokens(sParams) > params.maxFee) {
            revert InsufficientMaxFee();
        }
        if (
            IERC20(params.path[params.path.length - 1]).balanceOf(params.to) -
                balanceBefore <
            params.amountOutMin
        ) {
            revert InsufficientOutputAmount();
        }
    }

    /// @notice Identical to swapExactTokensForETH, but succeeds for tokens that take a fee on transfer
    /// @param params The parameters necessary for the swap, encoded as `swapExactTokensForETHParams` in calldata
    // @param amountIn The amount of input tokens to send
    // @param amountOutMin The minimum amount of output tokens that must be received for the transaction not to revert
    // @param path An array of token addresses
    // @param fees Associated fee for each two token addresses within the path
    // @param to Recipient of the output tokens
    // @param deadline Unix timestamp after which the transaction will revert
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        swapExactTokensForETHParams calldata params
    ) external virtual ensure(params.deadline) {
        if (params.path[params.path.length - 1] != WETH) revert InvalidPath();
        TransferHelper.safeTransferFrom(
            params.path[0],
            msg.sender,
            pairFor(params.path[0], params.path[1], params.fees[0]),
            params.amountIn
        );
        swapParams memory sParams = swapParams(
            params.path,
            params.fees,
            address(this)
        );
        if (_swapSupportingFeeOnTransferTokens(sParams) > params.maxFee) {
            revert InsufficientMaxFee();
        }
        uint256 amountOut = IERC20(WETH).balanceOf(address(this));
        if (amountOut < params.amountOutMin) revert InsufficientOutputAmount();
        IWETH(WETH).withdraw(amountOut);
        TransferHelper.safeTransferETH(params.to, amountOut);
    }

    // fetches and sorts the reserves for a pair
    function getReserves(
        address tokenA,
        address tokenB,
        uint16 fee
    ) public view returns (uint256 reserveA, uint256 reserveB) {
        (address token0, ) = sortTokens(tokenA, tokenB);
        (uint256 reserve0, uint256 reserve1, ) = IAntfarmPair(
            pairFor(tokenA, tokenB, fee)
        ).getReserves();
        (reserveA, reserveB) = tokenA == token0
            ? (reserve0, reserve1)
            : (reserve1, reserve0);
    }

    // SWAP
    // requires the initial amount to have already been sent to the first pair
    function _swap(
        uint256[] memory amounts,
        address[] memory path,
        uint16[] memory fees,
        address _to
    ) internal virtual returns (uint256 totalFee) {
        for (uint256 i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            uint16 fee = fees[i];
            IAntfarmPair antfarmPair = IAntfarmPair(
                pairFor(input, output, fee)
            );

            (address token0, ) = sortTokens(input, output);
            (uint256 amount0Out, uint256 amount1Out) = input == token0
                ? (uint256(0), amounts[i + 1])
                : (amounts[i + 1], uint256(0));

            {
                uint256 amountIn = amounts[i];

                if (input == antfarmToken) {
                    totalFee = totalFee + ((amountIn * fee) / (1000 + fee));
                } else if (output == antfarmToken) {
                    totalFee =
                        totalFee +
                        ((amounts[i + 1] * fee) / (1000 - fee));
                } else {
                    uint256 feeToPay = antfarmPair.getFees(
                        amount0Out,
                        input == token0 ? amountIn : uint256(0),
                        amount1Out,
                        input == token0 ? uint256(0) : amountIn
                    );

                    TransferHelper.safeTransferFrom(
                        antfarmToken,
                        msg.sender,
                        address(antfarmPair),
                        feeToPay
                    );

                    totalFee = totalFee + feeToPay;
                }
            }

            address to = i < path.length - 2
                ? pairFor(output, path[i + 2], fees[i + 1])
                : _to;
            antfarmPair.swap(amount0Out, amount1Out, to);
        }
    }

    // **** SWAP (supporting fee-on-transfer tokens) ****
    function _swapSupportingFeeOnTransferTokens(swapParams memory sParams)
        internal
        virtual
        returns (uint256 totalFee)
    {
        for (uint256 i; i < sParams.path.length - 1; i++) {
            (address input, address output) = (
                sParams.path[i],
                sParams.path[i + 1]
            );
            uint16 fee = sParams.fees[i];
            IAntfarmPair antfarmPair = IAntfarmPair(
                pairFor(input, output, fee)
            );

            (address token0, ) = sortTokens(input, output);

            uint256 amountIn;
            uint256 amountOut;
            {
                (uint256 reserve0, uint256 reserve1, ) = antfarmPair
                    .getReserves();
                (uint256 reserveIn, uint256 reserveOut) = input == token0
                    ? (reserve0, reserve1)
                    : (reserve1, reserve0);

                amountIn =
                    IERC20(input).balanceOf(address(antfarmPair)) -
                    reserveIn;

                if (input == antfarmToken) {
                    amountOut = getAmountOut(
                        (amountIn * 1000) / (1000 + fee),
                        reserveIn,
                        reserveOut
                    );
                } else if (output == antfarmToken) {
                    amountOut =
                        (getAmountOut(amountIn, reserveIn, reserveOut) *
                            (1000 - fee)) /
                        1000;
                } else {
                    amountOut = getAmountOut(amountIn, reserveIn, reserveOut);
                }
            }

            (uint256 amount0Out, uint256 amount1Out) = input == token0
                ? (uint256(0), amountOut)
                : (amountOut, uint256(0));

            if (input == antfarmToken) {
                totalFee = totalFee + ((amountIn * fee) / (1000 + fee));
            } else if (output == antfarmToken) {
                totalFee = totalFee + ((amountIn * fee) / 1000);
            } else {
                uint256 feeToPay = antfarmPair.getFees(
                    amount0Out,
                    input == token0 ? amountIn : uint256(0),
                    amount1Out,
                    input == token0 ? uint256(0) : amountIn
                );

                TransferHelper.safeTransferFrom(
                    antfarmToken,
                    msg.sender,
                    address(antfarmPair),
                    feeToPay
                );

                totalFee = totalFee + feeToPay;
            }

            address to = i < sParams.path.length - 2
                ? pairFor(output, sParams.path[i + 2], sParams.fees[i + 1])
                : sParams.to;
            antfarmPair.swap(amount0Out, amount1Out, to);
        }
    }

    // **** LIBRARY FUNCTIONS ADDED INTO THE CONTRACT ****
    // returns sorted token addresses, used to handle return values from pairs sorted in this order
    function sortTokens(address tokenA, address tokenB)
        internal
        view
        returns (address token0, address token1)
    {
        if (tokenA == tokenB) revert IdenticalAddresses();
        if (tokenA == antfarmToken || tokenB == antfarmToken) {
            (token0, token1) = tokenA == antfarmToken
                ? (antfarmToken, tokenB)
                : (antfarmToken, tokenA);
            if (token1 == address(0)) revert ZeroAddress();
        } else {
            (token0, token1) = tokenA < tokenB
                ? (tokenA, tokenB)
                : (tokenB, tokenA);
            if (token0 == address(0)) revert ZeroAddress();
        }
    }

    /// @notice Calculates the CREATE2 address for a pair without making any external calls
    /// @param tokenA Token0 from the AntfarmPair
    /// @param tokenB Token1 from the AntfarmPair
    /// @param fee Associated fee to the AntfarmPair
    /// @return pair The CREATE2 address for the desired AntFarmPair
    function pairFor(
        address tokenA,
        address tokenB,
        uint16 fee
    ) public view returns (address pair) {
        (address token0, address token1) = sortTokens(tokenA, tokenB);
        pair = address(
            uint160(
                uint256(
                    keccak256(
                        abi.encodePacked(
                            hex"ff",
                            factory,
                            keccak256(
                                abi.encodePacked(
                                    token0,
                                    token1,
                                    fee,
                                    antfarmToken
                                )
                            ),
                            token0 == antfarmToken
                                ? hex"99c189a5ef3d337612cf0ce2bd055546e23b91fea9e9e54201b23f14d763f333" // AtfPair init code hash
                                : hex"3b29ecd4cb06592a81cac4799fb24ef6a176fe95ecb50f304972882b150f3f3a" // Pair init code hash
                        )
                    )
                )
            )
        );
    }

    // performs chained getAmountOut calculations on any number of pairs
    function getAmountsOut(
        uint256 amountIn,
        address[] memory path,
        uint16[] memory fees
    ) public view returns (uint256[] memory) {
        if (path.length < 2) revert InvalidPath();
        uint256[] memory amounts = new uint256[](path.length);
        amounts[0] = amountIn;
        for (uint256 i; i < path.length - 1; i++) {
            (uint256 reserveIn, uint256 reserveOut) = getReserves(
                path[i],
                path[i + 1],
                fees[i]
            );
            if (path[i] == antfarmToken) {
                amounts[i + 1] = getAmountOut(
                    (amounts[i] * 1000) / (1000 + fees[i]),
                    reserveIn,
                    reserveOut
                );
            } else if (path[i + 1] == antfarmToken) {
                amounts[i + 1] =
                    (getAmountOut(amounts[i], reserveIn, reserveOut) *
                        (1000 - fees[i])) /
                    1000;
            } else {
                amounts[i + 1] = getAmountOut(
                    amounts[i],
                    reserveIn,
                    reserveOut
                );
            }
        }
        return amounts;
    }

    // performs chained getAmountIn calculations on any number of pairs
    function getAmountsIn(
        uint256 amountOut,
        address[] memory path,
        uint16[] memory fees
    ) public view returns (uint256[] memory) {
        if (path.length < 2) revert InvalidPath();
        uint256[] memory amounts = new uint256[](path.length);
        amounts[path.length - 1] = amountOut;
        for (uint256 i = path.length - 1; i > 0; i--) {
            (uint256 reserveIn, uint256 reserveOut) = getReserves(
                path[i - 1],
                path[i],
                fees[i - 1]
            );
            if (path[i - 1] == antfarmToken) {
                amounts[i - 1] =
                    (getAmountIn(amounts[i], reserveIn, reserveOut) *
                        (1000 + fees[i - 1])) /
                    1000;
            } else if (path[i] == antfarmToken) {
                amounts[i - 1] = getAmountIn(
                    (amounts[i] * 1000) / (1000 - fees[i - 1]),
                    reserveIn,
                    reserveOut
                );
            } else {
                amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
            }
        }
        return amounts;
    }

    // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
    function getAmountOut(
        uint256 amountIn,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256) {
        if (amountIn == 0) revert InsufficientInputAmount();
        if (reserveIn == 0 || reserveOut == 0) revert InsufficientLiquidity();
        uint256 numerator = amountIn * reserveOut;
        uint256 denominator = reserveIn + amountIn;
        return numerator / denominator;
    }

    // given an output amount of an asset and pair reserves, returns a required input amount of the other asset
    function getAmountIn(
        uint256 amountOut,
        uint256 reserveIn,
        uint256 reserveOut
    ) internal pure returns (uint256) {
        if (amountOut == 0) revert InsufficientOutputAmount();
        if (reserveIn == 0 || reserveOut == 0) revert InsufficientLiquidity();
        uint256 numerator = reserveIn * amountOut;
        uint256 denominator = reserveOut - amountOut;
        return (numerator / denominator) + 1;
    }
}

File 3 of 19 : IAntfarmBase.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "./pair/IAntfarmPairState.sol";
import "./pair/IAntfarmPairEvents.sol";
import "./pair/IAntfarmPairActions.sol";
import "./pair/IAntfarmPairDerivedState.sol";

interface IAntfarmBase is
    IAntfarmPairState,
    IAntfarmPairEvents,
    IAntfarmPairActions,
    IAntfarmPairDerivedState
{}

File 4 of 19 : IAntfarmFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

interface IAntfarmFactory {
    event PairCreated(
        address indexed token0,
        address indexed token1,
        address pair,
        uint16 fee,
        uint256 allPairsLength
    );

    function possibleFees(uint256) external view returns (uint16);

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

    function antfarmToken() external view returns (address);

    function getPairs(uint256 startIndex, uint256 numOfPairs)
        external
        view
        returns (address[] memory, uint256);

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

    function feesForPair(
        address tokenA,
        address tokenB,
        uint256
    ) external view returns (uint16);

    function getFeesForPair(address tokenA, address tokenB)
        external
        view
        returns (uint16[8] memory fees);

    function allPairsLength() external view returns (uint256);

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

File 5 of 19 : IAntfarmPair.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

import "./IAntfarmBase.sol";

interface IAntfarmPair is IAntfarmBase {
    /// @notice Initialize the pair
    /// @dev Can only be called by the factory
    function initialize(
        address,
        address,
        uint16,
        address
    ) external;

    /// @notice The Antfarm token address
    /// @return address Address
    function antfarmToken() external view returns (address);

    /// @notice The Oracle instance used to compute swap's fees
    /// @return AntfarmOracle Oracle instance
    function antfarmOracle() external view returns (address);

    /// @notice Calcul fee to pay
    /// @param amount0Out The token0 amount going out of the pool
    /// @param amount0In The token0 amount going in the pool
    /// @param amount1Out The token1 amount going out of the pool
    /// @param amount1In The token1 amount going in the pool
    /// @return feeToPay Calculated fee to be paid
    function getFees(
        uint256 amount0Out,
        uint256 amount0In,
        uint256 amount1Out,
        uint256 amount1In
    ) external view returns (uint256 feeToPay);

    /// @notice Check for the best Oracle to use to perform fee calculation for a swap
    /// @dev Returns address(0) if no better oracle is found.
    /// @param maxReserve Actual oracle reserve0
    /// @return bestOracle Address from the best oracle found
    function scanOracles(uint112 maxReserve)
        external
        view
        returns (address bestOracle);

    /// @notice Update oracle for token
    /// @custom:usability Update the current Oracle with a more suitable one. Revert if the current Oracle is already the more suitable
    function updateOracle() external;
}

File 6 of 19 : IAntfarmRouter.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

interface IAntfarmRouter {
    function factory() external view returns (address);

    function WETH() external view returns (address);

    function antfarmToken() external view returns (address);

    struct swapParams {
        address[] path;
        uint16[] fees;
        address to;
    }

    struct swapExactTokensForTokensParams {
        uint256 amountIn;
        uint256 amountOutMin;
        uint256 maxFee;
        address[] path;
        uint16[] fees;
        address to;
        uint256 deadline;
    }

    function swapExactTokensForTokens(
        swapExactTokensForTokensParams calldata params
    ) external returns (uint256[] memory amounts);

    struct swapTokensForExactTokensParams {
        uint256 amountOut;
        uint256 amountInMax;
        uint256 maxFee;
        address[] path;
        uint16[] fees;
        address to;
        uint256 deadline;
    }

    function swapTokensForExactTokens(
        swapTokensForExactTokensParams calldata params
    ) external returns (uint256[] memory amounts);

    struct swapExactETHForTokensParams {
        uint256 amountOutMin;
        uint256 maxFee;
        address[] path;
        uint16[] fees;
        address to;
        uint256 deadline;
    }

    function swapExactETHForTokens(swapExactETHForTokensParams calldata params)
        external
        payable
        returns (uint256[] memory amounts);

    struct swapTokensForExactETHParams {
        uint256 amountOut;
        uint256 amountInMax;
        uint256 maxFee;
        address[] path;
        uint16[] fees;
        address to;
        uint256 deadline;
    }

    function swapTokensForExactETH(swapTokensForExactETHParams calldata params)
        external
        returns (uint256[] memory amounts);

    struct swapExactTokensForETHParams {
        uint256 amountIn;
        uint256 amountOutMin;
        uint256 maxFee;
        address[] path;
        uint16[] fees;
        address to;
        uint256 deadline;
    }

    function swapExactTokensForETH(swapExactTokensForETHParams calldata params)
        external
        returns (uint256[] memory amounts);

    struct swapETHForExactTokensParams {
        uint256 amountOut;
        uint256 maxFee;
        address[] path;
        uint16[] fees;
        address to;
        uint256 deadline;
    }

    function swapETHForExactTokens(swapETHForExactTokensParams calldata params)
        external
        payable
        returns (uint256[] memory amounts);

    function swapExactTokensForTokensSupportingFeeOnTransferTokens(
        swapExactTokensForTokensParams calldata params
    ) external;

    function swapExactETHForTokensSupportingFeeOnTransferTokens(
        swapExactETHForTokensParams calldata params
    ) external payable;

    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        swapExactTokensForETHParams calldata params
    ) external;

    // fetches and sorts the reserves for a pair
    function getReserves(
        address tokenA,
        address tokenB,
        uint16 fee
    ) external view returns (uint256 reserveA, uint256 reserveB);
}

File 7 of 19 : IAntfarmToken.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

interface IAntfarmToken {
    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 (uint256);

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

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

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

    function approve(address spender, uint256 amount) external returns (bool);

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

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

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

    function DOMAIN_SEPARATOR() external view returns (bytes32);

    function burn(uint256 _amount) external;
}

File 8 of 19 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

interface IERC20 {
    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 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 (uint256);

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

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

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

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

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

File 9 of 19 : IWETH.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

interface IWETH {
    function deposit() external payable;

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

    function withdraw(uint256) external;
}

File 10 of 19 : IAntfarmPairActions.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

interface IAntfarmPairActions {
    /// @notice Mint liquidity for a specific position
    /// @dev Low-level function. Should be called from another contract which performs all necessary checks
    /// @param to The address to mint liquidity
    /// @param positionId The ID to store the position to allow multiple positions for a single address
    /// @return liquidity Minted liquidity
    function mint(address to, uint256 positionId)
        external
        returns (uint256 liquidity);

    /// @notice Burn liquidity from a specific position
    /// @dev Low-level function. Should be called from another contract which performs all necessary checks
    /// @param to The address to return the liquidity to
    /// @param positionId The ID of the position to burn liquidity from
    /// @param liquidity Liquidity amount to be burned
    /// @return amount0 The token0 amount received from the liquidity burn
    /// @return amount1 The token1 amount received from the liquidity burn
    function burn(
        address to,
        uint256 liquidity,
        uint256 positionId
    ) external returns (uint256 amount0, uint256 amount1);

    /// @notice Swap tokens
    /// @dev Low-level function. Should be called from another contract which performs all necessary checks
    /// @param amount0Out token0 amount to be swapped
    /// @param amount1Out token1 amount to be swapped
    /// @param to The address to send the swapped tokens
    function swap(
        uint256 amount0Out,
        uint256 amount1Out,
        address to
    ) external;

    /// @notice Force balances to match reserves
    /// @param to The address to send excessive tokens
    function skim(address to) external;

    /// @notice Force reserves to match balances
    function sync() external;

    /// @notice Claim dividends for a specific position
    /// @param to The address to receive claimed dividends
    /// @param positionId The ID of the position to claim
    /// @return claimedAmount The amount claimed
    function claimDividend(address to, uint256 positionId)
        external
        returns (uint256 claimedAmount);
}

File 11 of 19 : IAntfarmPairDerivedState.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

interface IAntfarmPairDerivedState {
    /// @notice Get position LP tokens
    /// @param operator Position owner
    /// @param positionId ID of the position
    /// @return uint128 LP tokens owned by the operator
    function getPositionLP(address operator, uint256 positionId)
        external
        view
        returns (uint128);

    /// @notice Get pair reserves
    /// @return reserve0 Reserve for token0
    /// @return reserve1 Reserve for token1
    /// @return blockTimestampLast Last block proceeded
    function getReserves()
        external
        view
        returns (
            uint112 reserve0,
            uint112 reserve1,
            uint32 blockTimestampLast
        );

    /// @notice Get Dividend from a specific position
    /// @param operator The address used to get dividends
    /// @param positionId Specific position
    /// @return amount Dividends owned by the address
    function claimableDividends(address operator, uint256 positionId)
        external
        view
        returns (uint256 amount);
}

File 12 of 19 : IAntfarmPairEvents.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

interface IAntfarmPairEvents {
    /// @notice Emitted when a position's liquidity is removed
    /// @param sender The address that initiated the burn call
    /// @param amount0 The amount of token0 withdrawn
    /// @param amount1 The amount of token1 withdrawn
    /// @param to The address to send token0 & token1
    event Burn(
        address indexed sender,
        uint256 amount0,
        uint256 amount1,
        address indexed to
    );

    /// @notice Emitted when liquidity is minted for a given position
    /// @param sender The address that initiated the mint call
    /// @param amount0 Required token0 for the minted liquidity
    /// @param amount1 Required token1 for the minted liquidity
    event Mint(address indexed sender, uint256 amount0, uint256 amount1);

    /// @notice Emitted by the pool for any swaps between token0 and token1
    /// @param sender The address that initiated the swap call
    /// @param amount0In Amount of token0 sent to the pair
    /// @param amount1In Amount of token1 sent to the pair
    /// @param amount0Out Amount of token0 going out of the pair
    /// @param amount1Out Amount of token1 going out of the pair
    /// @param to Address to transfer the swapped amount
    event Swap(
        address indexed sender,
        uint256 amount0In,
        uint256 amount1In,
        uint256 amount0Out,
        uint256 amount1Out,
        address indexed to
    );

    /// @notice Emitted by the pool for any call to Sync function
    /// @param reserve0 reserve0 updated from the pair
    /// @param reserve1 reserve1 updated from the pair
    event Sync(uint112 reserve0, uint112 reserve1);
}

File 13 of 19 : IAntfarmPairState.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;
import "../IAntfarmToken.sol";

interface IAntfarmPairState {
    /// @notice The contract that deployed the AntfarmPair, which must adhere to the IAntfarmFactory interface
    /// @return address The contract address
    function factory() external view returns (address);

    /// @notice The first of the two tokens of the AntfarmPair, sorted by address
    /// @return address The token contract address
    function token0() external view returns (address);

    /// @notice The second of the two tokens of the AntfarmPair, sorted by address
    /// @return address The token contract address
    function token1() external view returns (address);

    /// @notice Fee associated to the AntfarmPair instance
    /// @return uint16 Fee
    function fee() external view returns (uint16);

    /// @notice The LP tokens total circulating supply
    /// @return uint Total LP tokens
    function totalSupply() external view returns (uint256);

    /// @notice The AntFarmPair AntFarm's tokens cumulated fees
    /// @return uint Total Antfarm tokens
    function antfarmTokenReserve() external view returns (uint256);
}

File 14 of 19 : Babylonian.sol
// SPDX-License-Identifier: GPL-3.0-or-later

pragma solidity >=0.8.0;

// computes square roots using the babylonian method
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
library Babylonian {
    // credit for this implementation goes to
    // https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol#L687
    function sqrt(uint256 x) internal pure returns (uint256) {
        if (x == 0) return 0;
        // this block is equivalent to r = uint256(1) << (BitMath.mostSignificantBit(x) / 2);
        // however that code costs significantly more gas
        uint256 xx = x;
        uint256 r = 1;
        if (xx >= 0x100000000000000000000000000000000) {
            xx >>= 128;
            r <<= 64;
        }
        if (xx >= 0x10000000000000000) {
            xx >>= 64;
            r <<= 32;
        }
        if (xx >= 0x100000000) {
            xx >>= 32;
            r <<= 16;
        }
        if (xx >= 0x10000) {
            xx >>= 16;
            r <<= 8;
        }
        if (xx >= 0x100) {
            xx >>= 8;
            r <<= 4;
        }
        if (xx >= 0x10) {
            xx >>= 4;
            r <<= 2;
        }
        if (xx >= 0x8) {
            r <<= 1;
        }
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1; // Seven iterations should be enough
        uint256 r1 = x / r;
        return (r < r1 ? r : r1);
    }
}

File 15 of 19 : BitMath.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.0;

library BitMath {
    // returns the 0 indexed position of the most significant bit of the input x
    // s.t. x >= 2**msb and x < 2**(msb+1)
    function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
        require(x > 0, "BitMath::mostSignificantBit: zero");

        if (x >= 0x100000000000000000000000000000000) {
            x >>= 128;
            r += 128;
        }
        if (x >= 0x10000000000000000) {
            x >>= 64;
            r += 64;
        }
        if (x >= 0x100000000) {
            x >>= 32;
            r += 32;
        }
        if (x >= 0x10000) {
            x >>= 16;
            r += 16;
        }
        if (x >= 0x100) {
            x >>= 8;
            r += 8;
        }
        if (x >= 0x10) {
            x >>= 4;
            r += 4;
        }
        if (x >= 0x4) {
            x >>= 2;
            r += 2;
        }
        if (x >= 0x2) r += 1;
    }

    // returns the 0 indexed position of the least significant bit of the input x
    // s.t. (x & 2**lsb) != 0 and (x & (2**(lsb) - 1)) == 0)
    // i.e. the bit at the index is set and the mask of all lower bits is 0
    function leastSignificantBit(uint256 x) internal pure returns (uint8 r) {
        require(x > 0, "BitMath::leastSignificantBit: zero");

        r = 255;
        if (x & type(uint128).max > 0) {
            r -= 128;
        } else {
            x >>= 128;
        }
        if (x & type(uint64).max > 0) {
            r -= 64;
        } else {
            x >>= 64;
        }
        if (x & type(uint32).max > 0) {
            r -= 32;
        } else {
            x >>= 32;
        }
        if (x & type(uint16).max > 0) {
            r -= 16;
        } else {
            x >>= 16;
        }
        if (x & type(uint16).max > 0) {
            r -= 8;
        } else {
            x >>= 8;
        }
        if (x & 0xf > 0) {
            r -= 4;
        } else {
            x >>= 4;
        }
        if (x & 0x3 > 0) {
            r -= 2;
        } else {
            x >>= 2;
        }
        if (x & 0x1 > 0) r -= 1;
    }
}

File 16 of 19 : FixedPoint.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity >=0.8.0;

import "./FullMath.sol";
import "./Babylonian.sol";
import "./BitMath.sol";

// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
library FixedPoint {
    // range: [0, 2**112 - 1]
    // resolution: 1 / 2**112
    struct uq112x112 {
        uint224 _x;
    }

    // range: [0, 2**144 - 1]
    // resolution: 1 / 2**112
    struct uq144x112 {
        uint256 _x;
    }

    uint8 public constant RESOLUTION = 112;
    uint256 public constant Q112 = 0x10000000000000000000000000000; // 2**112
    uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000; // 2**224
    uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)

    // encode a uint112 as a UQ112x112
    function encode(uint112 x) internal pure returns (uq112x112 memory) {
        return uq112x112(uint224(x) << RESOLUTION);
    }

    // encodes a uint144 as a UQ144x112
    function encode144(uint144 x) internal pure returns (uq144x112 memory) {
        return uq144x112(uint256(x) << RESOLUTION);
    }

    // decode a UQ112x112 into a uint112 by truncating after the radix point
    function decode(uq112x112 memory self) internal pure returns (uint112) {
        return uint112(self._x >> RESOLUTION);
    }

    // decode a UQ144x112 into a uint144 by truncating after the radix point
    function decode144(uq144x112 memory self) internal pure returns (uint144) {
        return uint144(self._x >> RESOLUTION);
    }

    // multiply a UQ112x112 by a uint, returning a UQ144x112
    // reverts on overflow
    function mul(uq112x112 memory self, uint256 y) internal pure returns (uq144x112 memory) {
        uint256 z = 0;
        require(y == 0 || (z = self._x * y) / y == self._x, "FixedPoint::mul: overflow");
        return uq144x112(z);
    }

    // multiply a UQ112x112 by an int and decode, returning an int
    // reverts on overflow
    function muli(uq112x112 memory self, int256 y) internal pure returns (int256) {
        uint256 z = FullMath.mulDiv(self._x, uint256(y < 0 ? -y : y), Q112);
        require(z < 2**255, "FixedPoint::muli: overflow");
        return y < 0 ? -int256(z) : int256(z);
    }

    // multiply a UQ112x112 by a UQ112x112, returning a UQ112x112
    // lossy
    function muluq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) {
        if (self._x == 0 || other._x == 0) {
            return uq112x112(0);
        }
        uint112 upper_self = uint112(self._x >> RESOLUTION); // * 2^0
        uint112 lower_self = uint112(self._x & LOWER_MASK); // * 2^-112
        uint112 upper_other = uint112(other._x >> RESOLUTION); // * 2^0
        uint112 lower_other = uint112(other._x & LOWER_MASK); // * 2^-112

        // partial products
        uint224 upper = uint224(upper_self) * upper_other; // * 2^0
        uint224 lower = uint224(lower_self) * lower_other; // * 2^-224
        uint224 uppers_lowero = uint224(upper_self) * lower_other; // * 2^-112
        uint224 uppero_lowers = uint224(upper_other) * lower_self; // * 2^-112

        // so the bit shift does not overflow
        require(upper <= type(uint112).max, "FixedPoint::muluq: upper overflow");

        // this cannot exceed 256 bits, all values are 224 bits
        uint256 sum = uint256(upper << RESOLUTION) + uppers_lowero + uppero_lowers + (lower >> RESOLUTION);

        // so the cast does not overflow
        require(sum <= type(uint224).max, "FixedPoint::muluq: sum overflow");

        return uq112x112(uint224(sum));
    }

    // divide a UQ112x112 by a UQ112x112, returning a UQ112x112
    function divuq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) {
        require(other._x > 0, "FixedPoint::divuq: division by zero");
        if (self._x == other._x) {
            return uq112x112(uint224(Q112));
        }
        if (self._x <= type(uint144).max) {
            uint256 value = (uint256(self._x) << RESOLUTION) / other._x;
            require(value <= type(uint224).max, "FixedPoint::divuq: overflow");
            return uq112x112(uint224(value));
        }

        uint256 result = FullMath.mulDiv(Q112, self._x, other._x);
        require(result <= type(uint224).max, "FixedPoint::divuq: overflow");
        return uq112x112(uint224(result));
    }

    // returns a UQ112x112 which represents the ratio of the numerator to the denominator
    // can be lossy
    function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) {
        require(denominator > 0, "FixedPoint::fraction: division by zero");
        if (numerator == 0) return FixedPoint.uq112x112(0);

        if (numerator <= type(uint144).max) {
            uint256 result = (numerator << RESOLUTION) / denominator;
            require(result <= type(uint224).max, "FixedPoint::fraction: overflow");
            return uq112x112(uint224(result));
        } else {
            uint256 result = FullMath.mulDiv(numerator, Q112, denominator);
            require(result <= type(uint224).max, "FixedPoint::fraction: overflow");
            return uq112x112(uint224(result));
        }
    }

    // take the reciprocal of a UQ112x112
    // reverts on overflow
    // lossy
    function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) {
        require(self._x != 0, "FixedPoint::reciprocal: reciprocal of zero");
        require(self._x != 1, "FixedPoint::reciprocal: overflow");
        return uq112x112(uint224(Q224 / self._x));
    }

    // square root of a UQ112x112
    // lossy between 0/1 and 40 bits
    function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {
        if (self._x <= type(uint144).max) {
            return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112)));
        }

        uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);
        safeShiftBits -= safeShiftBits % 2;
        return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2)));
    }
}

File 17 of 19 : FullMath.sol
// SPDX-License-Identifier: CC-BY-4.0
pragma solidity >=0.8.0;

// taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1
// license is CC-BY-4.0
library FullMath {
    function fullMul(uint256 x, uint256 y) internal pure returns (uint256 l, uint256 h) {
        uint256 mm = mulmod(x, y, type(uint256).max);
        l = x * y;
        h = mm - l;
        if (mm < l) h -= 1;
    }

    function fullDiv(
        uint256 l,
        uint256 h,
        uint256 d
    ) private pure returns (uint256) {
        uint256 pow2 = d & (type(uint256).max - d + 1) & d;
        d /= pow2;
        l /= pow2;
        l += h * (((type(uint256).max - pow2 + 1) & pow2) / pow2 + 1);
        uint256 r = 1;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        r *= 2 - d * r;
        return l * r;
    }

    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 d
    ) internal pure returns (uint256) {
        (uint256 l, uint256 h) = fullMul(x, y);

        uint256 mm = mulmod(x, y, d);
        if (mm > l) h -= 1;
        l -= mm;

        if (h == 0) return l / d;

        require(h < d, "FullMath: FULLDIV_OVERFLOW");
        return fullDiv(l, h, d);
    }
}

File 18 of 19 : TransferHelper.sol
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity =0.8.10;

// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
    function safeApprove(
        address token,
        address to,
        uint256 value
    ) internal {
        // bytes4(keccak256(bytes("approve(address,uint256)")));
        (bool success, bytes memory data) = token.call(
            abi.encodeWithSelector(0x095ea7b3, to, value)
        );
        require(
            success && (data.length == 0 || abi.decode(data, (bool))),
            "TransferHelper::safeApprove: approve failed"
        );
    }

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

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

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

File 19 of 19 : AntfarmRouterErrors.sol
// SPDX-License-Identifier: MIT
pragma solidity =0.8.10;

error Expired();
error InsufficientOutputAmount();
error InsufficientInputAmount();
error InsufficientLiquidity();
error InsufficientMaxFee();
error ExcessiveInputAmount();
error InvalidPath();
error IdenticalAddresses();
error ZeroAddress();

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"address","name":"_antfarmToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ExcessiveInputAmount","type":"error"},{"inputs":[],"name":"Expired","type":"error"},{"inputs":[],"name":"IdenticalAddresses","type":"error"},{"inputs":[],"name":"InsufficientInputAmount","type":"error"},{"inputs":[],"name":"InsufficientLiquidity","type":"error"},{"inputs":[],"name":"InsufficientMaxFee","type":"error"},{"inputs":[],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"InvalidPath","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"antfarmToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint16","name":"fee","type":"uint16"}],"name":"getReserves","outputs":[{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint16","name":"fee","type":"uint16"}],"name":"pairFor","outputs":[{"internalType":"address","name":"pair","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapETHForExactTokensParams","name":"params","type":"tuple"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapExactETHForTokensParams","name":"params","type":"tuple"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapExactETHForTokensParams","name":"params","type":"tuple"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapExactTokensForETHParams","name":"params","type":"tuple"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapExactTokensForETHParams","name":"params","type":"tuple"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapExactTokensForTokensParams","name":"params","type":"tuple"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapExactTokensForTokensParams","name":"params","type":"tuple"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapTokensForExactETHParams","name":"params","type":"tuple"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"uint256","name":"maxFee","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint16[]","name":"fees","type":"uint16[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IAntfarmRouter.swapTokensForExactTokensParams","name":"params","type":"tuple"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60e06040523480156200001157600080fd5b506040516200417c3803806200417c833981016040819052620000349162000162565b6001600160a01b038316620000905760405162461bcd60e51b815260206004820152601460248201527f4e554c4c5f464143544f52595f4144445245535300000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b038216620000dc5760405162461bcd60e51b81526020600482015260116024820152704e554c4c5f574554485f4144445245535360781b604482015260640162000087565b6001600160a01b038116620001275760405162461bcd60e51b815260206004820152601060248201526f4e554c4c5f4154465f4144445245535360801b604482015260640162000087565b6001600160a01b0392831660805290821660a0521660c052620001ac565b80516001600160a01b03811681146200015d57600080fd5b919050565b6000806000606084860312156200017857600080fd5b620001838462000145565b9250620001936020850162000145565b9150620001a36040850162000145565b90509250925092565b60805160a05160c051613e88620002f4600039600081816102ca015281816108f001528181610cdf01528181610fd10152818161129a0152818161138c0152818161196d01528181611a5b01528181611cb201528181611d1b015281816124ac01528181612b4401528181612ba401528181612c4c01528181612cc101528181612dda015281816131c00152818161323501528181613382015281816136d7015281816137120152818161374d0152818161378601526137ad01526000818161010701528181610296015281816103c301528181610444015281816104b801528181610c4101528181610eb8015281816114ea015281816115f40152818161168201528181611e2a01528181611f4301528181611fd10152818161257b0152818161269b0152818161282001526128e90152600081816102fe0152611ce00152613e886000f3fe6080604052600436106100f75760003560e01c8063a502d3a01161008a578063cd0ba5df11610059578063cd0ba5df14610320578063d2a4949a14610333578063e80d2b3414610353578063ef1c88fb1461037357600080fd5b8063a502d3a01461024c578063ad5c464814610284578063c12a00a8146102b8578063c45a0155146102ec57600080fd5b80635ec70f5d116100c65780635ec70f5d146101c4578063636f5e0e146101e45780636451737d146101f7578063951eb42d1461021757600080fd5b80630438c45e1461013b57806305f9b6271461014e578063164d01be1461018457806359c90959146101a457600080fd5b3661013657336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461013457610134613855565b005b600080fd5b61013461014936600461387d565b610393565b34801561015a57600080fd5b5061016e6101693660046138cc565b6108bc565b60405161017b9190613901565b60405180910390f35b34801561019057600080fd5b5061016e61019f3660046138cc565b610c0f565b3480156101b057600080fd5b5061016e6101bf3660046138cc565b610f9d565b3480156101d057600080fd5b5061016e6101df366004613a50565b61116a565b61016e6101f236600461387d565b6114b8565b34801561020357600080fd5b5061016e610212366004613a50565b61186a565b34801561022357600080fd5b50610237610232366004613b1b565b611b76565b6040805192835260208301919091520161017b565b34801561025857600080fd5b5061026c610267366004613b1b565b611c4e565b6040516001600160a01b03909116815260200161017b565b34801561029057600080fd5b5061026c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c457600080fd5b5061026c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102f857600080fd5b5061026c7f000000000000000000000000000000000000000000000000000000000000000081565b61016e61032e36600461387d565b611df8565b34801561033f57600080fd5b5061013461034e3660046138cc565b6120e1565b34801561035f57600080fd5b5061016e61036e3660046138cc565b612478565b34801561037f57600080fd5b5061013461038e3660046138cc565b61266b565b8060a00135428110156103b957604051630407b05b60e31b815260040160405180910390fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166103f06040840184613b5e565b600081811061040157610401613ba8565b90506020020160208101906104169190613bbe565b6001600160a01b03161461043d576040516320db826760e01b815260040160405180910390fd5b60003490507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561049d57600080fd5b505af11580156104b1573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6105848580604001906104f89190613b5e565b600081811061050957610509613ba8565b905060200201602081019061051e9190613bbe565b61052b6040880188613b5e565b600181811061053c5761053c613ba8565b90506020020160208101906105519190613bbe565b61055e6060890189613b5e565b600081811061056f5761056f613ba8565b90506020020160208101906102679190613be0565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602481018490526044016020604051808303816000875af11580156105d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105f59190613bfb565b61060157610601613855565b60006106106040850185613b5e565b600161061f6040880188613b5e565b61062a929150613c33565b81811061063957610639613ba8565b905060200201602081019061064e9190613bbe565b6001600160a01b03166370a0823161066c60a0870160808801613bbe565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa1580156106b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d49190613c4a565b9050600060405180606001604052808680604001906106f39190613b5e565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506020016107376060880188613b5e565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060200161077e60a0880160808901613bbe565b6001600160a01b031690529050602085013561079982612968565b11156107b857604051634b41cb4560e01b815260040160405180910390fd5b8435826107c86040880188613b5e565b60016107d760408b018b613b5e565b6107e2929150613c33565b8181106107f1576107f1613ba8565b90506020020160208101906108069190613bbe565b6001600160a01b03166370a0823161082460a08a0160808b01613bbe565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061088c9190613c4a565b6108969190613c33565b10156108b5576040516342301c2360e01b815260040160405180910390fd5b5050505050565b60608160c00135428110156108e457604051630407b05b60e31b815260040160405180910390fd5b60006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001661091d6060860186613b5e565b600081811061092e5761092e613ba8565b90506020020160208101906109439190613bbe565b6001600160a01b03161461095b5783602001356109b9565b6103e861096b6080860186613b5e565b600081811061097c5761097c613ba8565b90506020020160208101906109919190613be0565b61099d906103e8613c63565b6109af9061ffff166020870135613c89565b6109b99190613ca8565b9050610a4384356109cd6060870187613b5e565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610a0c925050506080880188613b5e565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061116a92505050565b92508083600081518110610a5957610a59613ba8565b60200260200101511115610a805760405163e1b0da4f60e01b815260040160405180910390fd5b610b4d610a906060860186613b5e565b6000818110610aa157610aa1613ba8565b9050602002016020810190610ab69190613bbe565b33610b2d610ac76060890189613b5e565b6000818110610ad857610ad8613ba8565b9050602002016020810190610aed9190613bbe565b610afa60608a018a613b5e565b6001818110610b0b57610b0b613ba8565b9050602002016020810190610b209190613bbe565b61055e60808b018b613b5e565b86600081518110610b4057610b40613ba8565b6020026020010151612f15565b6040840135610be984610b636060880188613b5e565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610ba2925050506080890189613b5e565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610be49250505060c08a0160a08b01613bbe565b613092565b1115610c0857604051634b41cb4560e01b815260040160405180910390fd5b5050919050565b60608160c0013542811015610c3757604051630407b05b60e31b815260040160405180910390fd5b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016610c6e6060850185613b5e565b6001610c7d6060880188613b5e565b610c88929150613c33565b818110610c9757610c97613ba8565b9050602002016020810190610cac9190613bbe565b6001600160a01b031614610cd3576040516320db826760e01b815260040160405180910390fd5b60006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016610d0c6060860186613b5e565b6000818110610d1d57610d1d613ba8565b9050602002016020810190610d329190613bbe565b6001600160a01b031614610d4a578360200135610da8565b6103e8610d5a6080860186613b5e565b6000818110610d6b57610d6b613ba8565b9050602002016020810190610d809190613be0565b610d8c906103e8613c63565b610d9e9061ffff166020870135613c89565b610da89190613ca8565b9050610dbc84356109cd6060870187613b5e565b92508083600081518110610dd257610dd2613ba8565b60200260200101511115610df95760405163e1b0da4f60e01b815260040160405180910390fd5b610e09610a906060860186613b5e565b6040840135610e9784610e1f6060880188613b5e565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610e5e925050506080890189613b5e565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250309250613092915050565b1115610eb657604051634b41cb4560e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316632e1a7d4d8460018651610ef49190613c33565b81518110610f0457610f04613ba8565b60200260200101516040518263ffffffff1660e01b8152600401610f2a91815260200190565b600060405180830381600087803b158015610f4457600080fd5b505af1158015610f58573d6000803e3d6000fd5b50610c089250610f7191505060c0860160a08701613bbe565b8460018651610f809190613c33565b81518110610f9057610f90613ba8565b6020026020010151613492565b60608160c0013542811015610fc557604051630407b05b60e31b815260040160405180910390fd5b60006001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016610ffe6060860186613b5e565b600081811061100f5761100f613ba8565b90506020020160208101906110249190613bbe565b6001600160a01b031614611039578335611094565b6103e86110496080860186613b5e565b600081811061105a5761105a613ba8565b905060200201602081019061106f9190613be0565b61107b906103e8613c63565b61108a9061ffff168635613c89565b6110949190613ca8565b905061111d816110a76060870187613b5e565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506110e6925050506080880188613b5e565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061186a92505050565b9250836020013583600185516111339190613c33565b8151811061114357611143613ba8565b60200260200101511015610a80576040516342301c2360e01b815260040160405180910390fd5b606060028351101561118f576040516320db826760e01b815260040160405180910390fd5b6000835167ffffffffffffffff8111156111ab576111ab613945565b6040519080825280602002602001820160405280156111d4578160200160208202803683370190505b5090508481600186516111e79190613c33565b815181106111f7576111f7613ba8565b6020026020010181815250506000600185516112139190613c33565b90505b80156114af5760008061128b8761122e600186613c33565b8151811061123e5761123e613ba8565b602002602001015188858151811061125857611258613ba8565b60200260200101518860018761126e9190613c33565b8151811061127e5761127e613ba8565b6020026020010151611b76565b90925090506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016876112c6600186613c33565b815181106112d6576112d6613ba8565b60200260200101516001600160a01b0316141561138a576103e8866112fc600186613c33565b8151811061130c5761130c613ba8565b60200260200101516103e86113219190613c63565b61ffff1661134986868151811061133a5761133a613ba8565b6020026020010151858561357a565b6113539190613c89565b61135d9190613ca8565b84611369600186613c33565b8151811061137957611379613ba8565b60200260200101818152505061149a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168784815181106113c6576113c6613ba8565b60200260200101516001600160a01b0316141561144d5761135d866113ec600186613c33565b815181106113fc576113fc613ba8565b60200260200101516103e86114119190613cca565b61ffff1685858151811061142757611427613ba8565b60200260200101516103e861143c9190613c89565b6114469190613ca8565b838361357a565b61147184848151811061146257611462613ba8565b6020026020010151838361357a565b8461147d600186613c33565b8151811061148d5761148d613ba8565b6020026020010181815250505b505080806114a790613ced565b915050611216565b50949350505050565b60608160a00135428110156114e057604051630407b05b60e31b815260040160405180910390fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166115176040850185613b5e565b600081811061152857611528613ba8565b905060200201602081019061153d9190613bbe565b6001600160a01b031614611564576040516320db826760e01b815260040160405180910390fd5b6115b583356115766040860186613b5e565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610a0c925050506060870187613b5e565b915034826000815181106115cb576115cb613ba8565b602002602001015111156115f25760405163e1b0da4f60e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db08360008151811061163457611634613ba8565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b15801561166757600080fd5b505af115801561167b573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6116c28580604001906104f89190613b5e565b846000815181106116d5576116d5613ba8565b60200260200101516040518363ffffffff1660e01b815260040161170e9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af115801561172d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117519190613bfb565b61175d5761175d613855565b60208301356117f4836117736040870187613b5e565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506117b2925050506060880188613b5e565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250610be49250505060a0890160808a01613bbe565b111561181357604051634b41cb4560e01b815260040160405180910390fd5b8160008151811061182657611826613ba8565b602002602001015134111561186457611864338360008151811061184c5761184c613ba8565b60200260200101513461185f9190613c33565b613492565b50919050565b606060028351101561188f576040516320db826760e01b815260040160405180910390fd5b6000835167ffffffffffffffff8111156118ab576118ab613945565b6040519080825280602002602001820160405280156118d4578160200160208202803683370190505b50905084816000815181106118eb576118eb613ba8565b60200260200101818152505060005b600185516119089190613c33565b8110156114af5760008061196787848151811061192757611927613ba8565b60200260200101518885600161193d9190613d04565b8151811061194d5761194d613ba8565b602002602001015188868151811061127e5761127e613ba8565b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168784815181106119a7576119a7613ba8565b60200260200101516001600160a01b03161415611a5157611a248684815181106119d3576119d3613ba8565b60200260200101516103e86119e89190613c63565b61ffff168585815181106119fe576119fe613ba8565b60200260200101516103e8611a139190613c89565b611a1d9190613ca8565b83836135fe565b84611a30856001613d04565b81518110611a4057611a40613ba8565b602002602001018181525050611b61565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001687611a87856001613d04565b81518110611a9757611a97613ba8565b60200260200101516001600160a01b03161415611b14576103e8868481518110611ac357611ac3613ba8565b60200260200101516103e8611ad89190613cca565b61ffff16611b00868681518110611af157611af1613ba8565b602002602001015185856135fe565b611b0a9190613c89565b611a249190613ca8565b611b38848481518110611b2957611b29613ba8565b602002602001015183836135fe565b84611b44856001613d04565b81518110611b5457611b54613ba8565b6020026020010181815250505b50508080611b6e90613d1c565b9150506118fa565b6000806000611b858686613686565b509050600080611b96888888611c4e565b6001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bf79190613d55565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150826001600160a01b0316886001600160a01b031614611c3c578082611c3f565b81815b90999098509650505050505050565b6000806000611c5d8686613686565b6040516bffffffffffffffffffffffff19606084811b8216602084015283811b821660348401527fffff00000000000000000000000000000000000000000000000000000000000060f08a901b1660488401527f0000000000000000000000000000000000000000000000000000000000000000901b16604a82015291935091507f000000000000000000000000000000000000000000000000000000000000000090605e01604051602081830303815290604052805190602001207f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614611d8d576040518060400160405280602081526020017f3b29ecd4cb06592a81cac4799fb24ef6a176fe95ecb50f304972882b150f3f3a815250611dc4565b6040518060400160405280602081526020017f99c189a5ef3d337612cf0ce2bd055546e23b91fea9e9e54201b23f14d763f3338152505b604051602001611dd693929190613dd1565b60408051601f1981840301815291905280516020909101209695505050505050565b60608160a0013542811015611e2057604051630407b05b60e31b815260040160405180910390fd5b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016611e576040850185613b5e565b6000818110611e6857611e68613ba8565b9050602002016020810190611e7d9190613bbe565b6001600160a01b031614611ea4576040516320db826760e01b815260040160405180910390fd5b611ef434611eb56040860186613b5e565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506110e6925050506060870187613b5e565b915082600001358260018451611f0a9190613c33565b81518110611f1a57611f1a613ba8565b60200260200101511015611f41576040516342301c2360e01b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db083600081518110611f8357611f83613ba8565b60200260200101516040518263ffffffff1660e01b81526004016000604051808303818588803b158015611fb657600080fd5b505af1158015611fca573d6000803e3d6000fd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6120118580604001906104f89190613b5e565b8460008151811061202457612024613ba8565b60200260200101516040518363ffffffff1660e01b815260040161205d9291906001600160a01b03929092168252602082015260400190565b6020604051808303816000875af115801561207c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a09190613bfb565b6120ac576120ac613855565b60208301356120c2836117736040870187613b5e565b111561186457604051634b41cb4560e01b815260040160405180910390fd5b8060c001354281101561210757604051630407b05b60e31b815260040160405180910390fd5b6121bb6121176060840184613b5e565b600081811061212857612128613ba8565b905060200201602081019061213d9190613bbe565b336121b461214e6060870187613b5e565b600081811061215f5761215f613ba8565b90506020020160208101906121749190613bbe565b6121816060880188613b5e565b600181811061219257612192613ba8565b90506020020160208101906121a79190613bbe565b61055e6080890189613b5e565b8535612f15565b60006121ca6060840184613b5e565b60016121d96060870187613b5e565b6121e4929150613c33565b8181106121f3576121f3613ba8565b90506020020160208101906122089190613bbe565b6001600160a01b03166370a0823161222660c0860160a08701613bbe565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa15801561226a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061228e9190613c4a565b9050600060405180606001604052808580606001906122ad9190613b5e565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506020016122f16080870187613b5e565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060200161233860c0870160a08801613bbe565b6001600160a01b031690529050604084013561235382612968565b111561237257604051634b41cb4560e01b815260040160405180910390fd5b6020840135826123856060870187613b5e565b600161239460608a018a613b5e565b61239f929150613c33565b8181106123ae576123ae613ba8565b90506020020160208101906123c39190613bbe565b6001600160a01b03166370a082316123e160c0890160a08a01613bbe565b6040516001600160e01b031960e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015612425573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124499190613c4a565b6124539190613c33565b1015612472576040516342301c2360e01b815260040160405180910390fd5b50505050565b60608160c00135428110156124a057604051630407b05b60e31b815260040160405180910390fd5b60006001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166124d96060860186613b5e565b60008181106124ea576124ea613ba8565b90506020020160208101906124ff9190613bbe565b6001600160a01b03161461251457833561256f565b6103e86125246080860186613b5e565b600081811061253557612535613ba8565b905060200201602081019061254a9190613be0565b612556906103e8613c63565b6125659061ffff168635613c89565b61256f9190613ca8565b90506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166125a86060860186613b5e565b60016125b76060890189613b5e565b6125c2929150613c33565b8181106125d1576125d1613ba8565b90506020020160208101906125e69190613bbe565b6001600160a01b03161461260d576040516320db826760e01b815260040160405180910390fd5b61261e816110a76060870187613b5e565b9250836020013583600185516126349190613c33565b8151811061264457612644613ba8565b60200260200101511015610df9576040516342301c2360e01b815260040160405180910390fd5b8060c001354281101561269157604051630407b05b60e31b815260040160405180910390fd5b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166126c86060840184613b5e565b60016126d76060870187613b5e565b6126e2929150613c33565b8181106126f1576126f1613ba8565b90506020020160208101906127069190613bbe565b6001600160a01b03161461272d576040516320db826760e01b815260040160405180910390fd5b61273d6121176060840184613b5e565b6000604051806060016040528084806060019061275a9190613b5e565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060200161279e6080860186613b5e565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525030602090910152905060408301356127e982612968565b111561280857604051634b41cb4560e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190613c4a565b905083602001358110156128ba576040516342301c2360e01b815260040160405180910390fd5b6040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561293557600080fd5b505af1158015612949573d6000803e3d6000fd5b50612472925061296291505060c0860160a08701613bbe565b82613492565b6000805b82515161297b90600190613c33565b811015611864576000808460000151838151811061299b5761299b613ba8565b602002602001015185600001518460016129b59190613d04565b815181106129c5576129c5613ba8565b6020026020010151915091506000856020015184815181106129e9576129e9613ba8565b602002602001015190506000612a00848484611c4e565b90506000612a0e8585613686565b509050600080600080856001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612a55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a799190613d55565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff169150600080866001600160a01b03168b6001600160a01b031614612ac1578284612ac4565b83835b6040516370a0823160e01b81526001600160a01b038b8116600483015292945090925083918d16906370a0823190602401602060405180830381865afa158015612b12573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b369190613c4a565b612b409190613c33565b95507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168b6001600160a01b03161415612ba257612b9b612b8b8a6103e8613c63565b61ffff16611a13886103e8613c89565b9450612c1a565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168a6001600160a01b03161415612c0c576103e8612be98a82613cca565b61ffff16612bf88885856135fe565b612c029190613c89565b612b9b9190613ca8565b612c178683836135fe565b94505b50505050600080846001600160a01b0316896001600160a01b031614612c4257826000612c46565b6000835b915091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316896001600160a01b03161415612cbf57612c90876103e8613c63565b61ffff168761ffff1685612ca49190613c89565b612cae9190613ca8565b612cb8908c613d04565b9a50612e0f565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316886001600160a01b03161415612d0a576103e8612ca461ffff891686613c89565b6000866001600160a01b0316632f72563884886001600160a01b03168d6001600160a01b031614612d3c576000612d3e565b875b858a6001600160a01b03168f6001600160a01b031614612d5e5789612d61565b60005b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401602060405180830381865afa158015612daf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612dd39190613c4a565b9050612e017f0000000000000000000000000000000000000000000000000000000000000000338984612f15565b612e0b818d613d04565b9b50505b8b5151600090612e2190600290613c33565b8b10612e31578c60400151612e8b565b8c51612e8b908a90612e448e6002613d04565b81518110612e5457612e54613ba8565b60200260200101518f602001518e6001612e6e9190613d04565b81518110612e7e57612e7e613ba8565b6020026020010151611c4e565b6040516336cd320560e11b815260048101859052602481018490526001600160a01b03808316604483015291925090881690636d9a640a90606401600060405180830381600087803b158015612ee057600080fd5b505af1158015612ef4573d6000803e3d6000fd5b50505050505050505050505050508080612f0d90613d1c565b91505061296c565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691612fa79190613e36565b6000604051808303816000865af19150503d8060008114612fe4576040519150601f19603f3d011682016040523d82523d6000602084013e612fe9565b606091505b50915091508180156130135750805115806130135750808060200190518101906130139190613bfb565b61308a5760405162461bcd60e51b815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c656400000000000000000000000000000060648201526084015b60405180910390fd5b505050505050565b6000805b600185516130a49190613c33565b8110156114af576000808683815181106130c0576130c0613ba8565b6020026020010151878460016130d69190613d04565b815181106130e6576130e6613ba8565b602002602001015191509150600086848151811061310657613106613ba8565b60200260200101519050600061311d848484611c4e565b9050600061312b8585613686565b509050600080826001600160a01b0316876001600160a01b031614613175578c613156896001613d04565b8151811061316657613166613ba8565b6020026020010151600061319c565b60008d6131838a6001613d04565b8151811061319357613193613ba8565b60200260200101515b9150915060008d89815181106131b4576131b4613ba8565b602002602001015190507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316886001600160a01b0316141561323357613204866103e8613c63565b61ffff168661ffff16826132189190613c89565b6132229190613ca8565b61322c908b613d04565b99506133b7565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614156132b257613279866103e8613cca565b61ffff168661ffff168f8b60016132909190613d04565b815181106132a0576132a0613ba8565b60200260200101516132189190613c89565b6000856001600160a01b0316632f72563885876001600160a01b03168c6001600160a01b0316146132e45760006132e6565b845b86896001600160a01b03168e6001600160a01b0316146133065786613309565b60005b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401602060405180830381865afa158015613357573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061337b9190613c4a565b90506133a97f0000000000000000000000000000000000000000000000000000000000000000338884612f15565b6133b3818c613d04565b9a50505b50600060028d516133c89190613c33565b89106133d4578a61340a565b61340a878e6133e48c6002613d04565b815181106133f4576133f4613ba8565b60200260200101518e8c6001612e6e9190613d04565b6040516336cd320560e11b815260048101859052602481018490526001600160a01b03808316604483015291925090861690636d9a640a90606401600060405180830381600087803b15801561345f57600080fd5b505af1158015613473573d6000803e3d6000fd5b505050505050505050505050808061348a90613d1c565b915050613096565b604080516000808252602082019092526001600160a01b0384169083906040516134bc9190613e36565b60006040518083038185875af1925050503d80600081146134f9576040519150601f19603f3d011682016040523d82523d6000602084013e6134fe565b606091505b50509050806135755760405162461bcd60e51b815260206004820152603460248201527f5472616e7366657248656c7065723a3a736166655472616e736665724554483a60448201527f20455448207472616e73666572206661696c65640000000000000000000000006064820152608401613081565b505050565b60008361359a576040516342301c2360e01b815260040160405180910390fd5b8215806135a5575081155b156135c35760405163bb55fd2760e01b815260040160405180910390fd5b60006135cf8585613c89565b905060006135dd8685613c33565b90506135e98183613ca8565b6135f4906001613d04565b9695505050505050565b600083613637576040517f098fb56100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b821580613642575081155b156136605760405163bb55fd2760e01b815260040160405180910390fd5b600061366c8386613c89565b9050600061367a8686613d04565b90506135f48183613ca8565b600080826001600160a01b0316846001600160a01b031614156136d5576040517fbd969eb000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316148061374657507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316145b156137ff577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316146137ab577f0000000000000000000000000000000000000000000000000000000000000000846137ce565b7f0000000000000000000000000000000000000000000000000000000000000000835b90925090506001600160a01b0381166137fa5760405163d92e233d60e01b815260040160405180910390fd5b61384e565b826001600160a01b0316846001600160a01b03161061381f578284613822565b83835b90925090506001600160a01b03821661384e5760405163d92e233d60e01b815260040160405180910390fd5b9250929050565b634e487b7160e01b600052600160045260246000fd5b600060c0828403121561186457600080fd5b60006020828403121561388f57600080fd5b813567ffffffffffffffff8111156138a657600080fd5b6138b28482850161386b565b949350505050565b600060e0828403121561186457600080fd5b6000602082840312156138de57600080fd5b813567ffffffffffffffff8111156138f557600080fd5b6138b2848285016138ba565b6020808252825182820181905260009190848201906040850190845b818110156139395783518352928401929184019160010161391d565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561398457613984613945565b604052919050565b600067ffffffffffffffff8211156139a6576139a6613945565b5060051b60200190565b80356001600160a01b03811681146139c757600080fd5b919050565b803561ffff811681146139c757600080fd5b600082601f8301126139ef57600080fd5b81356020613a046139ff8361398c565b61395b565b82815260059290921b84018101918181019086841115613a2357600080fd5b8286015b84811015613a4557613a38816139cc565b8352918301918301613a27565b509695505050505050565b600080600060608486031215613a6557600080fd5b8335925060208085013567ffffffffffffffff80821115613a8557600080fd5b818701915087601f830112613a9957600080fd5b8135613aa76139ff8261398c565b81815260059190911b8301840190848101908a831115613ac657600080fd5b938501935b82851015613aeb57613adc856139b0565b82529385019390850190613acb565b965050506040870135925080831115613b0357600080fd5b5050613b11868287016139de565b9150509250925092565b600080600060608486031215613b3057600080fd5b613b39846139b0565b9250613b47602085016139b0565b9150613b55604085016139cc565b90509250925092565b6000808335601e19843603018112613b7557600080fd5b83018035915067ffffffffffffffff821115613b9057600080fd5b6020019150600581901b360382131561384e57600080fd5b634e487b7160e01b600052603260045260246000fd5b600060208284031215613bd057600080fd5b613bd9826139b0565b9392505050565b600060208284031215613bf257600080fd5b613bd9826139cc565b600060208284031215613c0d57600080fd5b81518015158114613bd957600080fd5b634e487b7160e01b600052601160045260246000fd5b600082821015613c4557613c45613c1d565b500390565b600060208284031215613c5c57600080fd5b5051919050565b600061ffff808316818516808303821115613c8057613c80613c1d565b01949350505050565b6000816000190483118215151615613ca357613ca3613c1d565b500290565b600082613cc557634e487b7160e01b600052601260045260246000fd5b500490565b600061ffff83811690831681811015613ce557613ce5613c1d565b039392505050565b600081613cfc57613cfc613c1d565b506000190190565b60008219821115613d1757613d17613c1d565b500190565b6000600019821415613d3057613d30613c1d565b5060010190565b80516dffffffffffffffffffffffffffff811681146139c757600080fd5b600080600060608486031215613d6a57600080fd5b613d7384613d37565b9250613d8160208501613d37565b9150604084015163ffffffff81168114613d9a57600080fd5b809150509250925092565b60005b83811015613dc0578181015183820152602001613da8565b838111156124725750506000910152565b7fff0000000000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff198460601b16600182015282601582015260008251613e27816035850160208701613da5565b91909101603501949350505050565b60008251613e48818460208701613da5565b919091019291505056fea2646970667358221220035e8a06ff2fb49525cf9f2c1541d7436c7f4a2a69289412e1072cf4ddea72c364736f6c634300080a00330000000000000000000000008af94528fbe3c4c148523e7aad48bcebcc0a71d70000000000000000000000004f9a0e7fd2bf6067db6994cf12e4495df938e6e900000000000000000000000040df0c3bbaae5ea3a509d8f2aa9e086776c98e6c

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

0000000000000000000000008af94528fbe3c4c148523e7aad48bcebcc0a71d70000000000000000000000004f9a0e7fd2bf6067db6994cf12e4495df938e6e900000000000000000000000040df0c3bbaae5ea3a509d8f2aa9e086776c98e6c

-----Decoded View---------------
Arg [0] : _factory (address): 0x8af94528fbe3c4c148523e7aad48bcebcc0a71d7
Arg [1] : _WETH (address): 0x4f9a0e7fd2bf6067db6994cf12e4495df938e6e9
Arg [2] : _antfarmToken (address): 0x40df0c3bbaae5ea3a509d8f2aa9e086776c98e6c

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000008af94528fbe3c4c148523e7aad48bcebcc0a71d7
Arg [1] : 0000000000000000000000004f9a0e7fd2bf6067db6994cf12e4495df938e6e9
Arg [2] : 00000000000000000000000040df0c3bbaae5ea3a509d8f2aa9e086776c98e6c


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