ETH Price: $2,673.84 (+1.80%)

Contract

0x2Bba09866b6F1025258542478C39720A09B728bF
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

> 10 Token Transfers found.

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Swapper

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 20000 runs

Other Settings:
cancun EvmVersion
File 1 of 15 : Swapper.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.0;

import {IEVault, IERC20} from "evk/EVault/IEVault.sol";
import {SafeERC20Lib} from "evk/EVault/shared/lib/SafeERC20Lib.sol";
import {RevertBytes} from "evk/EVault/shared/lib/RevertBytes.sol";

import {ISwapper} from "./ISwapper.sol";

import {GenericHandler} from "./handlers/GenericHandler.sol";
import {UniswapV2Handler} from "./handlers/UniswapV2Handler.sol";
import {UniswapV3Handler} from "./handlers/UniswapV3Handler.sol";

/// @title Swapper
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Untrusted helper contract for EVK for performing swaps and swaps to repay
contract Swapper is GenericHandler, UniswapV2Handler, UniswapV3Handler {
    bytes32 public constant HANDLER_GENERIC = bytes32("Generic");
    bytes32 public constant HANDLER_UNISWAP_V2 = bytes32("UniswapV2");
    bytes32 public constant HANDLER_UNISWAP_V3 = bytes32("UniswapV3");

    uint256 internal constant REENTRANCYLOCK_UNLOCKED = 1;
    uint256 internal constant REENTRANCYLOCK_LOCKED = 2;

    uint256 private reentrancyLock;

    error Swapper_UnknownMode();
    error Swapper_UnknownHandler();
    error Swapper_Reentrancy();

    // In the locked state, allow contract to call itself, but block all external calls
    modifier externalLock() {
        bool isExternal = msg.sender != address(this);

        if (isExternal) {
            if (reentrancyLock == REENTRANCYLOCK_LOCKED) revert Swapper_Reentrancy();
            reentrancyLock = REENTRANCYLOCK_LOCKED;
        }

        _;

        if (isExternal) reentrancyLock = REENTRANCYLOCK_UNLOCKED;
    }

    constructor(address uniswapRouterV2, address uniswapRouterV3)
        UniswapV2Handler(uniswapRouterV2)
        UniswapV3Handler(uniswapRouterV3)
    {}

    /// @inheritdoc ISwapper
    function swap(SwapParams memory params) public externalLock {
        if (params.mode >= MODE_MAX_VALUE) revert Swapper_UnknownMode();

        if (params.handler == HANDLER_GENERIC) {
            swapGeneric(params);
        } else if (params.handler == HANDLER_UNISWAP_V2) {
            swapUniswapV2(params);
        } else if (params.handler == HANDLER_UNISWAP_V3) {
            swapUniswapV3(params);
        } else {
            revert Swapper_UnknownHandler();
        }

        if (params.mode == MODE_EXACT_IN) return;

        // swapping to target debt is only useful for repaying
        if (params.mode == MODE_TARGET_DEBT) {
            // at this point amountOut holds the required repay amount
            _repayAndDeposit(params.tokenOut, params.receiver, params.amountOut, params.account);
        }

        // return unused input token after exact output swap
        _deposit(params.tokenIn, params.vaultIn, 0, params.accountIn);
    }

    /// @inheritdoc ISwapper
    /// @dev in case of over-swapping to repay, pass max uint amount
    function repay(address token, address vault, uint256 repayAmount, address account) public externalLock {
        setMaxAllowance(token, vault);
        uint256 balance = IERC20(token).balanceOf(address(this));
        repayAmount = _capRepayToBalance(repayAmount, balance);

        IEVault(vault).repay(repayAmount, account);
    }

    /// @inheritdoc ISwapper
    function repayAndDeposit(address token, address vault, uint256 repayAmount, address account) public externalLock {
        _repayAndDeposit(token, vault, repayAmount, account);
    }

    /// @inheritdoc ISwapper
    function deposit(address token, address vault, uint256 amountMin, address account) public externalLock {
        _deposit(token, vault, amountMin, account);
    }

    /// @inheritdoc ISwapper
    function sweep(address token, uint256 amountMin, address to) public externalLock {
        uint256 balance = IERC20(token).balanceOf(address(this));
        if (balance >= amountMin) {
            SafeERC20Lib.safeTransfer(IERC20(token), to, balance);
        }
    }

    /// @inheritdoc ISwapper
    function multicall(bytes[] memory calls) external externalLock {
        for (uint256 i; i < calls.length; i++) {
            (bool success, bytes memory result) = address(this).call(calls[i]);
            if (!success) RevertBytes.revertBytes(result);
        }
    }

    // internal

    function _deposit(address token, address vault, uint256 amountMin, address account) internal {
        setMaxAllowance(token, vault);
        uint256 balance = IERC20(token).balanceOf(address(this));

        if (balance >= amountMin) {
            IEVault(vault).deposit(balance, account);
        }
    }

    function _repayAndDeposit(address token, address vault, uint256 repayAmount, address account) internal {
        setMaxAllowance(token, vault);
        uint256 balance = IERC20(token).balanceOf(address(this));
        repayAmount = _capRepayToBalance(repayAmount, balance);

        repayAmount = IEVault(vault).repay(repayAmount, account);

        if (balance > repayAmount) {
            IEVault(vault).deposit(type(uint256).max, account);
        }
    }

    // Adjust repay to the available balance. It is needed when exact output swaps are not exact in reality.
    // It is user's responsibility to verify the debt is within accepted limits after the call to Swapper
    function _capRepayToBalance(uint256 repayAmount, uint256 balance) internal pure returns (uint256) {
        if (repayAmount != type(uint256).max && repayAmount > balance) {
            repayAmount = balance;
        }

        return repayAmount;
    }
}

File 2 of 15 : IEVault.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.8.0;

import {IVault as IEVCVault} from "ethereum-vault-connector/interfaces/IVault.sol";

// Full interface of EVault and all it's modules

/// @title IInitialize
/// @notice Interface of the initialization module of EVault
interface IInitialize {
    /// @notice Initialization of the newly deployed proxy contract
    /// @param proxyCreator Account which created the proxy or should be the initial governor
    function initialize(address proxyCreator) external;
}

/// @title IERC20
/// @notice Interface of the EVault's Initialize module
interface IERC20 {
    /// @notice Vault share token (eToken) name, ie "Euler Vault: DAI"
    /// @return The name of the eToken
    function name() external view returns (string memory);

    /// @notice Vault share token (eToken) symbol, ie "eDAI"
    /// @return The symbol of the eToken
    function symbol() external view returns (string memory);

    /// @notice Decimals, the same as the asset's or 18 if the asset doesn't implement `decimals()`
    /// @return The decimals of the eToken
    function decimals() external view returns (uint8);

    /// @notice Sum of all eToken balances
    /// @return The total supply of the eToken
    function totalSupply() external view returns (uint256);

    /// @notice Balance of a particular account, in eTokens
    /// @param account Address to query
    /// @return The balance of the account
    function balanceOf(address account) external view returns (uint256);

    /// @notice Retrieve the current allowance
    /// @param holder The account holding the eTokens
    /// @param spender Trusted address
    /// @return The allowance from holder for spender
    function allowance(address holder, address spender) external view returns (uint256);

    /// @notice Transfer eTokens to another address
    /// @param to Recipient account
    /// @param amount In shares.
    /// @return True if transfer succeeded
    function transfer(address to, uint256 amount) external returns (bool);

    /// @notice Transfer eTokens from one address to another
    /// @param from This address must've approved the to address
    /// @param to Recipient account
    /// @param amount In shares
    /// @return True if transfer succeeded
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

    /// @notice Allow spender to access an amount of your eTokens
    /// @param spender Trusted address
    /// @param amount Use max uint for "infinite" allowance
    /// @return True if approval succeeded
    function approve(address spender, uint256 amount) external returns (bool);
}

/// @title IToken
/// @notice Interface of the EVault's Token module
interface IToken is IERC20 {
    /// @notice Transfer the full eToken balance of an address to another
    /// @param from This address must've approved the to address
    /// @param to Recipient account
    /// @return True if transfer succeeded
    function transferFromMax(address from, address to) external returns (bool);
}

/// @title IERC4626
/// @notice Interface of an ERC4626 vault
interface IERC4626 {
    /// @notice Vault's underlying asset
    /// @return The vault's underlying asset
    function asset() external view returns (address);

    /// @notice Total amount of managed assets, cash and borrows
    /// @return The total amount of assets
    function totalAssets() external view returns (uint256);

    /// @notice Calculate amount of assets corresponding to the requested shares amount
    /// @param shares Amount of shares to convert
    /// @return The amount of assets
    function convertToAssets(uint256 shares) external view returns (uint256);

    /// @notice Calculate amount of shares corresponding to the requested assets amount
    /// @param assets Amount of assets to convert
    /// @return The amount of shares
    function convertToShares(uint256 assets) external view returns (uint256);

    /// @notice Fetch the maximum amount of assets a user can deposit
    /// @param account Address to query
    /// @return The max amount of assets the account can deposit
    function maxDeposit(address account) external view returns (uint256);

    /// @notice Calculate an amount of shares that would be created by depositing assets
    /// @param assets Amount of assets deposited
    /// @return Amount of shares received
    function previewDeposit(uint256 assets) external view returns (uint256);

    /// @notice Fetch the maximum amount of shares a user can mint
    /// @param account Address to query
    /// @return The max amount of shares the account can mint
    function maxMint(address account) external view returns (uint256);

    /// @notice Calculate an amount of assets that would be required to mint requested amount of shares
    /// @param shares Amount of shares to be minted
    /// @return Required amount of assets
    function previewMint(uint256 shares) external view returns (uint256);

    /// @notice Fetch the maximum amount of assets a user is allowed to withdraw
    /// @param owner Account holding the shares
    /// @return The maximum amount of assets the owner is allowed to withdraw
    function maxWithdraw(address owner) external view returns (uint256);

    /// @notice Calculate the amount of shares that will be burned when withdrawing requested amount of assets
    /// @param assets Amount of assets withdrawn
    /// @return Amount of shares burned
    function previewWithdraw(uint256 assets) external view returns (uint256);

    /// @notice Fetch the maximum amount of shares a user is allowed to redeem for assets
    /// @param owner Account holding the shares
    /// @return The maximum amount of shares the owner is allowed to redeem
    function maxRedeem(address owner) external view returns (uint256);

    /// @notice Calculate the amount of assets that will be transferred when redeeming requested amount of shares
    /// @param shares Amount of shares redeemed
    /// @return Amount of assets transferred
    function previewRedeem(uint256 shares) external view returns (uint256);

    /// @notice Transfer requested amount of underlying tokens from sender to the vault pool in return for shares
    /// @param amount Amount of assets to deposit (use max uint256 for full underlying token balance)
    /// @param receiver An account to receive the shares
    /// @return Amount of shares minted
    /// @dev Deposit will round down the amount of assets that are converted to shares. To prevent losses consider using
    /// mint instead.
    function deposit(uint256 amount, address receiver) external returns (uint256);

    /// @notice Transfer underlying tokens from sender to the vault pool in return for requested amount of shares
    /// @param amount Amount of shares to be minted
    /// @param receiver An account to receive the shares
    /// @return Amount of assets deposited
    function mint(uint256 amount, address receiver) external returns (uint256);

    /// @notice Transfer requested amount of underlying tokens from the vault and decrease account's shares balance
    /// @param amount Amount of assets to withdraw
    /// @param receiver Account to receive the withdrawn assets
    /// @param owner Account holding the shares to burn
    /// @return Amount of shares burned
    function withdraw(uint256 amount, address receiver, address owner) external returns (uint256);

    /// @notice Burn requested shares and transfer corresponding underlying tokens from the vault to the receiver
    /// @param amount Amount of shares to burn (use max uint256 to burn full owner balance)
    /// @param receiver Account to receive the withdrawn assets
    /// @param owner Account holding the shares to burn.
    /// @return Amount of assets transferred
    function redeem(uint256 amount, address receiver, address owner) external returns (uint256);
}

/// @title IVault
/// @notice Interface of the EVault's Vault module
interface IVault is IERC4626 {
    /// @notice Balance of the fees accumulator, in shares
    /// @return The accumulated fees in shares
    function accumulatedFees() external view returns (uint256);

    /// @notice Balance of the fees accumulator, in underlying units
    /// @return The accumulated fees in asset units
    function accumulatedFeesAssets() external view returns (uint256);

    /// @notice Address of the original vault creator
    /// @return The address of the creator
    function creator() external view returns (address);

    /// @notice Creates shares for the receiver, from excess asset balances of the vault (not accounted for in `cash`)
    /// @param amount Amount of assets to claim (use max uint256 to claim all available assets)
    /// @param receiver An account to receive the shares
    /// @return Amount of shares minted
    /// @dev Could be used as an alternative deposit flow in certain scenarios. E.g. swap directly to the vault, call
    /// `skim` to claim deposit.
    function skim(uint256 amount, address receiver) external returns (uint256);
}

/// @title IBorrowing
/// @notice Interface of the EVault's Borrowing module
interface IBorrowing {
    /// @notice Sum of all outstanding debts, in underlying units (increases as interest is accrued)
    /// @return The total borrows in asset units
    function totalBorrows() external view returns (uint256);

    /// @notice Sum of all outstanding debts, in underlying units scaled up by shifting
    /// INTERNAL_DEBT_PRECISION_SHIFT bits
    /// @return The total borrows in internal debt precision
    function totalBorrowsExact() external view returns (uint256);

    /// @notice Balance of vault assets as tracked by deposits/withdrawals and borrows/repays
    /// @return The amount of assets the vault tracks as current direct holdings
    function cash() external view returns (uint256);

    /// @notice Debt owed by a particular account, in underlying units
    /// @param account Address to query
    /// @return The debt of the account in asset units
    function debtOf(address account) external view returns (uint256);

    /// @notice Debt owed by a particular account, in underlying units scaled up by shifting
    /// INTERNAL_DEBT_PRECISION_SHIFT bits
    /// @param account Address to query
    /// @return The debt of the account in internal precision
    function debtOfExact(address account) external view returns (uint256);

    /// @notice Retrieves the current interest rate for an asset
    /// @return The interest rate in yield-per-second, scaled by 10**27
    function interestRate() external view returns (uint256);

    /// @notice Retrieves the current interest rate accumulator for an asset
    /// @return An opaque accumulator that increases as interest is accrued
    function interestAccumulator() external view returns (uint256);

    /// @notice Returns an address of the sidecar DToken
    /// @return The address of the DToken
    function dToken() external view returns (address);

    /// @notice Transfer underlying tokens from the vault to the sender, and increase sender's debt
    /// @param amount Amount of assets to borrow (use max uint256 for all available tokens)
    /// @param receiver Account receiving the borrowed tokens
    /// @return Amount of assets borrowed
    function borrow(uint256 amount, address receiver) external returns (uint256);

    /// @notice Transfer underlying tokens from the sender to the vault, and decrease receiver's debt
    /// @param amount Amount of debt to repay in assets (use max uint256 for full debt)
    /// @param receiver Account holding the debt to be repaid
    /// @return Amount of assets repaid
    function repay(uint256 amount, address receiver) external returns (uint256);

    /// @notice Pay off liability with shares ("self-repay")
    /// @param amount In asset units (use max uint256 to repay the debt in full or up to the available deposit)
    /// @param receiver Account to remove debt from by burning sender's shares
    /// @return shares Amount of shares burned
    /// @return debt Amount of debt removed in assets
    /// @dev Equivalent to withdrawing and repaying, but no assets are needed to be present in the vault
    /// @dev Contrary to a regular `repay`, if account is unhealthy, the repay amount must bring the account back to
    /// health, or the operation will revert during account status check
    function repayWithShares(uint256 amount, address receiver) external returns (uint256 shares, uint256 debt);

    /// @notice Take over debt from another account
    /// @param amount Amount of debt in asset units (use max uint256 for all the account's debt)
    /// @param from Account to pull the debt from
    /// @dev Due to internal debt precision accounting, the liability reported on either or both accounts after
    /// calling `pullDebt` may not match the `amount` requested precisely
    function pullDebt(uint256 amount, address from) external;

    /// @notice Request a flash-loan. A onFlashLoan() callback in msg.sender will be invoked, which must repay the loan
    /// to the main Euler address prior to returning.
    /// @param amount In asset units
    /// @param data Passed through to the onFlashLoan() callback, so contracts don't need to store transient data in
    /// storage
    function flashLoan(uint256 amount, bytes calldata data) external;

    /// @notice Updates interest accumulator and totalBorrows, credits reserves, re-targets interest rate, and logs
    /// vault status
    function touch() external;
}

/// @title ILiquidation
/// @notice Interface of the EVault's Liquidation module
interface ILiquidation {
    /// @notice Checks to see if a liquidation would be profitable, without actually doing anything
    /// @param liquidator Address that will initiate the liquidation
    /// @param violator Address that may be in collateral violation
    /// @param collateral Collateral which is to be seized
    /// @return maxRepay Max amount of debt that can be repaid, in asset units
    /// @return maxYield Yield in collateral corresponding to max allowed amount of debt to be repaid, in collateral
    /// balance (shares for vaults)
    function checkLiquidation(address liquidator, address violator, address collateral)
        external
        view
        returns (uint256 maxRepay, uint256 maxYield);

    /// @notice Attempts to perform a liquidation
    /// @param violator Address that may be in collateral violation
    /// @param collateral Collateral which is to be seized
    /// @param repayAssets The amount of underlying debt to be transferred from violator to sender, in asset units (use
    /// max uint256 to repay the maximum possible amount). Meant as slippage check together with `minYieldBalance`
    /// @param minYieldBalance The minimum acceptable amount of collateral to be transferred from violator to sender, in
    /// collateral balance units (shares for vaults).  Meant as slippage check together with `repayAssets`
    /// @dev If `repayAssets` is set to max uint256 it is assumed the caller will perform their own slippage checks to
    /// make sure they are not taking on too much debt. This option is mainly meant for smart contract liquidators
    function liquidate(address violator, address collateral, uint256 repayAssets, uint256 minYieldBalance) external;
}

/// @title IRiskManager
/// @notice Interface of the EVault's RiskManager module
interface IRiskManager is IEVCVault {
    /// @notice Retrieve account's total liquidity
    /// @param account Account holding debt in this vault
    /// @param liquidation Flag to indicate if the calculation should be performed in liquidation vs account status
    /// check mode, where different LTV values might apply.
    /// @return collateralValue Total risk adjusted value of all collaterals in unit of account
    /// @return liabilityValue Value of debt in unit of account
    function accountLiquidity(address account, bool liquidation)
        external
        view
        returns (uint256 collateralValue, uint256 liabilityValue);

    /// @notice Retrieve account's liquidity per collateral
    /// @param account Account holding debt in this vault
    /// @param liquidation Flag to indicate if the calculation should be performed in liquidation vs account status
    /// check mode, where different LTV values might apply.
    /// @return collaterals Array of collaterals enabled
    /// @return collateralValues Array of risk adjusted collateral values corresponding to items in collaterals array.
    /// In unit of account
    /// @return liabilityValue Value of debt in unit of account
    function accountLiquidityFull(address account, bool liquidation)
        external
        view
        returns (address[] memory collaterals, uint256[] memory collateralValues, uint256 liabilityValue);

    /// @notice Release control of the account on EVC if no outstanding debt is present
    function disableController() external;

    /// @notice Checks the status of an account and reverts if account is not healthy
    /// @param account The address of the account to be checked
    /// @return magicValue Must return the bytes4 magic value 0xb168c58f (which is a selector of this function) when
    /// account status is valid, or revert otherwise.
    /// @dev Only callable by EVC during status checks
    function checkAccountStatus(address account, address[] calldata collaterals) external view returns (bytes4);

    /// @notice Checks the status of the vault and reverts if caps are exceeded
    /// @return magicValue Must return the bytes4 magic value 0x4b3d1223 (which is a selector of this function) when
    /// account status is valid, or revert otherwise.
    /// @dev Only callable by EVC during status checks
    function checkVaultStatus() external returns (bytes4);
}

/// @title IBalanceForwarder
/// @notice Interface of the EVault's BalanceForwarder module
interface IBalanceForwarder {
    /// @notice Retrieve the address of rewards contract, tracking changes in account's balances
    /// @return The balance tracker address
    function balanceTrackerAddress() external view returns (address);

    /// @notice Retrieves boolean indicating if the account opted in to forward balance changes to the rewards contract
    /// @param account Address to query
    /// @return True if balance forwarder is enabled
    function balanceForwarderEnabled(address account) external view returns (bool);

    /// @notice Enables balance forwarding for the authenticated account
    /// @dev Only the authenticated account can enable balance forwarding for itself
    /// @dev Should call the IBalanceTracker hook with the current account's balance
    function enableBalanceForwarder() external;

    /// @notice Disables balance forwarding for the authenticated account
    /// @dev Only the authenticated account can disable balance forwarding for itself
    /// @dev Should call the IBalanceTracker hook with the account's balance of 0
    function disableBalanceForwarder() external;
}

/// @title IGovernance
/// @notice Interface of the EVault's Governance module
interface IGovernance {
    /// @notice Retrieves the address of the governor
    /// @return The governor address
    function governorAdmin() external view returns (address);

    /// @notice Retrieves address of the governance fee receiver
    /// @return The fee receiver address
    function feeReceiver() external view returns (address);

    /// @notice Retrieves the interest fee in effect for the vault
    /// @return Amount of interest that is redirected as a fee, as a fraction scaled by 1e4
    function interestFee() external view returns (uint16);

    /// @notice Looks up an asset's currently configured interest rate model
    /// @return Address of the interest rate contract or address zero to indicate 0% interest
    function interestRateModel() external view returns (address);

    /// @notice Retrieves the ProtocolConfig address
    /// @return The protocol config address
    function protocolConfigAddress() external view returns (address);

    /// @notice Retrieves the protocol fee share
    /// @return A percentage share of fees accrued belonging to the protocol, in 1e4 scale
    function protocolFeeShare() external view returns (uint256);

    /// @notice Retrieves the address which will receive protocol's fees
    /// @notice The protocol fee receiver address
    function protocolFeeReceiver() external view returns (address);

    /// @notice Retrieves supply and borrow caps in AmountCap format
    /// @return supplyCap The supply cap in AmountCap format
    /// @return borrowCap The borrow cap in AmountCap format
    function caps() external view returns (uint16 supplyCap, uint16 borrowCap);

    /// @notice Retrieves the borrow LTV of the collateral, which is used to determine if the account is healthy during
    /// account status checks.
    /// @param collateral The address of the collateral to query
    /// @return Borrowing LTV in 1e4 scale
    function LTVBorrow(address collateral) external view returns (uint16);

    /// @notice Retrieves the current liquidation LTV, which is used to determine if the account is eligible for
    /// liquidation
    /// @param collateral The address of the collateral to query
    /// @return Liquidation LTV in 1e4 scale
    function LTVLiquidation(address collateral) external view returns (uint16);

    /// @notice Retrieves LTV configuration for the collateral
    /// @param collateral Collateral asset
    /// @return borrowLTV The current value of borrow LTV for originating positions
    /// @return liquidationLTV The value of fully converged liquidation LTV
    /// @return initialLiquidationLTV The initial value of the liquidation LTV, when the ramp began
    /// @return targetTimestamp The timestamp when the liquidation LTV is considered fully converged
    /// @return rampDuration The time it takes for the liquidation LTV to converge from the initial value to the fully
    /// converged value
    function LTVFull(address collateral)
        external
        view
        returns (
            uint16 borrowLTV,
            uint16 liquidationLTV,
            uint16 initialLiquidationLTV,
            uint48 targetTimestamp,
            uint32 rampDuration
        );

    /// @notice Retrieves a list of collaterals with configured LTVs
    /// @return List of asset collaterals
    /// @dev Returned assets could have the ltv disabled (set to zero)
    function LTVList() external view returns (address[] memory);

    /// @notice Retrieves the maximum liquidation discount
    /// @return The maximum liquidation discount in 1e4 scale
    /// @dev The default value, which is zero, is deliberately bad, as it means there would be no incentive to liquidate
    /// unhealthy users. The vault creator must take care to properly select the limit, given the underlying and
    /// collaterals used.
    function maxLiquidationDiscount() external view returns (uint16);

    /// @notice Retrieves liquidation cool-off time, which must elapse after successful account status check before
    /// account can be liquidated
    /// @return The liquidation cool off time in seconds
    function liquidationCoolOffTime() external view returns (uint16);

    /// @notice Retrieves a hook target and a bitmask indicating which operations call the hook target
    /// @return hookTarget Address of the hook target contract
    /// @return hookedOps Bitmask with operations that should call the hooks. See Constants.sol for a list of operations
    function hookConfig() external view returns (address hookTarget, uint32 hookedOps);

    /// @notice Retrieves a bitmask indicating enabled config flags
    /// @return Bitmask with config flags enabled
    function configFlags() external view returns (uint32);

    /// @notice Address of EthereumVaultConnector contract
    /// @return The EVC address
    function EVC() external view returns (address);

    /// @notice Retrieves a reference asset used for liquidity calculations
    /// @return The address of the reference asset
    function unitOfAccount() external view returns (address);

    /// @notice Retrieves the address of the oracle contract
    /// @return The address of the oracle
    function oracle() external view returns (address);

    /// @notice Retrieves the Permit2 contract address
    /// @return The address of the Permit2 contract
    function permit2Address() external view returns (address);

    /// @notice Splits accrued fees balance according to protocol fee share and transfers shares to the governor fee
    /// receiver and protocol fee receiver
    function convertFees() external;

    /// @notice Set a new governor address
    /// @param newGovernorAdmin The new governor address
    /// @dev Set to zero address to renounce privileges and make the vault non-governed
    function setGovernorAdmin(address newGovernorAdmin) external;

    /// @notice Set a new governor fee receiver address
    /// @param newFeeReceiver The new fee receiver address
    function setFeeReceiver(address newFeeReceiver) external;

    /// @notice Set a new LTV config
    /// @param collateral Address of collateral to set LTV for
    /// @param borrowLTV New borrow LTV, for assessing account's health during account status checks, in 1e4 scale
    /// @param liquidationLTV New liquidation LTV after ramp ends in 1e4 scale
    /// @param rampDuration Ramp duration in seconds
    function setLTV(address collateral, uint16 borrowLTV, uint16 liquidationLTV, uint32 rampDuration) external;

    /// @notice Set a new maximum liquidation discount
    /// @param newDiscount New maximum liquidation discount in 1e4 scale
    /// @dev If the discount is zero (the default), the liquidators will not be incentivized to liquidate unhealthy
    /// accounts
    function setMaxLiquidationDiscount(uint16 newDiscount) external;

    /// @notice Set a new liquidation cool off time, which must elapse after successful account status check before
    /// account can be liquidated
    /// @param newCoolOffTime The new liquidation cool off time in seconds
    /// @dev Setting cool off time to zero allows liquidating the account in the same block as the last successful
    /// account status check
    function setLiquidationCoolOffTime(uint16 newCoolOffTime) external;

    /// @notice Set a new interest rate model contract
    /// @param newModel The new IRM address
    /// @dev If the new model reverts, perhaps due to governor error, the vault will silently use a zero interest
    /// rate. Governor should make sure the new interest rates are computed as expected.
    function setInterestRateModel(address newModel) external;

    /// @notice Set a new hook target and a new bitmap indicating which operations should call the hook target.
    /// Operations are defined in Constants.sol.
    /// @param newHookTarget The new hook target address. Use address(0) to simply disable hooked operations
    /// @param newHookedOps Bitmask with the new hooked operations
    /// @dev All operations are initially disabled in a newly created vault. The vault creator must set their
    /// own configuration to make the vault usable
    function setHookConfig(address newHookTarget, uint32 newHookedOps) external;

    /// @notice Set new bitmap indicating which config flags should be enabled. Flags are defined in Constants.sol
    /// @param newConfigFlags Bitmask with the new config flags
    function setConfigFlags(uint32 newConfigFlags) external;

    /// @notice Set new supply and borrow caps in AmountCap format
    /// @param supplyCap The new supply cap in AmountCap fromat
    /// @param borrowCap The new borrow cap in AmountCap fromat
    function setCaps(uint16 supplyCap, uint16 borrowCap) external;

    /// @notice Set a new interest fee
    /// @param newFee The new interest fee
    function setInterestFee(uint16 newFee) external;
}

/// @title IEVault
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Interface of the EVault, an EVC enabled lending vault
interface IEVault is
    IInitialize,
    IToken,
    IVault,
    IBorrowing,
    ILiquidation,
    IRiskManager,
    IBalanceForwarder,
    IGovernance
{
    /// @notice Fetch address of the `Initialize` module
    function MODULE_INITIALIZE() external view returns (address);
    /// @notice Fetch address of the `Token` module
    function MODULE_TOKEN() external view returns (address);
    /// @notice Fetch address of the `Vault` module
    function MODULE_VAULT() external view returns (address);
    /// @notice Fetch address of the `Borrowing` module
    function MODULE_BORROWING() external view returns (address);
    /// @notice Fetch address of the `Liquidation` module
    function MODULE_LIQUIDATION() external view returns (address);
    /// @notice Fetch address of the `RiskManager` module
    function MODULE_RISKMANAGER() external view returns (address);
    /// @notice Fetch address of the `BalanceForwarder` module
    function MODULE_BALANCE_FORWARDER() external view returns (address);
    /// @notice Fetch address of the `Governance` module
    function MODULE_GOVERNANCE() external view returns (address);
}

File 3 of 15 : SafeERC20Lib.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.0;

import {IERC20} from "../../IEVault.sol";
import {RevertBytes} from "./RevertBytes.sol";
import {IPermit2} from "../../../interfaces/IPermit2.sol";

/// @title SafeERC20Lib Library
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice The library provides helpers for ERC20 transfers, including Permit2 support
library SafeERC20Lib {
    error E_TransferFromFailed(bytes errorPermit2, bytes errorTransferFrom);

    // If no code exists under the token address, the function will succeed. EVault ensures this is not the case in
    // `initialize`.
    function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value)
        internal
        returns (bool, bytes memory)
    {
        (bool success, bytes memory data) = address(token).call(abi.encodeCall(IERC20.transferFrom, (from, to, value)));

        return isEmptyOrTrueReturn(success, data) ? (true, bytes("")) : (false, data);
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value, address permit2) internal {
        bool success;
        bytes memory permit2Data;
        bytes memory transferData;

        if (permit2 != address(0) && value <= type(uint160).max) {
            // it's safe to down-cast value to uint160
            (success, permit2Data) =
                permit2.call(abi.encodeCall(IPermit2.transferFrom, (from, to, uint160(value), address(token))));
        }

        if (!success) {
            (success, transferData) = trySafeTransferFrom(token, from, to, value);
        }

        if (!success) revert E_TransferFromFailed(permit2Data, transferData);
    }

    // If no code exists under the token address, the function will succeed. EVault ensures this is not the case in
    // `initialize`.
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        (bool success, bytes memory data) = address(token).call(abi.encodeCall(IERC20.transfer, (to, value)));
        if (!isEmptyOrTrueReturn(success, data)) RevertBytes.revertBytes(data);
    }

    function isEmptyOrTrueReturn(bool callSuccess, bytes memory data) private pure returns (bool) {
        return callSuccess && (data.length == 0 || (data.length >= 32 && abi.decode(data, (bool))));
    }
}

File 4 of 15 : RevertBytes.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.0;

import "../Errors.sol";

/// @title RevertBytes Library
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice The library provides a helper function for bubbling up errors
library RevertBytes {
    function revertBytes(bytes memory errMsg) internal pure {
        if (errMsg.length > 0) {
            assembly {
                revert(add(32, errMsg), mload(errMsg))
            }
        }

        revert Errors.E_EmptyError();
    }
}

File 5 of 15 : ISwapper.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.8.0;

/// @title ISwapper
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Interface of helper contracts, which handle swapping of assets for Euler Vault Kit
interface ISwapper {
    /// @title SwapParams
    /// @notice This struct holds all the parameters needed to carry out a swap
    struct SwapParams {
        // An id of the swap handler to use
        bytes32 handler;
        // Swap mode to execute
        // 0 - exact input swap
        // 1 - exect output swap
        // 2 - exact output swap and repay, targeting a debt amount of an account
        uint256 mode;
        // An EVC compatible account address, used e.g. as receiver of repay in swap and repay mode
        address account;
        // Sold asset
        address tokenIn;
        // Bought asset
        address tokenOut;
        // Vault to which the unused input in exact output swap will be deposited back
        address vaultIn;
        // An EVC compatible account address, to which the unused input in exact output swap will be deposited back
        address accountIn;
        // In swapping modes (0 and 1) - address of the intended recipient of the bought tokens
        // In swap and repay mode (2) - address of the liability vault of the account, where to repay debt
        // Note that if the swap uses off-chain encoded payload, the receiver might be ignored. The user
        // should verify the assets are in fact in the receiver address after the swap
        address receiver;
        // In exact input mode (0) - ignored
        // In exact output mode (1) - amount of `tokenOut` to buy
        // In swap and repay mode (2) - amount of debt the account should have after swap and repay.
        //    To repay all debt without leaving any dust, set this to zero.
        uint256 amountOut;
        // Auxiliary payload for swap providers. For GenericHandler it's an abi encoded tuple: target contract address
        // and call data
        bytes data;
    }

    /// @notice Execute a swap (and possibly repay or deposit) according to the SwapParams configuration
    /// @param params Configuration of the swap
    function swap(SwapParams calldata params) external;

    /// @notice Use the contract's token balance to repay debt of the account in a lending vault
    /// @param token The asset that is borrowed
    /// @param vault The lending vault where the debt is tracked
    /// @param repayAmount Amount of debt to repay
    /// @param account Receiver of the repay
    /// @dev If contract's balance is lower than requested repay amount, repay only the balance
    function repay(address token, address vault, uint256 repayAmount, address account) external;

    /// @notice Use the contract's token balance to repay debt of the account in a lending vault
    /// and deposit any remaining balance for the account in that same vault
    /// @param token The asset that is borrowed
    /// @param vault The lending vault where the debt is tracked
    /// @param repayAmount Amount of debt to repay
    /// @param account Receiver of the repay
    /// @dev If contract's balance is lower than requested repay amount, repay only the balance
    function repayAndDeposit(address token, address vault, uint256 repayAmount, address account) external;

    /// @notice Use all of the contract's token balance to execute a deposit for an account
    /// @param token Asset to deposit
    /// @param vault Vault to deposit the token to
    /// @param amountMin A minimum amount of tokens to deposit. If unavailable, the operation is a no-op
    /// @param account Receiver of the repay
    /// @dev Use amountMin to ignore dust
    function deposit(address token, address vault, uint256 amountMin, address account) external;

    /// @notice Transfer all tokens held by the contract
    /// @param token Token to transfer
    /// @param amountMin Minimum amount of tokens to transfer. If unavailable, the operation is a no-op
    /// @param to Address to send the tokens to
    function sweep(address token, uint256 amountMin, address to) external;

    /// @notice Call multiple functions of the contract
    /// @param calls Array of encoded payloads
    /// @dev Calls itself with regular external calls
    function multicall(bytes[] memory calls) external;
}

File 6 of 15 : GenericHandler.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.0;

import {BaseHandler} from "./BaseHandler.sol";

/// @title GenericHandler
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Swap handler executing arbitrary trades on arbitrary target
abstract contract GenericHandler is BaseHandler {
    /// @dev the handler expects SwapParams.data to contain an abi encoded tuple: target contract address and call data
    function swapGeneric(SwapParams memory params) internal virtual {
        (address target, bytes memory payload) = abi.decode(params.data, (address, bytes));

        if (params.mode == MODE_TARGET_DEBT) resolveParams(params); // set repay amount in params.amountOut

        setMaxAllowance(params.tokenIn, target);

        (bool success, bytes memory result) = target.call(payload);
        if (!success) revert Swapper_SwapError(target, result);
    }
}

File 7 of 15 : UniswapV2Handler.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.0;

import {BaseHandler} from "./BaseHandler.sol";
import {IUniswapV2Router01} from "../vendor/ISwapRouterV2.sol";

/// @title UniswapV2Handler
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Swap handler executing exact output trades on Uniswap V2
abstract contract UniswapV2Handler is BaseHandler {
    address public immutable uniswapRouterV2;

    error UniswapV2Handler_InvalidPath();

    constructor(address _uniswapRouterV2) {
        uniswapRouterV2 = _uniswapRouterV2;
    }

    function swapUniswapV2(SwapParams memory params) internal virtual {
        if (params.mode == MODE_EXACT_IN) revert Swapper_UnsupportedMode();
        if (params.data.length < 64 || params.data.length % 32 != 0) revert UniswapV2Handler_InvalidPath();

        setMaxAllowance(params.tokenIn, uniswapRouterV2);
        // process params according to the mode and current state
        (uint256 amountOut, address receiver) = resolveParams(params);

        if (amountOut > 0) {
            (bool success, bytes memory result) = uniswapRouterV2.call(
                abi.encodeCall(
                    IUniswapV2Router01.swapTokensForExactTokens,
                    (amountOut, type(uint256).max, abi.decode(params.data, (address[])), receiver, block.timestamp)
                )
            );
            if (!success) revert Swapper_SwapError(uniswapRouterV2, result);
        }
    }
}

File 8 of 15 : UniswapV3Handler.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.0;

import {BaseHandler} from "./BaseHandler.sol";
import {ISwapRouterV3} from "../vendor/ISwapRouterV3.sol";

/// @title UniswapV3Handler
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Swap handler executing exact output trades on Uniswap V3
abstract contract UniswapV3Handler is BaseHandler {
    address public immutable uniswapRouterV3;

    error UniswapV3Handler_InvalidPath();

    constructor(address _uniswapRouterV3) {
        uniswapRouterV3 = _uniswapRouterV3;
    }

    function swapUniswapV3(SwapParams memory params) internal virtual {
        if (params.mode == MODE_EXACT_IN) revert Swapper_UnsupportedMode();
        unchecked {
            if (params.data.length < 43 || (params.data.length - 20) % 23 != 0) revert UniswapV3Handler_InvalidPath();
        }

        setMaxAllowance(params.tokenIn, uniswapRouterV3);
        // update amountOut and receiver according to the mode and current state
        (uint256 amountOut, address receiver) = resolveParams(params);

        if (amountOut > 0) {
            (bool success, bytes memory result) = uniswapRouterV3.call(
                abi.encodeCall(
                    ISwapRouterV3.exactOutput,
                    ISwapRouterV3.ExactOutputParams({
                        path: params.data,
                        recipient: receiver,
                        amountOut: amountOut,
                        amountInMaximum: type(uint256).max,
                        deadline: block.timestamp
                    })
                )
            );
            if (!success) revert Swapper_SwapError(uniswapRouterV3, result);
        }
    }
}

File 9 of 15 : IVault.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.8.0;

/// @title IVault
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice This interface defines the methods for the Vault for the purpose of integration with the Ethereum Vault
/// Connector.
interface IVault {
    /// @notice Disables a controller (this vault) for the authenticated account.
    /// @dev A controller is a vault that has been chosen for an account to have special control over account’s
    /// balances in the enabled collaterals vaults. User calls this function in order for the vault to disable itself
    /// for the account if the conditions are met (i.e. user has repaid debt in full). If the conditions are not met,
    /// the function reverts.
    function disableController() external;

    /// @notice Checks the status of an account.
    /// @dev This function must only deliberately revert if the account status is invalid. If this function reverts due
    /// to any other reason, it may render the account unusable with possibly no way to recover funds.
    /// @param account The address of the account to be checked.
    /// @param collaterals The array of enabled collateral addresses to be considered for the account status check.
    /// @return magicValue Must return the bytes4 magic value 0xb168c58f (which is a selector of this function) when
    /// account status is valid, or revert otherwise.
    function checkAccountStatus(
        address account,
        address[] calldata collaterals
    ) external view returns (bytes4 magicValue);

    /// @notice Checks the status of the vault.
    /// @dev This function must only deliberately revert if the vault status is invalid. If this function reverts due to
    /// any other reason, it may render some accounts unusable with possibly no way to recover funds.
    /// @return magicValue Must return the bytes4 magic value 0x4b3d1223 (which is a selector of this function) when
    /// account status is valid, or revert otherwise.
    function checkVaultStatus() external returns (bytes4 magicValue);
}

File 10 of 15 : IPermit2.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity >=0.8.0;

/// @title IPermit2
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice A minimal interface of the Uniswap's Permit2 contract
interface IPermit2 {
    /// @notice Transfer tokens between two accounts
    /// @param from The account to send the tokens from
    /// @param to The account to send the tokens to
    /// @param amount Amount of tokens to send
    /// @param token Address of the token contract
    function transferFrom(address from, address to, uint160 amount, address token) external;
}

File 11 of 15 : Errors.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.0;

/// @title Errors
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Contract implementing EVault's custom errors
contract Errors {
    error E_Initialized();
    error E_ProxyMetadata();
    error E_SelfTransfer();
    error E_InsufficientAllowance();
    error E_InsufficientCash();
    error E_InsufficientAssets();
    error E_InsufficientBalance();
    error E_InsufficientDebt();
    error E_FlashLoanNotRepaid();
    error E_Reentrancy();
    error E_OperationDisabled();
    error E_OutstandingDebt();
    error E_AmountTooLargeToEncode();
    error E_DebtAmountTooLargeToEncode();
    error E_RepayTooMuch();
    error E_TransientState();
    error E_SelfLiquidation();
    error E_ControllerDisabled();
    error E_CollateralDisabled();
    error E_ViolatorLiquidityDeferred();
    error E_LiquidationCoolOff();
    error E_ExcessiveRepayAmount();
    error E_MinYield();
    error E_BadAddress();
    error E_ZeroAssets();
    error E_ZeroShares();
    error E_Unauthorized();
    error E_CheckUnauthorized();
    error E_NotSupported();
    error E_EmptyError();
    error E_BadBorrowCap();
    error E_BadSupplyCap();
    error E_BadCollateral();
    error E_AccountLiquidity();
    error E_NoLiability();
    error E_NotController();
    error E_BadFee();
    error E_SupplyCapExceeded();
    error E_BorrowCapExceeded();
    error E_InvalidLTVAsset();
    error E_NoPriceOracle();
    error E_ConfigAmountTooLargeToEncode();
    error E_BadAssetReceiver();
    error E_BadSharesOwner();
    error E_BadSharesReceiver();
    error E_BadMaxLiquidationDiscount();
    error E_LTVBorrow();
    error E_LTVLiquidation();
    error E_NotHookTarget();
}

File 12 of 15 : BaseHandler.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.0;

import {ISwapper} from "../ISwapper.sol";
import {IEVault, IERC20} from "evk/EVault/IEVault.sol";
import {RevertBytes} from "evk/EVault/shared/lib/RevertBytes.sol";

/// @title BaseHandler
/// @custom:security-contact [email protected]
/// @author Euler Labs (https://www.eulerlabs.com/)
/// @notice Base contract for swap handlers - contracts interfacing with swap providers
abstract contract BaseHandler is ISwapper {
    // exact input swaps - unknown amount of tokens bought for exact amount of tokens sold
    uint256 internal constant MODE_EXACT_IN = 0;
    // exact output swaps - exact amount of tokens bought for unknown amount of tokens sold
    uint256 internal constant MODE_EXACT_OUT = 1;
    // target debt swap and repay - the amount requested is the debt amount the account should have after swap and repay
    uint256 internal constant MODE_TARGET_DEBT = 2;
    // swap modes delimiter
    uint256 internal constant MODE_MAX_VALUE = 3;

    error Swapper_UnsupportedMode();
    error Swapper_TargetDebt();
    error Swapper_SwapError(address swapProvider, bytes rawError);

    function resolveParams(SwapParams memory params) internal view returns (uint256 amountOut, address receiver) {
        amountOut = params.amountOut;
        receiver = params.receiver;

        if (params.mode == MODE_EXACT_IN) return (amountOut, receiver);

        uint256 balanceOut = IERC20(params.tokenOut).balanceOf(address(this));

        // for combined exact output swaps, which accumulate the output in the swapper, check how much is already
        // available
        if (params.mode == MODE_EXACT_OUT && params.receiver == address(this)) {
            unchecked {
                amountOut = balanceOut >= amountOut ? 0 : amountOut - balanceOut;
            }

            return (amountOut, receiver);
        }

        if (params.mode == MODE_TARGET_DEBT) {
            uint256 debt = IEVault(params.receiver).debtOf(params.account);

            // amountOut is the target debt
            if (amountOut > debt) revert Swapper_TargetDebt();

            unchecked {
                // reuse params.amountOut to hold repay
                amountOut = params.amountOut = debt - amountOut;

                // check if balance is already sufficient to repay
                amountOut = balanceOut >= amountOut ? 0 : amountOut - balanceOut;
            }

            // collect output in the swapper for repay
            receiver = address(this);
        }
    }

    function setMaxAllowance(address token, address spender) internal {
        safeApproveWithRetry(token, spender, type(uint256).max);
    }

    function trySafeApprove(address token, address to, uint256 value) internal returns (bool, bytes memory) {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value));
        return (success && (data.length == 0 || abi.decode(data, (bool))), data);
    }

    function safeApproveWithRetry(address token, address to, uint256 value) internal {
        (bool success, bytes memory data) = trySafeApprove(token, to, value);

        // some tokens, like USDT, require the allowance to be set to 0 first
        if (!success) {
            (success,) = trySafeApprove(token, to, 0);
            if (success) {
                (success,) = trySafeApprove(token, to, value);
            }
        }

        if (!success) RevertBytes.revertBytes(data);
    }
}

File 13 of 15 : ISwapRouterV2.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.6.2;

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

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

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

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

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

File 14 of 15 : ISwapRouterV3.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.5;
pragma abicoder v2;

import "./IUniswapV3SwapCallback.sol";

/// @title Router token swapping functionality
/// @notice Functions for swapping tokens via Uniswap V3
interface ISwapRouterV3 is IUniswapV3SwapCallback {
    struct ExactInputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);

    struct ExactInputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountIn;
        uint256 amountOutMinimum;
    }

    /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path
    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata
    /// @return amountOut The amount of the received token
    function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut);

    struct ExactOutputSingleParams {
        address tokenIn;
        address tokenOut;
        uint24 fee;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
        uint160 sqrtPriceLimitX96;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of another token
    /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn);

    struct ExactOutputParams {
        bytes path;
        address recipient;
        uint256 deadline;
        uint256 amountOut;
        uint256 amountInMaximum;
    }

    /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed)
    /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata
    /// @return amountIn The amount of the input token
    function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn);
}

File 15 of 15 : IUniswapV3SwapCallback.sol
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;

/// @title Callback for IUniswapV3PoolActions#swap
/// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface
interface IUniswapV3SwapCallback {
    /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap.
    /// @dev In the implementation you must pay the pool tokens owed for the swap.
    /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory.
    /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped.
    /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token0 to the pool.
    /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by
    /// the end of the swap. If positive, the callback must send that amount of token1 to the pool.
    /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call
    function uniswapV3SwapCallback(int256 amount0Delta, int256 amount1Delta, bytes calldata data) external;
}

Settings
{
  "remappings": [
    "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
    "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "ethereum-vault-connector/=lib/ethereum-vault-connector/src/",
    "evc/=lib/ethereum-vault-connector/src/",
    "evk/=lib/euler-vault-kit/src/",
    "evk-test/=lib/euler-vault-kit/test/",
    "euler-price-oracle/=lib/euler-price-oracle/src/",
    "euler-price-oracle-test/=lib/euler-price-oracle/test/",
    "fee-flow/=lib/fee-flow/src/",
    "reward-streams/=lib/reward-streams/src/",
    "lib/euler-price-oracle:@openzeppelin/contracts/=lib/euler-price-oracle/lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "euler-earn/=lib/euler-earn/src/",
    "@openzeppelin-upgradeable/=lib/euler-earn/lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
    "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
    "@pendle/core-v2/=lib/euler-price-oracle/lib/pendle-core-v2-public/contracts/",
    "@pyth/=lib/euler-price-oracle/lib/pyth-sdk-solidity/",
    "@redstone/evm-connector/=lib/euler-price-oracle/lib/redstone-oracles-monorepo/packages/evm-connector/contracts/",
    "@solady/=lib/euler-price-oracle/lib/solady/src/",
    "@uniswap/v3-core/=lib/euler-price-oracle/lib/v3-core/",
    "@uniswap/v3-periphery/=lib/euler-price-oracle/lib/v3-periphery/",
    "ERC4626/=lib/euler-earn/lib/properties/lib/ERC4626/contracts/",
    "crytic-properties/=lib/euler-earn/lib/properties/contracts/",
    "ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "euler-vault-kit/=lib/euler-vault-kit/src/",
    "forge-gas-snapshot/=lib/euler-vault-kit/lib/permit2/lib/forge-gas-snapshot/src/",
    "forge-std/=lib/forge-std/src/",
    "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
    "openzeppelin/=lib/ethereum-vault-connector/lib/openzeppelin-contracts/contracts/",
    "pendle-core-v2-public/=lib/euler-price-oracle/lib/pendle-core-v2-public/contracts/",
    "permit2/=lib/euler-vault-kit/lib/permit2/",
    "properties/=lib/euler-earn/lib/properties/contracts/",
    "pyth-sdk-solidity/=lib/euler-price-oracle/lib/pyth-sdk-solidity/",
    "redstone-oracles-monorepo/=lib/euler-price-oracle/lib/",
    "solady/=lib/euler-price-oracle/lib/solady/src/",
    "solmate/=lib/fee-flow/lib/solmate/src/",
    "v3-core/=lib/euler-price-oracle/lib/v3-core/contracts/",
    "v3-periphery/=lib/euler-price-oracle/lib/v3-periphery/contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 20000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"uniswapRouterV2","type":"address"},{"internalType":"address","name":"uniswapRouterV3","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"E_EmptyError","type":"error"},{"inputs":[],"name":"Swapper_Reentrancy","type":"error"},{"inputs":[{"internalType":"address","name":"swapProvider","type":"address"},{"internalType":"bytes","name":"rawError","type":"bytes"}],"name":"Swapper_SwapError","type":"error"},{"inputs":[],"name":"Swapper_TargetDebt","type":"error"},{"inputs":[],"name":"Swapper_UnknownHandler","type":"error"},{"inputs":[],"name":"Swapper_UnknownMode","type":"error"},{"inputs":[],"name":"Swapper_UnsupportedMode","type":"error"},{"inputs":[],"name":"UniswapV2Handler_InvalidPath","type":"error"},{"inputs":[],"name":"UniswapV3Handler_InvalidPath","type":"error"},{"inputs":[],"name":"HANDLER_GENERIC","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HANDLER_UNISWAP_V2","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"HANDLER_UNISWAP_V3","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"amountMin","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"calls","type":"bytes[]"}],"name":"multicall","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"repay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"repayAmount","type":"uint256"},{"internalType":"address","name":"account","type":"address"}],"name":"repayAndDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes32","name":"handler","type":"bytes32"},{"internalType":"uint256","name":"mode","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"address","name":"vaultIn","type":"address"},{"internalType":"address","name":"accountIn","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct ISwapper.SwapParams","name":"params","type":"tuple"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapRouterV2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapRouterV3","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c060405234801562000010575f80fd5b5060405162001f2138038062001f21833981016040819052620000339162000067565b6001600160a01b039182166080521660a0526200009d565b80516001600160a01b038116811462000062575f80fd5b919050565b5f806040838503121562000079575f80fd5b62000084836200004b565b915062000094602084016200004b565b90509250929050565b60805160a051611e39620000e85f395f818160cd015281816111190152818161115701526112c901525f818161014601528181610e8801528181610ec601526110170152611e395ff3fe608060405234801561000f575f80fd5b50600436106100c4575f3560e01c8063a55f08d31161007d578063d60116cb11610058578063d60116cb146101fe578063dc2c256f14610211578063f71679d014610224575f80fd5b8063a55f08d31461019d578063ac9650d8146101c4578063c4d88adf146101d7575f80fd5b806352da17a4116100ad57806352da17a41461012e578063596fa9e3146101415780637db6657d14610168575f80fd5b806310f91b0b146100c85780633bc1f1ed14610119575b5f80fd5b6100ef7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61012c6101273660046116e7565b610237565b005b61012c61013c3660046116e7565b61029f565b6100ef7f000000000000000000000000000000000000000000000000000000000000000081565b61018f7f47656e657269630000000000000000000000000000000000000000000000000081565b604051908152602001610110565b61018f7f556e69737761705632000000000000000000000000000000000000000000000081565b61012c6101d2366004611897565b61043a565b61018f7f556e69737761705633000000000000000000000000000000000000000000000081565b61012c61020c3660046116e7565b61053a565b61012c61021f366004611941565b610590565b61012c610232366004611980565b61068e565b3330148015906102815760025f540361027c576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b61028d85858585610839565b80156102985760015f555b5050505050565b3330148015906102e95760025f54036102e4576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b6102f38585610979565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa15801561035d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103819190611a72565b905061038d84826109a4565b6040517facb708150000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff85811660248301529195509086169063acb70815906044016020604051808303815f875af1158015610403573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104279190611a72565b505080156102985760015f555050505050565b3330148015906104845760025f540361047f576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b5f5b825181101561052a575f803073ffffffffffffffffffffffffffffffffffffffff168584815181106104ba576104ba611a89565b60200260200101516040516104cf9190611ad8565b5f604051808303815f865af19150503d805f8114610508576040519150601f19603f3d011682016040523d82523d5f602084013e61050d565b606091505b50915091508161052057610520816109e4565b5050600101610486565b5080156105365760015f555b5050565b3330148015906105845760025f540361057f576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b61028d85858585610a25565b3330148015906105da5760025f54036105d5576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610644573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106689190611a72565b905083811061067c5761067c858483610be7565b5080156106885760015f555b50505050565b3330148015906106d85760025f54036106d3576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b6003826020015110610716576040517f70b55f7e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81517fb89a919a8d969d000000000000000000000000000000000000000000000000000161074c5761074782610cf3565b6107e0565b81517faa91968c889e8fa9ce00000000000000000000000000000000000000000000000161077d5761074782610de6565b81517faa91968c889e8fa9cd0000000000000000000000000000000000000000000000016107ae5761074782611070565b6040517f48e355b100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208201511561082b5760028260200151036108135761081382608001518360e001518461010001518560400151610a25565b61082b82606001518360a001515f8560c00151610839565b80156105365760015f555050565b6108438484610979565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156108ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108d19190611a72565b9050828110610298576040517f6e553f650000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8381166024830152851690636e553f65906044015b6020604051808303815f875af115801561094d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109719190611a72565b505050505050565b61053682827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61131d565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83141580156109d457508183115b156109dd578192505b5090919050565b8051156109f357805181602001fd5b6040517f2082e20000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a2f8484610979565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610a99573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610abd9190611a72565b9050610ac983826109a4565b6040517facb708150000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff84811660248301529194509085169063acb70815906044016020604051808303815f875af1158015610b3f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b639190611a72565b925082811115610298576040517f6e553f650000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152851690636e553f6590604401610931565b60405173ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390525f918291861690606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905251610c999190611ad8565b5f604051808303815f865af19150503d805f8114610cd2576040519150601f19603f3d011682016040523d82523d5f602084013e610cd7565b606091505b5091509150610ce68282611364565b61029857610298816109e4565b5f80826101200151806020019051810190610d0e9190611af3565b915091506002836020015103610d2a57610d278361139e565b50505b610d38836060015183610979565b5f808373ffffffffffffffffffffffffffffffffffffffff1683604051610d5f9190611ad8565b5f604051808303815f865af19150503d805f8114610d98576040519150601f19603f3d011682016040523d82523d5f602084013e610d9d565b606091505b5091509150816102985783816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610ddd929190611bc4565b60405180910390fd5b6020810151610e21576040517fda62918000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040816101200151511080610e475750602081610120015151610e449190611c27565b15155b15610e7e576040517f807d9b7b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610eac81606001517f0000000000000000000000000000000000000000000000000000000000000000610979565b5f80610eb78361139e565b9092509050811561106b575f807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff876101200151806020019051810190610f369190611c5f565b8642604051602401610f4c959493929190611cf4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8803dbee0000000000000000000000000000000000000000000000000000000017905251610fcd9190611ad8565b5f604051808303815f865af19150503d805f8114611006576040519150601f19603f3d011682016040523d82523d5f602084013e61100b565b606091505b509150915081610298577f0000000000000000000000000000000000000000000000000000000000000000816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610ddd929190611bc4565b505050565b60208101516110ab576040517fda62918000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602b8161012001515110806110d85750601760148261012001515103816110d4576110d4611bfa565b0615155b1561110f576040517f8f22cca200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61113d81606001517f0000000000000000000000000000000000000000000000000000000000000000610979565b5f806111488361139e565b9092509050811561106b575f807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166040518060a0016040528087610120015181526020018573ffffffffffffffffffffffffffffffffffffffff1681526020014281526020018681526020017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8152506040516024016111fe9190611d7f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff28c0498000000000000000000000000000000000000000000000000000000001790525161127f9190611ad8565b5f604051808303815f865af19150503d805f81146112b8576040519150601f19603f3d011682016040523d82523d5f602084013e6112bd565b606091505b509150915081610298577f0000000000000000000000000000000000000000000000000000000000000000816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610ddd929190611bc4565b5f8061132a8585856115a6565b91509150816113565761133e85855f6115a6565b5091508115611356576113528585856115a6565b5091505b8161029857610298816109e4565b5f828015611397575081511580611397575060208251101580156113975750818060200190518101906113979190611de4565b9392505050565b61010081015160e082015160208301516113b757915091565b60808301516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611425573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114499190611a72565b905060018460200151148015611478575060e084015173ffffffffffffffffffffffffffffffffffffffff1630145b15611497578281101561148d5780830361148f565b5f5b925050915091565b60028460200151036115a05760e084015160408086015190517fd283e75f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201525f92919091169063d283e75f90602401602060405180830381865afa15801561151b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061153f9190611a72565b90508084111561157b576040517fb245150100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9283036101008501819052928382101561159757818403611599565b5f5b9350309250505b50915091565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905291515f926060928492839289169161163f91611ad8565b5f604051808303815f865af19150503d805f8114611678576040519150601f19603f3d011682016040523d82523d5f602084013e61167d565b606091505b50915091508180156116a75750805115806116a75750808060200190518101906116a79190611de4565b97909650945050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146116d4575f80fd5b50565b80356116e2816116b3565b919050565b5f805f80608085870312156116fa575f80fd5b8435611705816116b3565b93506020850135611715816116b3565b925060408501359150606085013561172c816116b3565b939692955090935050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051610140810167ffffffffffffffff8111828210171561178857611788611737565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156117d5576117d5611737565b604052919050565b5f67ffffffffffffffff8211156117f6576117f6611737565b5060051b60200190565b5f67ffffffffffffffff82111561181957611819611737565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f82601f830112611854575f80fd5b813561186761186282611800565b61178e565b81815284602083860101111561187b575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208083850312156118a8575f80fd5b823567ffffffffffffffff808211156118bf575f80fd5b818501915085601f8301126118d2575f80fd5b81356118e0611862826117dd565b81815260059190911b830184019084810190888311156118fe575f80fd5b8585015b8381101561193457803585811115611918575f80fd5b6119268b89838a0101611845565b845250918601918601611902565b5098975050505050505050565b5f805f60608486031215611953575f80fd5b833561195e816116b3565b9250602084013591506040840135611975816116b3565b809150509250925092565b5f60208284031215611990575f80fd5b813567ffffffffffffffff808211156119a7575f80fd5b9083019061014082860312156119bb575f80fd5b6119c3611764565b82358152602083013560208201526119dd604084016116d7565b60408201526119ee606084016116d7565b60608201526119ff608084016116d7565b6080820152611a1060a084016116d7565b60a0820152611a2160c084016116d7565b60c0820152611a3260e084016116d7565b60e082015261010083810135908201526101208084013583811115611a55575f80fd5b611a6188828701611845565b918301919091525095945050505050565b5f60208284031215611a82575f80fd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5b83811015611ad0578181015183820152602001611ab8565b50505f910152565b5f8251611ae9818460208701611ab6565b9190910192915050565b5f8060408385031215611b04575f80fd5b8251611b0f816116b3565b602084015190925067ffffffffffffffff811115611b2b575f80fd5b8301601f81018513611b3b575f80fd5b8051611b4961186282611800565b818152866020838501011115611b5d575f80fd5b611b6e826020830160208601611ab6565b8093505050509250929050565b5f8151808452611b92816020860160208601611ab6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611bf26040830184611b7b565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f82611c5a577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b5f6020808385031215611c70575f80fd5b825167ffffffffffffffff811115611c86575f80fd5b8301601f81018513611c96575f80fd5b8051611ca4611862826117dd565b81815260059190911b82018301908381019087831115611cc2575f80fd5b928401925b82841015611ce9578351611cda816116b3565b82529284019290840190611cc7565b979650505050505050565b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b81811015611d5157845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101611d1f565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b602081525f825160a06020840152611d9a60c0840182611b7b565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b5f60208284031215611df4575f80fd5b81518015158114611397575f80fdfea2646970667358221220bcce0601ed6b95ba997ab63f34e3bcc4c6dd1b17173329aa82002539ba84522864736f6c634300081800330000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564

Deployed Bytecode

0x608060405234801561000f575f80fd5b50600436106100c4575f3560e01c8063a55f08d31161007d578063d60116cb11610058578063d60116cb146101fe578063dc2c256f14610211578063f71679d014610224575f80fd5b8063a55f08d31461019d578063ac9650d8146101c4578063c4d88adf146101d7575f80fd5b806352da17a4116100ad57806352da17a41461012e578063596fa9e3146101415780637db6657d14610168575f80fd5b806310f91b0b146100c85780633bc1f1ed14610119575b5f80fd5b6100ef7f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156481565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61012c6101273660046116e7565b610237565b005b61012c61013c3660046116e7565b61029f565b6100ef7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b61018f7f47656e657269630000000000000000000000000000000000000000000000000081565b604051908152602001610110565b61018f7f556e69737761705632000000000000000000000000000000000000000000000081565b61012c6101d2366004611897565b61043a565b61018f7f556e69737761705633000000000000000000000000000000000000000000000081565b61012c61020c3660046116e7565b61053a565b61012c61021f366004611941565b610590565b61012c610232366004611980565b61068e565b3330148015906102815760025f540361027c576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b61028d85858585610839565b80156102985760015f555b5050505050565b3330148015906102e95760025f54036102e4576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b6102f38585610979565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa15801561035d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103819190611a72565b905061038d84826109a4565b6040517facb708150000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff85811660248301529195509086169063acb70815906044016020604051808303815f875af1158015610403573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104279190611a72565b505080156102985760015f555050505050565b3330148015906104845760025f540361047f576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b5f5b825181101561052a575f803073ffffffffffffffffffffffffffffffffffffffff168584815181106104ba576104ba611a89565b60200260200101516040516104cf9190611ad8565b5f604051808303815f865af19150503d805f8114610508576040519150601f19603f3d011682016040523d82523d5f602084013e61050d565b606091505b50915091508161052057610520816109e4565b5050600101610486565b5080156105365760015f555b5050565b3330148015906105845760025f540361057f576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b61028d85858585610a25565b3330148015906105da5760025f54036105d5576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610644573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106689190611a72565b905083811061067c5761067c858483610be7565b5080156106885760015f555b50505050565b3330148015906106d85760025f54036106d3576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025f555b6003826020015110610716576040517f70b55f7e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81517fb89a919a8d969d000000000000000000000000000000000000000000000000000161074c5761074782610cf3565b6107e0565b81517faa91968c889e8fa9ce00000000000000000000000000000000000000000000000161077d5761074782610de6565b81517faa91968c889e8fa9cd0000000000000000000000000000000000000000000000016107ae5761074782611070565b6040517f48e355b100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208201511561082b5760028260200151036108135761081382608001518360e001518461010001518560400151610a25565b61082b82606001518360a001515f8560c00151610839565b80156105365760015f555050565b6108438484610979565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156108ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108d19190611a72565b9050828110610298576040517f6e553f650000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8381166024830152851690636e553f65906044015b6020604051808303815f875af115801561094d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109719190611a72565b505050505050565b61053682827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61131d565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83141580156109d457508183115b156109dd578192505b5090919050565b8051156109f357805181602001fd5b6040517f2082e20000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a2f8484610979565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610a99573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610abd9190611a72565b9050610ac983826109a4565b6040517facb708150000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff84811660248301529194509085169063acb70815906044016020604051808303815f875af1158015610b3f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b639190611a72565b925082811115610298576040517f6e553f650000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152851690636e553f6590604401610931565b60405173ffffffffffffffffffffffffffffffffffffffff8381166024830152604482018390525f918291861690606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905251610c999190611ad8565b5f604051808303815f865af19150503d805f8114610cd2576040519150601f19603f3d011682016040523d82523d5f602084013e610cd7565b606091505b5091509150610ce68282611364565b61029857610298816109e4565b5f80826101200151806020019051810190610d0e9190611af3565b915091506002836020015103610d2a57610d278361139e565b50505b610d38836060015183610979565b5f808373ffffffffffffffffffffffffffffffffffffffff1683604051610d5f9190611ad8565b5f604051808303815f865af19150503d805f8114610d98576040519150601f19603f3d011682016040523d82523d5f602084013e610d9d565b606091505b5091509150816102985783816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610ddd929190611bc4565b60405180910390fd5b6020810151610e21576040517fda62918000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040816101200151511080610e475750602081610120015151610e449190611c27565b15155b15610e7e576040517f807d9b7b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610eac81606001517f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d610979565b5f80610eb78361139e565b9092509050811561106b575f807f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff16847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff876101200151806020019051810190610f369190611c5f565b8642604051602401610f4c959493929190611cf4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8803dbee0000000000000000000000000000000000000000000000000000000017905251610fcd9190611ad8565b5f604051808303815f865af19150503d805f8114611006576040519150601f19603f3d011682016040523d82523d5f602084013e61100b565b606091505b509150915081610298577f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610ddd929190611bc4565b505050565b60208101516110ab576040517fda62918000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602b8161012001515110806110d85750601760148261012001515103816110d4576110d4611bfa565b0615155b1561110f576040517f8f22cca200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61113d81606001517f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564610979565b5f806111488361139e565b9092509050811561106b575f807f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff166040518060a0016040528087610120015181526020018573ffffffffffffffffffffffffffffffffffffffff1681526020014281526020018681526020017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8152506040516024016111fe9190611d7f565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff28c0498000000000000000000000000000000000000000000000000000000001790525161127f9190611ad8565b5f604051808303815f865af19150503d805f81146112b8576040519150601f19603f3d011682016040523d82523d5f602084013e6112bd565b606091505b509150915081610298577f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610ddd929190611bc4565b5f8061132a8585856115a6565b91509150816113565761133e85855f6115a6565b5091508115611356576113528585856115a6565b5091505b8161029857610298816109e4565b5f828015611397575081511580611397575060208251101580156113975750818060200190518101906113979190611de4565b9392505050565b61010081015160e082015160208301516113b757915091565b60808301516040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f9173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa158015611425573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114499190611a72565b905060018460200151148015611478575060e084015173ffffffffffffffffffffffffffffffffffffffff1630145b15611497578281101561148d5780830361148f565b5f5b925050915091565b60028460200151036115a05760e084015160408086015190517fd283e75f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201525f92919091169063d283e75f90602401602060405180830381865afa15801561151b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061153f9190611a72565b90508084111561157b576040517fb245150100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9283036101008501819052928382101561159757818403611599565b5f5b9350309250505b50915091565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905291515f926060928492839289169161163f91611ad8565b5f604051808303815f865af19150503d805f8114611678576040519150601f19603f3d011682016040523d82523d5f602084013e61167d565b606091505b50915091508180156116a75750805115806116a75750808060200190518101906116a79190611de4565b97909650945050505050565b73ffffffffffffffffffffffffffffffffffffffff811681146116d4575f80fd5b50565b80356116e2816116b3565b919050565b5f805f80608085870312156116fa575f80fd5b8435611705816116b3565b93506020850135611715816116b3565b925060408501359150606085013561172c816116b3565b939692955090935050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051610140810167ffffffffffffffff8111828210171561178857611788611737565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156117d5576117d5611737565b604052919050565b5f67ffffffffffffffff8211156117f6576117f6611737565b5060051b60200190565b5f67ffffffffffffffff82111561181957611819611737565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b5f82601f830112611854575f80fd5b813561186761186282611800565b61178e565b81815284602083860101111561187b575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208083850312156118a8575f80fd5b823567ffffffffffffffff808211156118bf575f80fd5b818501915085601f8301126118d2575f80fd5b81356118e0611862826117dd565b81815260059190911b830184019084810190888311156118fe575f80fd5b8585015b8381101561193457803585811115611918575f80fd5b6119268b89838a0101611845565b845250918601918601611902565b5098975050505050505050565b5f805f60608486031215611953575f80fd5b833561195e816116b3565b9250602084013591506040840135611975816116b3565b809150509250925092565b5f60208284031215611990575f80fd5b813567ffffffffffffffff808211156119a7575f80fd5b9083019061014082860312156119bb575f80fd5b6119c3611764565b82358152602083013560208201526119dd604084016116d7565b60408201526119ee606084016116d7565b60608201526119ff608084016116d7565b6080820152611a1060a084016116d7565b60a0820152611a2160c084016116d7565b60c0820152611a3260e084016116d7565b60e082015261010083810135908201526101208084013583811115611a55575f80fd5b611a6188828701611845565b918301919091525095945050505050565b5f60208284031215611a82575f80fd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5b83811015611ad0578181015183820152602001611ab8565b50505f910152565b5f8251611ae9818460208701611ab6565b9190910192915050565b5f8060408385031215611b04575f80fd5b8251611b0f816116b3565b602084015190925067ffffffffffffffff811115611b2b575f80fd5b8301601f81018513611b3b575f80fd5b8051611b4961186282611800565b818152866020838501011115611b5d575f80fd5b611b6e826020830160208601611ab6565b8093505050509250929050565b5f8151808452611b92816020860160208601611ab6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201525f611bf26040830184611b7b565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f82611c5a577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500690565b5f6020808385031215611c70575f80fd5b825167ffffffffffffffff811115611c86575f80fd5b8301601f81018513611c96575f80fd5b8051611ca4611862826117dd565b81815260059190911b82018301908381019087831115611cc2575f80fd5b928401925b82841015611ce9578351611cda816116b3565b82529284019290840190611cc7565b979650505050505050565b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b81811015611d5157845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101611d1f565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b602081525f825160a06020840152611d9a60c0840182611b7b565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b5f60208284031215611df4575f80fd5b81518015158114611397575f80fdfea2646970667358221220bcce0601ed6b95ba997ab63f34e3bcc4c6dd1b17173329aa82002539ba84522864736f6c63430008180033

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

0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564

-----Decoded View---------------
Arg [0] : uniswapRouterV2 (address): 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
Arg [1] : uniswapRouterV3 (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d
Arg [1] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.