Contract 0x17F65b6f5853B99a16D4d643DA1632b69255CdF5

Contract Overview

Balance:
0 AVAX
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x35d572dbfd13407adc65d6f8bc7ec7bca0896e0c7249a028761a8d53bf023006Transfer Ownersh...44241552022-01-04 14:03:59265 days 17 hrs ago0x3f09e942b0089b8af73ccb9603da8064b6c4b637 IN 0x17f65b6f5853b99a16d4d643da1632b69255cdf50 AVAX0.00071557525
0xffe479da8445a9fb1ee7cde120e0bd8bd20dcb57bcea9065d648ce7284599df30x6101006044241302022-01-04 14:03:08265 days 17 hrs ago0x3f09e942b0089b8af73ccb9603da8064b6c4b637 IN  Create: UniV2LimitsStops0 AVAX0.065706825
[ Download CSV Export 
Latest 25 internal transaction
Parent Txn Hash Block From To Value
0x5f90d4ff9b9ce1314ecec1f8f5ed40ca4ecbf12f45c40d5e823dff5faebcae3c50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
0x5f90d4ff9b9ce1314ecec1f8f5ed40ca4ecbf12f45c40d5e823dff5faebcae3c50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
0x5f90d4ff9b9ce1314ecec1f8f5ed40ca4ecbf12f45c40d5e823dff5faebcae3c50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0x5f90d4ff9b9ce1314ecec1f8f5ed40ca4ecbf12f45c40d5e823dff5faebcae3c50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0x5f90d4ff9b9ce1314ecec1f8f5ed40ca4ecbf12f45c40d5e823dff5faebcae3c50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0x5f90d4ff9b9ce1314ecec1f8f5ed40ca4ecbf12f45c40d5e823dff5faebcae3c50424142022-01-19 14:14:21250 days 17 hrs ago 0x457b8bb4d6c8cc2e506789f768996ddae60cd4fd0x17f65b6f5853b99a16d4d643da1632b69255cdf50 AVAX
0xa8f8eadbd17f4d212dd0d981c8fba1d6fd3d6fec338c4c88cba1e0efde200aee50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
0xa8f8eadbd17f4d212dd0d981c8fba1d6fd3d6fec338c4c88cba1e0efde200aee50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
0xa8f8eadbd17f4d212dd0d981c8fba1d6fd3d6fec338c4c88cba1e0efde200aee50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0xa8f8eadbd17f4d212dd0d981c8fba1d6fd3d6fec338c4c88cba1e0efde200aee50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0xa8f8eadbd17f4d212dd0d981c8fba1d6fd3d6fec338c4c88cba1e0efde200aee50424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0xa8f8eadbd17f4d212dd0d981c8fba1d6fd3d6fec338c4c88cba1e0efde200aee50424142022-01-19 14:14:21250 days 17 hrs ago 0x457b8bb4d6c8cc2e506789f768996ddae60cd4fd0x17f65b6f5853b99a16d4d643da1632b69255cdf50 AVAX
0x0e0d48264d28e5b06ebf8e4ce7033fafed62c4a8934790650715076b1f788d3950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
0x0e0d48264d28e5b06ebf8e4ce7033fafed62c4a8934790650715076b1f788d3950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
0x0e0d48264d28e5b06ebf8e4ce7033fafed62c4a8934790650715076b1f788d3950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0x0e0d48264d28e5b06ebf8e4ce7033fafed62c4a8934790650715076b1f788d3950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0x0e0d48264d28e5b06ebf8e4ce7033fafed62c4a8934790650715076b1f788d3950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0x0e0d48264d28e5b06ebf8e4ce7033fafed62c4a8934790650715076b1f788d3950424142022-01-19 14:14:21250 days 17 hrs ago 0x457b8bb4d6c8cc2e506789f768996ddae60cd4fd0x17f65b6f5853b99a16d4d643da1632b69255cdf50 AVAX
0xcaee853d751abb9b55b9d535c4dc9ebb442cd7af7d3fa56a4c9d7fa8b1a46b5950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
0xcaee853d751abb9b55b9d535c4dc9ebb442cd7af7d3fa56a4c9d7fa8b1a46b5950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
0xcaee853d751abb9b55b9d535c4dc9ebb442cd7af7d3fa56a4c9d7fa8b1a46b5950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0xcaee853d751abb9b55b9d535c4dc9ebb442cd7af7d3fa56a4c9d7fa8b1a46b5950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0xcaee853d751abb9b55b9d535c4dc9ebb442cd7af7d3fa56a4c9d7fa8b1a46b5950424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf50x171ee22328a936d7e9d67af0978fe973403f09c70 AVAX
0xcaee853d751abb9b55b9d535c4dc9ebb442cd7af7d3fa56a4c9d7fa8b1a46b5950424142022-01-19 14:14:21250 days 17 hrs ago 0x457b8bb4d6c8cc2e506789f768996ddae60cd4fd0x17f65b6f5853b99a16d4d643da1632b69255cdf50 AVAX
0xfbf709c4fcc66089f38109d019f763553388f5b9b670829bd9c83caa786421f150424142022-01-19 14:14:21250 days 17 hrs ago 0x17f65b6f5853b99a16d4d643da1632b69255cdf5 0x2d99abd9008dc933ff5c0cd271b88309593ab9210 AVAX
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
UniV2LimitsStops

Compiler Version
v0.8.6+commit.11564f7e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 8 : uniV2LimitsStops.sol
pragma solidity 0.8.6;


import "IERC20.sol";
import "Ownable.sol";
import "SafeERC20.sol";
import "IUniswapV2Router02.sol";


// Comments referenced throughout
// *1:
// Reduce amountOutMin proportionally so that the price of execution is the same
// as what was intended by the user. This is done so that the trade executes at
// the price intended by the user, even though they'll receive less than if
// that'd market bought/sold at that price (because they pay for the execution
// in regular ETH tx fees with normal Uniswap market orders). The naive way is
// to do the trade, then take the output token, and trade some of that for
// whatever the fee is paid in - this will execute at the intended price, but
// is gas inefficient because it then requires sending the output tokens here
// (and then requiring an additional transfer to the user), rather than inputing
// the recipient into the Uniswap trade. Instead, we can have 2 Uniswap trades
// (in the worst case scenario where the fee token isn't one of the traded tokens)
// that sends the fee in the 1st, and reduce amountOutMin in the 2nd proportional
// to the fees spent, such that the total execution price is the same as what was
// intended by the user, even though there are fewer input tokens to spend on the
// trade
// *2:
// Can't do `tradeInput = (inputAmount - inputSpentOnFee)` because of stack too deep


/**
* @title    UniV2LimitsStops
* @notice   Wraps around an arbitrary UniV2 router contract and adds conditions
*           of price to create limit orders and stop losses. Ensures that
*           only a specific user can call a trade because the Autonomy Registry
*           forces that the first argument of the calldata is the user's address
*           and this contract knows that condition is true when the call is coming
*           from an appropriate proxy
* @author   Quantaf1re (James Key)
*/
contract UniV2LimitsStops is Ownable {

    using SafeERC20 for IERC20;

    address payable public immutable registry;
    address public immutable userVeriForwarder;
    address public immutable userFeeVeriForwarder;
    address public immutable WETH;
    FeeInfo private _defaultFeeInfo;
    uint256 private constant MAX_UINT = type(uint256).max;


    constructor(
        address payable registry_,
        address userVeriForwarder_,
        address userFeeVeriForwarder_,
        address WETH_,
        FeeInfo memory defaultFeeInfo
    ) Ownable() {
        registry = registry_;
        userVeriForwarder = userVeriForwarder_;
        userFeeVeriForwarder = userFeeVeriForwarder_;
        WETH = WETH_;
        _defaultFeeInfo = defaultFeeInfo;
    }


    struct FeeInfo {
        // Need a known instance of UniV2 that is guaranteed to have the token
        // that the default fee is paid in, along with enough liquidity, since
        // an arbitrary instance of UniV2 is passed to fcns in this contract
        IUniswapV2Router02 uni;
        address[] path;
        // Whether or not the fee token is AUTO, because that needs to
        // get sent to the user, since `transferFrom` is used from them directly
        // in the Registry to charge the fee
        bool isAUTO;
    }

    // Hold arguments for calling Uniswap to avoid stack to deep errors
    struct UniArgs{
        uint inputAmount;
        uint amountOutMin;
        uint amountOutMax;
        address[] path;
        uint deadline;
    }


    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////
    ////                                                          ////
    ////-----------------------ETH to token-----------------------////
    ////                                                          ////
    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////

    /**
     * @notice  Only calls swapExactAVAXForTokens if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired.
     */
    function ethToTokenRange(
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external payable gasPriceCheck(maxGasPrice) {
        uint[] memory amounts = uni.swapExactAVAXForTokens{value: msg.value}(amountOutMin, path, to, deadline);
        require(amounts[amounts.length-1] <= amountOutMax, "LimitsStops: price too high");
    }

    function _ethToTokenPayDefault(
        address user,
        uint feeAmount,
        IUniswapV2Router02 uni,
        UniArgs memory uniArgs
    ) private {
        FeeInfo memory feeInfo = _defaultFeeInfo;
        if (feeInfo.isAUTO) {
            feeInfo.path[0] = WETH;
        }

        _ethToTokenPaySpecific(user, feeAmount, uni, feeInfo, uniArgs);
    }

    function _ethToTokenPaySpecific(
        address user,
        uint feeAmount,
        IUniswapV2Router02 uni,
        FeeInfo memory feeInfo,
        UniArgs memory uniArgs
    ) private {
        // Pay the execution fee
        uint tradeInput = msg.value;
        if (feeInfo.isAUTO) {
            tradeInput -= feeInfo.uni.swapAVAXForExactTokens{value: msg.value}(
                feeAmount,
                feeInfo.path,
                user,
                uniArgs.deadline
            )[0];
        } else {
            registry.transfer(feeAmount);
            tradeInput -= feeAmount;
        }

        // *1, *2
        uint[] memory amounts = uni.swapExactAVAXForTokens{value: tradeInput}(
            uniArgs.amountOutMin * tradeInput / msg.value,
            uniArgs.path,
            user,
            uniArgs.deadline
        );

        require(amounts[amounts.length-1] <= uniArgs.amountOutMax * tradeInput / msg.value, "LimitsStops: price too high");
    }

    /**
     * @notice  Only calls swapExactAVAXForTokens if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired. Additionally, 
     *          takes part of the trade and uses it to pay `feeAmount`,
     *          in the default fee token, to the registry
     */
    function ethToTokenRangePayDefault(
        address user,
        uint feeAmount,
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        uint deadline
    ) external payable gasPriceCheck(maxGasPrice) userFeeVerified {
        _ethToTokenPayDefault(
            user,
            feeAmount,
            uni,
            UniArgs(0, amountOutMin, amountOutMax, path, deadline)
        );
    }

    /**
     * @notice  Only calls swapExactAVAXForTokens if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired. Additionally, 
     *          takes part of the trade and uses it to pay `feeAmount`,
     *          in the specified fee token, to the registry.
     *          WARNING: only use this if you want to do things non-standard
     */
    function ethToTokenRangePaySpecific(
        address user,
        uint feeAmount,
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        FeeInfo memory feeInfo,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        uint deadline
    ) external payable gasPriceCheck(maxGasPrice) userFeeVerified {
        _ethToTokenPaySpecific(
            user,
            feeAmount,
            uni,
            feeInfo,
            UniArgs(0, amountOutMin, amountOutMax, path, deadline)
        );
    }


    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////
    ////                                                          ////
    ////-----------------------Token to ETH-----------------------////
    ////                                                          ////
    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////

    /**
     * @notice  Only calls swapExactTokensForAVAX if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired.
     */
    function tokenToEthRange(
        address user,
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        uint inputAmount,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external gasPriceCheck(maxGasPrice) userVerified {
        transferApproveUnapproved(uni, path[0], inputAmount, user);
        uint[] memory amounts = uni.swapExactTokensForAVAX(inputAmount, amountOutMin, path, to, deadline);
        require(amounts[amounts.length-1] <= amountOutMax, "LimitsStops: price too high");
    }

    function _tokenToEthPayDefault(
        address user,
        uint feeAmount,
        IUniswapV2Router02 uni,
        UniArgs memory uniArgs
    ) private {
        FeeInfo memory feeInfo = _defaultFeeInfo;
        // The fee path only needs to be modified when not paying in ETH (since
        // the output of the trade is ETH and that can be used) and when the input
        // token isn't AUTO anyway (since that can be used without a 2nd trade)
        if (feeInfo.isAUTO && uniArgs.path[0] != feeInfo.path[feeInfo.path.length-1]) {
            address[] memory newFeePath = new address[](3);
            newFeePath[0] = uniArgs.path[0];               // src token
            newFeePath[1] = WETH;   // WETH_ since path in tokenToETH ends in WETH_
            newFeePath[2] = feeInfo.path[feeInfo.path.length-1];   // AUTO since feePath here ends in AUTO
            feeInfo.path = newFeePath;
        }

        _tokenToEthPaySpecific(user, feeAmount, uni, feeInfo, uniArgs);
    }

    function _tokenToEthPaySpecific(
        address user,
        uint feeAmount,
        IUniswapV2Router02 uni,
        FeeInfo memory feeInfo,
        UniArgs memory uniArgs
    ) private {
        // Pay the execution fee
        uint tradeInput = uniArgs.inputAmount;
        if (feeInfo.isAUTO) {
            // If the src token is AUTO
            if (uniArgs.path[0] == feeInfo.path[feeInfo.path.length-1]) {
                // The user already holds inputAmount of AUTO, so don't move them
                tradeInput -= feeAmount;
                transferApproveUnapproved(uni, uniArgs.path[0], tradeInput, user);
            } else {
                transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user);
                approveUnapproved(feeInfo.uni, uniArgs.path[0], uniArgs.inputAmount);
                tradeInput -= feeInfo.uni.swapTokensForExactTokens(feeAmount, uniArgs.inputAmount, feeInfo.path, user, uniArgs.deadline)[0];
            }
        } else {
            transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user);
        }

        // *1, *2
        uint[] memory amounts = uni.swapExactTokensForAVAX(
            tradeInput,
            uniArgs.amountOutMin * tradeInput / uniArgs.inputAmount,
            uniArgs.path,
            // Sending it all to the registry means that the fee will be kept
            // (if it's in ETH) and the excess sent to the user
            feeInfo.isAUTO ? user : registry,
            uniArgs.deadline
        );
        require(amounts[amounts.length-1] <= uniArgs.amountOutMax * tradeInput / uniArgs.inputAmount, "LimitsStops: price too high");
    }

    /**
     * @notice  Only calls swapExactTokensForAVAX if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired. Additionally, 
     *          takes part of the trade and uses it to pay `feeAmount`,
     *          in the default fee token, to the registry
     */
    function tokenToEthRangePayDefault(
        address user,
        uint feeAmount,
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        uint inputAmount,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        uint deadline
    ) external gasPriceCheck(maxGasPrice) userFeeVerified {
        _tokenToEthPayDefault(
            user,
            feeAmount,
            uni,
            UniArgs(inputAmount, amountOutMin, amountOutMax, path, deadline)
        );
    }

    /**
     * @notice  Only calls swapExactTokensForAVAX if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired. Additionally, 
     *          takes part of the trade and uses it to pay `feeAmount`,
     *          in the specified fee token, to the registry.
     *          WARNING: only use this if you want to do things non-standard
     */
    function tokenToEthRangePaySpecific(
        address user,
        uint feeAmount,
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        FeeInfo memory feeInfo,
        uint inputAmount,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        uint deadline
    ) external gasPriceCheck(maxGasPrice) userFeeVerified {
        _tokenToEthPaySpecific(
            user,
            feeAmount,
            uni,
            feeInfo,
            UniArgs(inputAmount, amountOutMin, amountOutMax, path, deadline)
        );
    }

    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////
    ////                                                          ////
    ////----------------------Token to token----------------------////
    ////                                                          ////
    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////

    /**
     * @notice  Only calls swapExactTokensForTokens if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired.
     */
    function tokenToTokenRange(
        address user,
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        uint inputAmount,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        address to,
        uint deadline
    ) external gasPriceCheck(maxGasPrice) userVerified {
        transferApproveUnapproved(uni, path[0], inputAmount, user);
        uint[] memory amounts = uni.swapExactTokensForTokens(inputAmount, amountOutMin, path, to, deadline);
        require(amounts[amounts.length-1] <= amountOutMax, "LimitsStops: price too high");
    }

    function _tokenToTokenPayDefault(
        address user,
        uint feeAmount,
        IUniswapV2Router02 uni,
        UniArgs memory uniArgs
    ) private {
        FeeInfo memory feeInfo = _defaultFeeInfo;
        // The fee path only needs to be modified when the src/dest tokens aren't
        // AUTO (if paying in AUTO), and when paying in ETH
        if (feeInfo.isAUTO && uniArgs.path[0] != feeInfo.path[feeInfo.path.length-1]) {
            address[] memory newFeePath = new address[](3);
            newFeePath[0] = uniArgs.path[0];                // src token
            newFeePath[1] = WETH;                  // WETH_ since path in tokenToETH ends in WETH_
            newFeePath[2] = feeInfo.path[feeInfo.path.length-1];   // AUTO since feePath here ends in AUTO
            feeInfo.path = newFeePath;
        } else if (!feeInfo.isAUTO) {
            feeInfo.path[0] = uniArgs.path[0];
        }

        _tokenToTokenPaySpecific(user, feeAmount, uni, feeInfo, uniArgs);
    }

    function _tokenToTokenPaySpecific(
        address user,
        uint feeAmount,
        IUniswapV2Router02 uni,
        FeeInfo memory feeInfo,
        UniArgs memory uniArgs
    ) private {
        // Pay the execution fee
        uint tradeInput = uniArgs.inputAmount;
        if (feeInfo.isAUTO) {
            // If the src token is AUTO
            if (uniArgs.path[0] == feeInfo.path[feeInfo.path.length-1]) {
                // The user already holds inputAmount of AUTO
                tradeInput -= feeAmount;
                transferApproveUnapproved(uni, uniArgs.path[0], tradeInput, user);
            // If the dest token is AUTO
            } else if (uniArgs.path[uniArgs.path.length-1] == feeInfo.path[feeInfo.path.length-1]) {
                // Do nothing because it'll all get sent to the user, and the
                // fee will be taken from them after that
                transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user);
            } else {
                transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user);
                approveUnapproved(feeInfo.uni, uniArgs.path[0], uniArgs.inputAmount);
                tradeInput -= feeInfo.uni.swapTokensForExactTokens(feeAmount, uniArgs.inputAmount, feeInfo.path, user, uniArgs.deadline)[0];
            }
        } else {
            transferApproveUnapproved(uni, uniArgs.path[0], uniArgs.inputAmount, user);
            approveUnapproved(feeInfo.uni, uniArgs.path[0], uniArgs.inputAmount);
            tradeInput -= feeInfo.uni.swapTokensForExactAVAX(feeAmount, uniArgs.inputAmount, feeInfo.path, registry, uniArgs.deadline)[0];
        }

        // *1, *2
        uint[] memory amounts = uni.swapExactTokensForTokens(
            tradeInput,
            uniArgs.amountOutMin * tradeInput / uniArgs.inputAmount,
            uniArgs.path,
            user,
            uniArgs.deadline
        );
        require(amounts[amounts.length-1] <= uniArgs.amountOutMax * tradeInput / uniArgs.inputAmount, "LimitsStops: price too high");
    }

    /**
     * @notice  Only calls swapExactTokensForTokens if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired. Additionally, 
     *          takes part of the trade and uses it to pay `feeAmount`,
     *          in the default fee token, to the registry
     */
    function tokenToTokenRangePayDefault(
        address user,
        uint feeAmount,
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        uint inputAmount,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        uint deadline
    ) external gasPriceCheck(maxGasPrice) userFeeVerified {
        _tokenToTokenPayDefault(
            user,
            feeAmount,
            uni,
            UniArgs(inputAmount, amountOutMin, amountOutMax, path, deadline)
        );
    }

    /**
     * @notice  Only calls swapExactTokensForTokens if the output is above
     *          `amountOutMin` and below `amountOutMax`. `amountOutMax`
     *          is the 'stop price' when used as a stop loss, and
     *          `amountOutMin` is the 'limit price' when used as a limit
     *          order. When using this as a classic limit order, `amountOutMax`
     *          would be sent to the max uint value. When using this
     *          as a classic stop loss, `amountOutMin` would be set to 0.
     *          The min/max can also be used to limit downside during flash
     *          crashes, e.g. `amountOutMin` could be set to 10% lower then
     *          `amountOutMax` for a stop loss, if desired. Additionally, 
     *          takes part of the trade and uses it to pay `feeAmount`,
     *          in the specified fee token, to the registry.
     *          WARNING: only use this if you want to do things non-standard
     */
    function tokenToTokenRangePaySpecific(
        address user,
        uint feeAmount,
        uint maxGasPrice,
        IUniswapV2Router02 uni,
        FeeInfo memory feeInfo,
        uint inputAmount,
        uint amountOutMin,
        uint amountOutMax,
        address[] calldata path,
        uint deadline
    ) external gasPriceCheck(maxGasPrice) userFeeVerified {
        _tokenToTokenPaySpecific(
            user,
            feeAmount,
            uni,
            feeInfo,
            UniArgs(inputAmount, amountOutMin, amountOutMax, path, deadline)
        );
    }


    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////
    ////                                                          ////
    ////-------------------------Helpers--------------------------////
    ////                                                          ////
    //////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////

    function approveUnapproved(IUniswapV2Router02 uni, address tokenAddr, uint amount) private returns (IERC20 token) {
        token = IERC20(tokenAddr);
        if (token.allowance(address(this), address(uni)) < amount) {
            token.approve(address(uni), MAX_UINT);
        }
    }

    function transferApproveUnapproved(IUniswapV2Router02 uni, address tokenAddr, uint amount, address user) private {
        IERC20 token = approveUnapproved(uni, tokenAddr, amount);
        token.safeTransferFrom(user, address(this), amount);
    }

    function setDefaultFeeInfo(FeeInfo calldata newDefaultFee) external onlyOwner {
        _defaultFeeInfo = newDefaultFee;
    }

    function getDefaultFeeInfo() external view returns (FeeInfo memory) {
        return _defaultFeeInfo;
    }

    modifier userVerified() {
        require(msg.sender == userVeriForwarder, "LimitsStops: not userForw");
        _;
    }

    modifier userFeeVerified() {
        require(msg.sender == userFeeVeriForwarder, "LimitsStops: not userFeeForw");
        _;
    }

    modifier gasPriceCheck(uint maxGasPrice) {
        require(tx.gasprice <= maxGasPrice, "LimitsStops: gasPrice too high");
        _;
    }

    // Needed to receive excess ETH when calling swapAVAXForExactTokens
    receive() external payable {}
}

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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

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

File 3 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 4 of 8 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

File 5 of 8 : SafeERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "IERC20.sol";
import "Address.sol";

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

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

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

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

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

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

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

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

File 6 of 8 : Address.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 7 of 8 : IUniswapV2Router02.sol
pragma solidity 0.8.6;

import "IUniswapV2Router01.sol";

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

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

File 8 of 8 : IUniswapV2Router01.sol
pragma solidity 0.8.6;

interface IUniswapV2Router01 {
    function factory() external pure returns (address);
    function WETH() external pure returns (address);

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

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

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

Contract ABI

[{"inputs":[{"internalType":"address payable","name":"registry_","type":"address"},{"internalType":"address","name":"userVeriForwarder_","type":"address"},{"internalType":"address","name":"userFeeVeriForwarder_","type":"address"},{"internalType":"address","name":"WETH_","type":"address"},{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"defaultFeeInfo","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ethToTokenRange","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ethToTokenRangePayDefault","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"feeInfo","type":"tuple"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ethToTokenRangePaySpecific","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"getDefaultFeeInfo","outputs":[{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"registry","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"newDefaultFee","type":"tuple"}],"name":"setDefaultFeeInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToEthRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToEthRangePayDefault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"feeInfo","type":"tuple"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToEthRangePaySpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToTokenRange","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToTokenRangePayDefault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"uint256","name":"maxGasPrice","type":"uint256"},{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"components":[{"internalType":"contract IUniswapV2Router02","name":"uni","type":"address"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"bool","name":"isAUTO","type":"bool"}],"internalType":"struct UniV2LimitsStops.FeeInfo","name":"feeInfo","type":"tuple"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"amountOutMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToTokenRangePaySpecific","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"userFeeVeriForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"userVeriForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

6101006040523480156200001257600080fd5b50604051620030fe380380620030fe8339810160408190526200003591620001b8565b6200004033620000d1565b606085811b6001600160601b031990811660805285821b811660a05284821b811660c0529083901b1660e0528051600180546001600160a01b0319166001600160a01b039092169190911781556020808301518051849392620000a99260029291019062000121565b50604091909101516002909101805460ff191691151591909117905550620003bc9350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b82805482825590600052602060002090810192821562000179579160200282015b828111156200017957825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000142565b50620001879291506200018b565b5090565b5b808211156200018757600081556001016200018c565b80518015158114620001b357600080fd5b919050565b600080600080600060a08688031215620001d157600080fd5b8551620001de81620003a3565b80955050602080870151620001f381620003a3565b60408801519095506200020681620003a3565b60608801519094506200021981620003a3565b60808801519093506001600160401b03808211156200023757600080fd5b908801906060828b0312156200024c57600080fd5b620002566200032f565b82516200026381620003a3565b815282840151828111156200027757600080fd5b8301601f81018c136200028957600080fd5b8051838111156200029e576200029e6200038d565b8060051b9350620002b18685016200035a565b8082825287820191508784018f89888701011115620002cf57600080fd5b600096505b83871015620003025780519450620002ec85620003a3565b84835260019690960195918801918801620002d4565b5084880152506200031991505060408401620001a2565b6040820152809450505050509295509295909350565b604051606081016001600160401b03811182821017156200035457620003546200038d565b60405290565b604051601f8201601f191681016001600160401b03811182821017156200038557620003856200038d565b604052919050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114620003b957600080fd5b50565b60805160601c60a05160601c60c05160601c60e05160601c612c9a62000464600039600081816102cc01528181610f5601528181611a3f0152611c1801526000818161012b015281816103cb0152818161068801528181610756015281816108610152818161092f0152610baf015260008181610298015281816104a50152610aca0152600081816101d30152818161130a015281816114f301526118a30152612c9a6000f3fe60806040526004361061010d5760003560e01c806399459cf611610095578063c9f567a111610064578063c9f567a114610301578063ce6db3cc14610323578063d2a9fb3e14610343578063f2fde38b14610363578063f69920631461038357600080fd5b806399459cf614610266578063a5030ded14610286578063ad5c4648146102ba578063bc60b9aa146102ee57600080fd5b80637b103999116100dc5780637b103999146101c157806385183df8146101f55780638c833449146102155780638c99cd3f146102285780638da5cb5b1461024857600080fd5b806306bddfdf1461011957806335ae7b6e1461016a5780633b62609f1461018c578063715018a6146101ac57600080fd5b3661011457005b600080fd5b34801561012557600080fd5b5061014d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561017657600080fd5b5061018a6101853660046124b0565b610396565b005b34801561019857600080fd5b5061018a6101a73660046121dc565b610479565b3480156101b857600080fd5b5061018a610626565b3480156101cd57600080fd5b5061014d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561020157600080fd5b5061018a61021036600461234c565b61065c565b61018a610223366004612289565b61072a565b34801561023457600080fd5b5061018a6102433660046125e9565b6107f9565b34801561025457600080fd5b506000546001600160a01b031661014d565b34801561027257600080fd5b5061018a61028136600461234c565b610835565b34801561029257600080fd5b5061014d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102c657600080fd5b5061014d7f000000000000000000000000000000000000000000000000000000000000000081565b61018a6102fc366004612419565b610903565b34801561030d57600080fd5b506103166109dd565b6040516101619190612876565b34801561032f57600080fd5b5061018a61033e3660046121dc565b610a9e565b34801561034f57600080fd5b5061018a61035e3660046124b0565b610b83565b34801561036f57600080fd5b5061018a61037e3660046121bf565b610c50565b61018a61039136600461263c565b610ceb565b87803a11156103c05760405162461bcd60e51b81526004016103b79061283f565b60405180910390fd5b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104085760405162461bcd60e51b81526004016103b79061279c565b61046c8b8b8a6040518060a001604052808c81526020018b81526020018a8152602001898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250505090825250602001879052610de1565b5050505050505050505050565b88803a111561049a5760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461050e5760405162461bcd60e51b81526020600482015260196024820152784c696d69747353746f70733a206e6f742075736572466f727760381b60448201526064016103b7565b610541898686600081811061052557610525612ab7565b905060200201602081019061053a91906121bf565b8a8e61106e565b6040516338ed173960e01b81526000906001600160a01b038b16906338ed17399061057a908c908c908b908b908b908b90600401612928565b600060405180830381600087803b15801561059457600080fd5b505af11580156105a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105d09190810190612535565b90508681600183516105e29190612a5e565b815181106105f2576105f2612ab7565b602002602001015111156106185760405162461bcd60e51b81526004016103b7906127d3565b505050505050505050505050565b6000546001600160a01b031633146106505760405162461bcd60e51b81526004016103b79061280a565b61065a6000611092565b565b88803a111561067d5760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106c55760405162461bcd60e51b81526004016103b79061279c565b6106188c8c8b8b6040518060a001604052808d81526020018c81526020018b81526020018a8a808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506020018890526110e2565b87803a111561074b5760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107935760405162461bcd60e51b81526004016103b79061279c565b61046c8b8b8a8a6040518060a00160405280600081526020018c81526020018b81526020018a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060200188905261141a565b6000546001600160a01b031633146108235760405162461bcd60e51b81526004016103b79061280a565b8060016108308282612b03565b505050565b88803a11156108565760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461089e5760405162461bcd60e51b81526004016103b79061279c565b6106188c8c8b8b6040518060a001604052808d81526020018c81526020018b81526020018a8a8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050509082525060200188905261160a565b86803a11156109245760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461096c5760405162461bcd60e51b81526004016103b79061279c565b6109d18a8a896040518060a00160405280600081526020018b81526020018a81526020018989808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506020018790526119a5565b50505050505050505050565b610a0c604051806060016040528060006001600160a01b03168152602001606081526020016000151581525090565b60408051606081018252600180546001600160a01b03168252600280548451602082810282018101909652818152939492938386019390929190830182828015610a7f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610a61575b50505091835250506002919091015460ff161515602090910152919050565b88803a1115610abf5760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b335760405162461bcd60e51b81526020600482015260196024820152784c696d69747353746f70733a206e6f742075736572466f727760381b60448201526064016103b7565b610b4a898686600081811061052557610525612ab7565b60405163676528d160e01b81526000906001600160a01b038b169063676528d19061057a908c908c908b908b908b908b90600401612928565b87803a1115610ba45760405162461bcd60e51b81526004016103b79061283f565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610bec5760405162461bcd60e51b81526004016103b79061279c565b61046c8b8b8a6040518060a001604052808c81526020018b81526020018a8152602001898980806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250505090825250602001879052611aa3565b6000546001600160a01b03163314610c7a5760405162461bcd60e51b81526004016103b79061280a565b6001600160a01b038116610cdf5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103b7565b610ce881611092565b50565b87803a1115610d0c5760405162461bcd60e51b81526004016103b79061283f565b6000886001600160a01b031663a2a1623d348a898989896040518763ffffffff1660e01b8152600401610d439594939291906128bc565b6000604051808303818588803b158015610d5c57600080fd5b505af1158015610d70573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f19168201604052610d999190810190612535565b9050868160018351610dab9190612a5e565b81518110610dbb57610dbb612ab7565b602002602001015111156109d15760405162461bcd60e51b81526004016103b7906127d3565b60408051606081018252600180546001600160a01b0316825260028054845160208281028201810190965281815260009580860193919290830182828015610e5257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e34575b50505091835250506002919091015460ff16151560209091015260408101519091508015610eda575060208101518051610e8e90600190612a5e565b81518110610e9e57610e9e612ab7565b60200260200101516001600160a01b03168260600151600081518110610ec657610ec6612ab7565b60200260200101516001600160a01b031614155b15610ffa5760408051600380825260808201909252600091602082016060803683370190505090508260600151600081518110610f1957610f19612ab7565b602002602001015181600081518110610f3457610f34612ab7565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000000000000000000000000000000000000000000081600181518110610f8857610f88612ab7565b6001600160a01b039092166020928302919091018201528201518051610fb090600190612a5e565b81518110610fc057610fc0612ab7565b602002602001015181600281518110610fdb57610fdb612ab7565b6001600160a01b0390921660209283029190910182015282015261105a565b806040015161105a57816060015160008151811061101a5761101a612ab7565b6020026020010151816020015160008151811061103957611039612ab7565b60200260200101906001600160a01b031690816001600160a01b0316815250505b611067858585848661160a565b5050505050565b600061107b858585611cc5565b90506110676001600160a01b038216833086611dda565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516040830151156112ae576020830151805161110190600190612a5e565b8151811061111157611111612ab7565b60200260200101516001600160a01b0316826060015160008151811061113957611139612ab7565b60200260200101516001600160a01b0316141561118b5761115a8582612a5e565b905061118684836060015160008151811061117757611177612ab7565b6020026020010151838961106e565b6112c9565b6111b98483606001516000815181106111a6576111a6612ab7565b602002602001015184600001518961106e565b6111ea836000015183606001516000815181106111d8576111d8612ab7565b60200260200101518460000151611cc5565b508251825160208501516080850151604051634401edf760e11b81526001600160a01b0390941693638803dbee9361122c938b93919290918d91600401612966565b600060405180830381600087803b15801561124657600080fd5b505af115801561125a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112829190810190612535565b60008151811061129457611294612ab7565b6020026020010151816112a79190612a5e565b90506112c9565b6112c98483606001516000815181106111a6576111a6612ab7565b6000846001600160a01b031663676528d18385600001518587602001516112f09190612a3f565b6112fa9190612a1d565b8660600151886040015161132e577f0000000000000000000000000000000000000000000000000000000000000000611330565b8b5b88608001516040518663ffffffff1660e01b8152600401611355959493929190612966565b600060405180830381600087803b15801561136f57600080fd5b505af1158015611383573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526113ab9190810190612535565b905082600001518284604001516113c29190612a3f565b6113cc9190612a1d565b81600183516113db9190612a5e565b815181106113eb576113eb612ab7565b602002602001015111156114115760405162461bcd60e51b81526004016103b7906127d3565b50505050505050565b60408201513490156114e657825160208401516080840151604051638a657e6760e01b81526001600160a01b0390931692638a657e67923492611464928b92918d916004016128f3565b6000604051808303818588803b15801561147d57600080fd5b505af1158015611491573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526114ba9190810190612535565b6000815181106114cc576114cc612ab7565b6020026020010151816114df9190612a5e565b905061154a565b6040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169086156108fc029087906000818181858888f1935050505015801561153c573d6000803e3d6000fd5b506115478582612a5e565b90505b6000846001600160a01b031663a2a1623d833485876020015161156d9190612a3f565b6115779190612a1d565b86606001518b88608001516040518663ffffffff1660e01b81526004016115a194939291906128f3565b6000604051808303818588803b1580156115ba57600080fd5b505af11580156115ce573d6000803e3d6000fd5b50505050506040513d6000823e601f3d908101601f191682016040526115f79190810190612535565b9050348284604001516113c29190612a3f565b805160408301511561182f576020830151805161162990600190612a5e565b8151811061163957611639612ab7565b60200260200101516001600160a01b0316826060015160008151811061166157611661612ab7565b60200260200101516001600160a01b031614156116a4576116828582612a5e565b905061169f84836060015160008151811061117757611177612ab7565b611949565b602083015180516116b790600190612a5e565b815181106116c7576116c7612ab7565b60200260200101516001600160a01b0316826060015160018460600151516116ef9190612a5e565b815181106116ff576116ff612ab7565b60200260200101516001600160a01b031614156117315761169f8483606001516000815181106111a6576111a6612ab7565b61174c8483606001516000815181106111a6576111a6612ab7565b61176b836000015183606001516000815181106111d8576111d8612ab7565b508251825160208501516080850151604051634401edf760e11b81526001600160a01b0390941693638803dbee936117ad938b93919290918d91600401612966565b600060405180830381600087803b1580156117c757600080fd5b505af11580156117db573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526118039190810190612535565b60008151811061181557611815612ab7565b6020026020010151816118289190612a5e565b9050611949565b61184a8483606001516000815181106111a6576111a6612ab7565b611869836000015183606001516000815181106111d8576111d8612ab7565b508251825160208501516080850151604051633d2120b560e11b81526001600160a01b0390941693637a42416a936118cb938b93919290917f000000000000000000000000000000000000000000000000000000000000000091600401612966565b600060405180830381600087803b1580156118e557600080fd5b505af11580156118f9573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526119219190810190612535565b60008151811061193357611933612ab7565b6020026020010151816119469190612a5e565b90505b6000846001600160a01b03166338ed17398385600001518587602001516119709190612a3f565b61197a9190612a1d565b86606001518b88608001516040518663ffffffff1660e01b8152600401611355959493929190612966565b60408051606081018252600180546001600160a01b0316825260028054845160208281028201810190965281815260009580860193919290830182828015611a1657602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116119f8575b50505091835250506002919091015460ff161515602090910152604081015190915015611a96577f00000000000000000000000000000000000000000000000000000000000000008160200151600081518110611a7557611a75612ab7565b60200260200101906001600160a01b031690816001600160a01b0316815250505b611067858585848661141a565b60408051606081018252600180546001600160a01b0316825260028054845160208281028201810190965281815260009580860193919290830182828015611b1457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611af6575b50505091835250506002919091015460ff16151560209091015260408101519091508015611b9c575060208101518051611b5090600190612a5e565b81518110611b6057611b60612ab7565b60200260200101516001600160a01b03168260600151600081518110611b8857611b88612ab7565b60200260200101516001600160a01b031614155b15611cb85760408051600380825260808201909252600091602082016060803683370190505090508260600151600081518110611bdb57611bdb612ab7565b602002602001015181600081518110611bf657611bf6612ab7565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000000000000000000000000000000000000000000081600181518110611c4a57611c4a612ab7565b6001600160a01b039092166020928302919091018201528201518051611c7290600190612a5e565b81518110611c8257611c82612ab7565b602002602001015181600281518110611c9d57611c9d612ab7565b6001600160a01b039092166020928302919091018201528201525b61106785858584866110e2565b604051636eb1769f60e11b81523060048201526001600160a01b0384811660248301528391839183169063dd62ed3e9060440160206040518083038186803b158015611d1057600080fd5b505afa158015611d24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d489190612623565b1015611dd35760405163095ea7b360e01b81526001600160a01b038581166004830152600019602483015282169063095ea7b390604401602060405180830381600087803b158015611d9957600080fd5b505af1158015611dad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dd191906125cc565b505b9392505050565b604080516001600160a01b0385811660248301528416604482015260648082018490528251808303909101815260849091019091526020810180516001600160e01b03166323b872dd60e01b179052611e34908590611e3a565b50505050565b6000611e8f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611f0c9092919063ffffffff16565b8051909150156108305780806020019051810190611ead91906125cc565b6108305760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016103b7565b6060611f1b8484600085611f23565b949350505050565b606082471015611f845760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016103b7565b843b611fd25760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016103b7565b600080866001600160a01b03168587604051611fee919061274d565b60006040518083038185875af1925050503d806000811461202b576040519150601f19603f3d011682016040523d82523d6000602084013e612030565b606091505b509150915061204082828661204b565b979650505050505050565b6060831561205a575081611dd3565b82511561206a5782518084602001fd5b8160405162461bcd60e51b81526004016103b79190612769565b803561208f81612c41565b919050565b60008083601f8401126120a657600080fd5b5081356001600160401b038111156120bd57600080fd5b6020830191508360208260051b85010111156120d857600080fd5b9250929050565b803561208f81612c56565b6000606082840312156120fc57600080fd5b6121046129a2565b9050813561211181612c41565b81526020828101356001600160401b0381111561212d57600080fd5b8301601f8101851361213e57600080fd5b803561215161214c826129fa565b6129ca565b80828252848201915084840188868560051b870101111561217157600080fd5b600094505b8385101561219d57803561218981612c41565b835260019490940193918501918501612176565b50808587015250505050506121b4604083016120df565b604082015292915050565b6000602082840312156121d157600080fd5b8135611dd381612c41565b6000806000806000806000806000806101208b8d0312156121fc57600080fd5b8a3561220781612c41565b995060208b0135985060408b013561221e81612c41565b975060608b0135965060808b0135955060a08b0135945060c08b01356001600160401b0381111561224e57600080fd5b61225a8d828e01612094565b90955093505060e08b013561226e81612c41565b809250506101008b013590509295989b9194979a5092959850565b6000806000806000806000806000806101208b8d0312156122a957600080fd5b8a356122b481612c41565b995060208b0135985060408b0135975060608b01356122d281612c41565b965060808b01356001600160401b03808211156122ee57600080fd5b6122fa8e838f016120ea565b975060a08d0135965060c08d0135955060e08d013591508082111561231e57600080fd5b5061232b8d828e01612094565b915080945050809250506101008b013590509295989b9194979a5092959850565b60008060008060008060008060008060006101408c8e03121561236e57600080fd5b6123778c612084565b9a5060208c0135995060408c0135985061239360608d01612084565b97506001600160401b038060808e013511156123ae57600080fd5b6123be8e60808f01358f016120ea565b975060a08d0135965060c08d0135955060e08d01359450806101008e013511156123e757600080fd5b506123f98d6101008e01358e01612094565b81945080935050506101208c013590509295989b509295989b9093969950565b60008060008060008060008060006101008a8c03121561243857600080fd5b893561244381612c41565b985060208a0135975060408a0135965060608a013561246181612c41565b955060808a0135945060a08a0135935060c08a01356001600160401b0381111561248a57600080fd5b6124968c828d01612094565b9a9d999c50979a9699959894979660e00135949350505050565b6000806000806000806000806000806101208b8d0312156124d057600080fd5b8a356124db81612c41565b995060208b0135985060408b0135975060608b01356124f981612c41565b965060808b0135955060a08b0135945060c08b0135935060e08b01356001600160401b0381111561252957600080fd5b61232b8d828e01612094565b6000602080838503121561254857600080fd5b82516001600160401b0381111561255e57600080fd5b8301601f8101851361256f57600080fd5b805161257d61214c826129fa565b80828252848201915084840188868560051b870101111561259d57600080fd5b600094505b838510156125c05780518352600194909401939185019185016125a2565b50979650505050505050565b6000602082840312156125de57600080fd5b8151611dd381612c56565b6000602082840312156125fb57600080fd5b81356001600160401b0381111561261157600080fd5b820160608185031215611dd357600080fd5b60006020828403121561263557600080fd5b5051919050565b60008060008060008060008060e0898b03121561265857600080fd5b88359750602089013561266a81612c41565b9650604089013595506060890135945060808901356001600160401b0381111561269357600080fd5b61269f8b828c01612094565b90955093505060a08901356126b381612c41565b8092505060c089013590509295985092959890939650565b8183526000602080850194508260005b858110156127095781356126ee81612c41565b6001600160a01b0316875295820195908201906001016126db565b509495945050505050565b600081518084526020808501945080840160005b838110156127095781516001600160a01b031687529582019590820190600101612728565b6000825161275f818460208701612a75565b9190910192915050565b6020815260008251806020840152612788816040850160208701612a75565b601f01601f19169190910160400192915050565b6020808252601c908201527f4c696d69747353746f70733a206e6f742075736572466565466f727700000000604082015260600190565b6020808252601b908201527f4c696d69747353746f70733a20707269636520746f6f20686967680000000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601e908201527f4c696d69747353746f70733a20676173507269636520746f6f20686967680000604082015260600190565b602080825282516001600160a01b031682820152820151606060408301526000906128a46080840182612714565b90506040840151151560608401528091505092915050565b8581526080602082015260006128d66080830186886126cb565b6001600160a01b0394909416604083015250606001529392505050565b84815260806020820152600061290c6080830186612714565b6001600160a01b03949094166040830152506060015292915050565b86815285602082015260a06040820152600061294860a0830186886126cb565b6001600160a01b039490941660608301525060800152949350505050565b85815284602082015260a06040820152600061298560a0830186612714565b6001600160a01b0394909416606083015250608001529392505050565b604051606081016001600160401b03811182821017156129c4576129c4612acd565b60405290565b604051601f8201601f191681016001600160401b03811182821017156129f2576129f2612acd565b604052919050565b60006001600160401b03821115612a1357612a13612acd565b5060051b60200190565b600082612a3a57634e487b7160e01b600052601260045260246000fd5b500490565b6000816000190483118215151615612a5957612a59612aa1565b500290565b600082821015612a7057612a70612aa1565b500390565b60005b83811015612a90578181015183820152602001612a78565b83811115611e345750506000910152565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60008135612af081612c41565b92915050565b60008135612af081612c56565b8135612b0e81612c41565b81546001600160a01b0319166001600160a01b0391909116178155600181810160208481013536869003601e19018112612b4757600080fd5b850180356001600160401b03811115612b5f57600080fd5b82820191508060051b3603821315612b7657600080fd5b68010000000000000000811115612b8f57612b8f612acd565b835481855580821015612bc35760008581528481208381019083015b80821015612bbf5782825590880190612bab565b5050505b50600093845260208420935b81811015612c0f57612c00612be384612ae3565b86546001600160a01b0319166001600160a01b0391909116178655565b93850193918301918501612bcf565b505050505050612c3d612c2460408401612af6565b6002830160ff1981541660ff8315151681178255505050565b5050565b6001600160a01b0381168114610ce857600080fd5b8015158114610ce857600080fdfea26469706673582212201f1fe54382414dad0acf7a4a7c333a7a74deb98ccbd82c305914a40eac77362364736f6c63430008060033000000000000000000000000a0f25b796dd59e504077f87caea1c0472cd6b7b4000000000000000000000000ff02150dbd816526b2c7b0d4e5abf63e16ef6402000000000000000000000000457b8bb4d6c8cc2e506789f768996ddae60cd4fd000000000000000000000000d00ae08403b9bbb9124bb305c09058e32c39a48c00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000002d99abd9008dc933ff5c0cd271b88309593ab9210000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d00ae08403b9bbb9124bb305c09058e32c39a48c

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

000000000000000000000000a0f25b796dd59e504077f87caea1c0472cd6b7b4000000000000000000000000ff02150dbd816526b2c7b0d4e5abf63e16ef6402000000000000000000000000457b8bb4d6c8cc2e506789f768996ddae60cd4fd000000000000000000000000d00ae08403b9bbb9124bb305c09058e32c39a48c00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000002d99abd9008dc933ff5c0cd271b88309593ab9210000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d00ae08403b9bbb9124bb305c09058e32c39a48c

-----Decoded View---------------
Arg [0] : registry_ (address): 0xa0f25b796dd59e504077f87caea1c0472cd6b7b4
Arg [1] : userVeriForwarder_ (address): 0xff02150dbd816526b2c7b0d4e5abf63e16ef6402
Arg [2] : userFeeVeriForwarder_ (address): 0x457b8bb4d6c8cc2e506789f768996ddae60cd4fd
Arg [3] : WETH_ (address): 0xd00ae08403b9bbb9124bb305c09058e32c39a48c
Arg [4] : defaultFeeInfo (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
11 Constructor Arguments found :
Arg [0] : 000000000000000000000000a0f25b796dd59e504077f87caea1c0472cd6b7b4
Arg [1] : 000000000000000000000000ff02150dbd816526b2c7b0d4e5abf63e16ef6402
Arg [2] : 000000000000000000000000457b8bb4d6c8cc2e506789f768996ddae60cd4fd
Arg [3] : 000000000000000000000000d00ae08403b9bbb9124bb305c09058e32c39a48c
Arg [4] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [5] : 0000000000000000000000002d99abd9008dc933ff5c0cd271b88309593ab921
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [10] : 000000000000000000000000d00ae08403b9bbb9124bb305c09058e32c39a48c


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading