Overview
ETH Balance
ETH Value
$0.00Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28255686 | 14 hrs ago | 0 ETH | ||||
| 28228789 | 32 hrs ago | 0 ETH | ||||
| 28228789 | 32 hrs ago | 0 ETH | ||||
| 28228789 | 32 hrs ago | 0 ETH | ||||
| 28228789 | 32 hrs ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Swapper
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity Standard Json-Input format)
// 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;
}
}// 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);
}// 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))));
}
}// 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(); } }
// 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; }
// 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 || (result.length == 0 && target.code.length == 0)) revert Swapper_SwapError(target, result);
}
}// 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 || (result.length == 0 && uniswapRouterV2.code.length == 0)) {
revert Swapper_SwapError(uniswapRouterV2, result);
}
}
}
}// 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 || (result.length == 0 && uniswapRouterV3.code.length == 0)) {
revert Swapper_SwapError(uniswapRouterV3, result);
}
}
}
}// 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); }
// 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; }
// 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(); }
// 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);
}
}// 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;
}// 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);
}// 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;
}{
"remappings": [
"lib/euler-price-oracle:@openzeppelin/contracts/=lib/euler-price-oracle/lib/openzeppelin-contracts/contracts/",
"lib/euler-earn:@openzeppelin/=lib/euler-earn/lib/openzeppelin-contracts/",
"lib/euler-earn:@openzeppelin-upgradeable/=lib/euler-earn/lib/openzeppelin-contracts-upgradeable/contracts/",
"lib/euler-earn:ethereum-vault-connector/=lib/euler-earn/lib/ethereum-vault-connector/src/",
"lib/layerzero-devtools/packages/oft-evm/contracts:@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts/contracts/",
"lib/layerzero-devtools/packages/oft-evm-upgradeable/contracts:@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"lib/layerzero-devtools/packages/oapp-evm-upgradeable/contracts:@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@layerzerolabs/oft-evm/=lib/layerzero-devtools/packages/oft-evm/",
"@layerzerolabs/oapp-evm/=lib/layerzero-devtools/packages/oapp-evm/",
"@layerzerolabs/oapp-evm-upgradeable/=lib/layerzero-devtools/packages/oapp-evm-upgradeable/",
"@layerzerolabs/lz-evm-protocol-v2/=lib/layerzero-v2/packages/layerzero-v2/evm/protocol/",
"@layerzerolabs/lz-evm-messagelib-v2/=lib/layerzero-v2/packages/layerzero-v2/evm/messagelib/",
"@layerzerolabs/lz-evm-oapp-v2/=lib/layerzero-v2/packages/layerzero-v2/evm/oapp/",
"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/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"euler-earn/=lib/euler-earn/src/",
"layerzero/oft-evm/=lib/layerzero-devtools/packages/oft-evm/contracts/",
"layerzero/oft-evm-upgradeable/=lib/layerzero-devtools/packages/oft-evm-upgradeable/contracts/",
"solidity-bytes-utils/=lib/solidity-bytes-utils/",
"@openzeppelin-upgradeable/=lib/euler-earn/lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/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/ethereum-vault-connector/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"euler-vault-kit/=lib/euler-vault-kit/",
"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-upgradeable/lib/halmos-cheatcodes/src/",
"layerzero-devtools/=lib/layerzero-devtools/packages/toolbox-foundry/src/",
"layerzero-v2/=lib/layerzero-v2/",
"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": 10000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "london",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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"}]Contract Creation Code
60c06040523480156200001157600080fd5b5060405162001fdb38038062001fdb833981016040819052620000349162000069565b6001600160a01b039182166080521660a052620000a1565b80516001600160a01b03811681146200006457600080fd5b919050565b600080604083850312156200007d57600080fd5b62000088836200004c565b915062000098602084016200004c565b90509250929050565b60805160a051611edd620000fe6000396000818160d30152818161119a015281816111da01528181611354015261137e01526000818161014c01528181610ed501528181610f150152818161106e01526110980152611edd6000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063a55f08d311610081578063d60116cb1161005b578063d60116cb14610204578063dc2c256f14610217578063f71679d01461022a57600080fd5b8063a55f08d3146101a3578063ac9650d8146101ca578063c4d88adf146101dd57600080fd5b806352da17a4116100b257806352da17a414610134578063596fa9e3146101475780637db6657d1461016e57600080fd5b806310f91b0b146100ce5780633bc1f1ed1461011f575b600080fd5b6100f57f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61013261012d3660046117ad565b61023d565b005b6101326101423660046117ad565b6102a8565b6100f57f000000000000000000000000000000000000000000000000000000000000000081565b6101957f47656e657269630000000000000000000000000000000000000000000000000081565b604051908152602001610116565b6101957f556e69737761705632000000000000000000000000000000000000000000000081565b6101326101d836600461192c565b61044c565b6101957f556e69737761705633000000000000000000000000000000000000000000000081565b6101326102123660046117ad565b610555565b6101326102253660046119dd565b6105ad565b610132610238366004611a1f565b6106b1565b33301480159061028957600260005403610283576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b61029585858585610860565b80156102a15760016000555b5050505050565b3330148015906102f4576002600054036102ee576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b6102fe85856109a6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa15801561036b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038f9190611b16565b905061039b84826109d1565b6040517facb708150000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff85811660248301529195509086169063acb70815906044016020604051808303816000875af1158015610414573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104389190611b16565b505080156102a15760016000555050505050565b33301480159061049857600260005403610492576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b60005b8251811015610544576000803073ffffffffffffffffffffffffffffffffffffffff168584815181106104d0576104d0611b2f565b60200260200101516040516104e59190611b82565b6000604051808303816000865af19150503d8060008114610522576040519150601f19603f3d011682016040523d82523d6000602084013e610527565b606091505b50915091508161053a5761053a81610a12565b505060010161049b565b5080156105515760016000555b5050565b3330148015906105a15760026000540361059b576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b61029585858585610a53565b3330148015906105f9576002600054036105f3576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068a9190611b16565b905083811061069e5761069e858483610c1b565b5080156106ab5760016000555b50505050565b3330148015906106fd576002600054036106f7576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b600382602001511061073b576040517f70b55f7e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81517fb89a919a8d969d00000000000000000000000000000000000000000000000000016107715761076c82610d0e565b610805565b81517faa91968c889e8fa9ce0000000000000000000000000000000000000000000000016107a25761076c82610e33565b81517faa91968c889e8fa9cd0000000000000000000000000000000000000000000000016107d35761076c826110f1565b6040517f48e355b100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020820151156108515760028260200151036108385761083882608001518360e001518461010001518560400151610a53565b61085182606001518360a0015160008560c00151610860565b80156105515760016000555050565b61086a84846109a6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156108d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fb9190611b16565b90508281106102a1576040517f6e553f650000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8381166024830152851690636e553f65906044015b6020604051808303816000875af115801561097a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099e9190611b16565b505050505050565b61055182827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6113d2565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8314158015610a0257508183115b15610a0b578192505b5090919050565b805115610a2157805181602001fd5b6040517f2082e20000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a5d84846109a6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190611b16565b9050610afa83826109d1565b6040517facb708150000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff84811660248301529194509085169063acb70815906044016020604051808303816000875af1158015610b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b979190611b16565b9250828111156102a1576040517f6e553f650000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152851690636e553f659060440161095b565b60405173ffffffffffffffffffffffffffffffffffffffff838116602483015260448201839052600091829186169060640160408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905251610cb09190611b82565b6000604051808303816000865af19150503d8060008114610ced576040519150601f19603f3d011682016040523d82523d6000602084013e610cf2565b606091505b5091509150610d01828261141b565b6102a1576102a181610a12565b600080826101200151806020019051810190610d2a9190611b9e565b915091506002836020015103610d4657610d4383611456565b50505b610d548360600151836109a6565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d7c9190611b82565b6000604051808303816000865af19150503d8060008114610db9576040519150601f19603f3d011682016040523d82523d6000602084013e610dbe565b606091505b5091509150811580610def57508051158015610def575073ffffffffffffffffffffffffffffffffffffffff84163b155b156102a15783816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610e2a929190611c57565b60405180910390fd5b6020810151610e6e576040517fda62918000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040816101200151511080610e945750602081610120015151610e919190611cbd565b15155b15610ecb576040517f807d9b7b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ef981606001517f00000000000000000000000000000000000000000000000000000000000000006109a6565b600080610f0583611456565b909250905081156110ec576000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff876101200151806020019051810190610f859190611cf8565b8642604051602401610f9b959493929190611d92565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8803dbee0000000000000000000000000000000000000000000000000000000017905251610ffe9190611b82565b6000604051808303816000865af19150503d806000811461103b576040519150601f19603f3d011682016040523d82523d6000602084013e611040565b606091505b509150915081158061109157508051158015611091575073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163b155b156102a1577f0000000000000000000000000000000000000000000000000000000000000000816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610e2a929190611c57565b505050565b602081015161112c576040517fda62918000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602b81610120015151108061115957506017601482610120015151038161115557611155611c8e565b0615155b15611190576040517f8f22cca200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111be81606001517f00000000000000000000000000000000000000000000000000000000000000006109a6565b6000806111ca83611456565b909250905081156110ec576000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166040518060a0016040528087610120015181526020018573ffffffffffffffffffffffffffffffffffffffff1681526020014281526020018681526020017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8152506040516024016112819190611e1f565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff28c049800000000000000000000000000000000000000000000000000000000179052516112e49190611b82565b6000604051808303816000865af19150503d8060008114611321576040519150601f19603f3d011682016040523d82523d6000602084013e611326565b606091505b509150915081158061137757508051158015611377575073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163b155b156102a1577f0000000000000000000000000000000000000000000000000000000000000000816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610e2a929190611c57565b6000806113e0858585611666565b915091508161140d576113f585856000611666565b509150811561140d57611409858585611666565b5091505b816102a1576102a181610a12565b600082801561144f57508151158061144f5750602082511015801561144f57508180602001905181019061144f9190611e85565b9392505050565b61010081015160e0820151602083015161146f57915091565b60808301516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156114e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115049190611b16565b905060018460200151148015611533575060e084015173ffffffffffffffffffffffffffffffffffffffff1630145b1561155357828110156115485780830361154b565b60005b925050915091565b60028460200151036116605760e084015160408086015190517fd283e75f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600092919091169063d283e75f90602401602060405180830381865afa1580156115da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fe9190611b16565b90508084111561163a576040517fb245150100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9283036101008501819052928382101561165657818403611659565b60005b9350309250505b50915091565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905291516000926060928492839289169161170091611b82565b6000604051808303816000865af19150503d806000811461173d576040519150601f19603f3d011682016040523d82523d6000602084013e611742565b606091505b509150915081801561176c57508051158061176c57508080602001905181019061176c9190611e85565b97909650945050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461179a57600080fd5b50565b80356117a881611778565b919050565b600080600080608085870312156117c357600080fd5b84356117ce81611778565b935060208501356117de81611778565b92506040850135915060608501356117f581611778565b939692955090935050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561185357611853611800565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561188257611882611800565b604052919050565b600067ffffffffffffffff8211156118a4576118a4611800565b5060051b60200190565b600067ffffffffffffffff8211156118c8576118c8611800565b50601f01601f191660200190565b600082601f8301126118e757600080fd5b81356118fa6118f5826118ae565b611859565b81815284602083860101111561190f57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602080838503121561193f57600080fd5b823567ffffffffffffffff8082111561195757600080fd5b818501915085601f83011261196b57600080fd5b81356119796118f58261188a565b81815260059190911b8301840190848101908883111561199857600080fd5b8585015b838110156119d0578035858111156119b45760008081fd5b6119c28b89838a01016118d6565b84525091860191860161199c565b5098975050505050505050565b6000806000606084860312156119f257600080fd5b83356119fd81611778565b9250602084013591506040840135611a1481611778565b809150509250925092565b600060208284031215611a3157600080fd5b813567ffffffffffffffff80821115611a4957600080fd5b908301906101408286031215611a5e57600080fd5b611a6661182f565b8235815260208301356020820152611a806040840161179d565b6040820152611a916060840161179d565b6060820152611aa26080840161179d565b6080820152611ab360a0840161179d565b60a0820152611ac460c0840161179d565b60c0820152611ad560e0840161179d565b60e082015261010083810135908201526101208084013583811115611af957600080fd5b611b05888287016118d6565b918301919091525095945050505050565b600060208284031215611b2857600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b83811015611b79578181015183820152602001611b61565b50506000910152565b60008251611b94818460208701611b5e565b9190910192915050565b60008060408385031215611bb157600080fd5b8251611bbc81611778565b602084015190925067ffffffffffffffff811115611bd957600080fd5b8301601f81018513611bea57600080fd5b8051611bf86118f5826118ae565b818152866020838501011115611c0d57600080fd5b611c1e826020830160208601611b5e565b8093505050509250929050565b60008151808452611c43816020860160208601611b5e565b601f01601f19169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611c866040830184611c2b565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611cf3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60006020808385031215611d0b57600080fd5b825167ffffffffffffffff811115611d2257600080fd5b8301601f81018513611d3357600080fd5b8051611d416118f58261188a565b81815260059190911b82018301908381019087831115611d6057600080fd5b928401925b82841015611d87578351611d7881611778565b82529284019290840190611d65565b979650505050505050565b600060a08201878352602087602085015260a0604085015281875180845260c08601915060208901935060005b81811015611df157845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101611dbf565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b602081526000825160a06020840152611e3b60c0840182611c2b565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b600060208284031215611e9757600080fd5b8151801515811461144f57600080fdfea2646970667358221220897e21eaf6bcb14a665794639e836a64c2da3fd4b185cfb220bc8706f55a904664736f6c6343000818003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d4e44eb1374240ce5f1b871ab261cd16335b76a
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063a55f08d311610081578063d60116cb1161005b578063d60116cb14610204578063dc2c256f14610217578063f71679d01461022a57600080fd5b8063a55f08d3146101a3578063ac9650d8146101ca578063c4d88adf146101dd57600080fd5b806352da17a4116100b257806352da17a414610134578063596fa9e3146101475780637db6657d1461016e57600080fd5b806310f91b0b146100ce5780633bc1f1ed1461011f575b600080fd5b6100f57f0000000000000000000000003d4e44eb1374240ce5f1b871ab261cd16335b76a81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61013261012d3660046117ad565b61023d565b005b6101326101423660046117ad565b6102a8565b6100f57f000000000000000000000000000000000000000000000000000000000000000081565b6101957f47656e657269630000000000000000000000000000000000000000000000000081565b604051908152602001610116565b6101957f556e69737761705632000000000000000000000000000000000000000000000081565b6101326101d836600461192c565b61044c565b6101957f556e69737761705633000000000000000000000000000000000000000000000081565b6101326102123660046117ad565b610555565b6101326102253660046119dd565b6105ad565b610132610238366004611a1f565b6106b1565b33301480159061028957600260005403610283576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b61029585858585610860565b80156102a15760016000555b5050505050565b3330148015906102f4576002600054036102ee576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b6102fe85856109a6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8716906370a0823190602401602060405180830381865afa15801561036b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038f9190611b16565b905061039b84826109d1565b6040517facb708150000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff85811660248301529195509086169063acb70815906044016020604051808303816000875af1158015610414573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104389190611b16565b505080156102a15760016000555050505050565b33301480159061049857600260005403610492576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b60005b8251811015610544576000803073ffffffffffffffffffffffffffffffffffffffff168584815181106104d0576104d0611b2f565b60200260200101516040516104e59190611b82565b6000604051808303816000865af19150503d8060008114610522576040519150601f19603f3d011682016040523d82523d6000602084013e610527565b606091505b50915091508161053a5761053a81610a12565b505060010161049b565b5080156105515760016000555b5050565b3330148015906105a15760026000540361059b576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b61029585858585610a53565b3330148015906105f9576002600054036105f3576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610666573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068a9190611b16565b905083811061069e5761069e858483610c1b565b5080156106ab5760016000555b50505050565b3330148015906106fd576002600054036106f7576040517fce17255100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026000555b600382602001511061073b576040517f70b55f7e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b81517fb89a919a8d969d00000000000000000000000000000000000000000000000000016107715761076c82610d0e565b610805565b81517faa91968c889e8fa9ce0000000000000000000000000000000000000000000000016107a25761076c82610e33565b81517faa91968c889e8fa9cd0000000000000000000000000000000000000000000000016107d35761076c826110f1565b6040517f48e355b100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6020820151156108515760028260200151036108385761083882608001518360e001518461010001518560400151610a53565b61085182606001518360a0015160008560c00151610860565b80156105515760016000555050565b61086a84846109a6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa1580156108d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fb9190611b16565b90508281106102a1576040517f6e553f650000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff8381166024830152851690636e553f65906044015b6020604051808303816000875af115801561097a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061099e9190611b16565b505050505050565b61055182827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6113d2565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8314158015610a0257508183115b15610a0b578192505b5090919050565b805115610a2157805181602001fd5b6040517f2082e20000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a5d84846109a6565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015610aca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aee9190611b16565b9050610afa83826109d1565b6040517facb708150000000000000000000000000000000000000000000000000000000081526004810182905273ffffffffffffffffffffffffffffffffffffffff84811660248301529194509085169063acb70815906044016020604051808303816000875af1158015610b73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b979190611b16565b9250828111156102a1576040517f6e553f650000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600482015273ffffffffffffffffffffffffffffffffffffffff8381166024830152851690636e553f659060440161095b565b60405173ffffffffffffffffffffffffffffffffffffffff838116602483015260448201839052600091829186169060640160408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905251610cb09190611b82565b6000604051808303816000865af19150503d8060008114610ced576040519150601f19603f3d011682016040523d82523d6000602084013e610cf2565b606091505b5091509150610d01828261141b565b6102a1576102a181610a12565b600080826101200151806020019051810190610d2a9190611b9e565b915091506002836020015103610d4657610d4383611456565b50505b610d548360600151836109a6565b6000808373ffffffffffffffffffffffffffffffffffffffff1683604051610d7c9190611b82565b6000604051808303816000865af19150503d8060008114610db9576040519150601f19603f3d011682016040523d82523d6000602084013e610dbe565b606091505b5091509150811580610def57508051158015610def575073ffffffffffffffffffffffffffffffffffffffff84163b155b156102a15783816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610e2a929190611c57565b60405180910390fd5b6020810151610e6e576040517fda62918000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040816101200151511080610e945750602081610120015151610e919190611cbd565b15155b15610ecb576040517f807d9b7b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ef981606001517f00000000000000000000000000000000000000000000000000000000000000006109a6565b600080610f0583611456565b909250905081156110ec576000807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff876101200151806020019051810190610f859190611cf8565b8642604051602401610f9b959493929190611d92565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f8803dbee0000000000000000000000000000000000000000000000000000000017905251610ffe9190611b82565b6000604051808303816000865af19150503d806000811461103b576040519150601f19603f3d011682016040523d82523d6000602084013e611040565b606091505b509150915081158061109157508051158015611091575073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163b155b156102a1577f0000000000000000000000000000000000000000000000000000000000000000816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610e2a929190611c57565b505050565b602081015161112c576040517fda62918000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b602b81610120015151108061115957506017601482610120015151038161115557611155611c8e565b0615155b15611190576040517f8f22cca200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111be81606001517f0000000000000000000000003d4e44eb1374240ce5f1b871ab261cd16335b76a6109a6565b6000806111ca83611456565b909250905081156110ec576000807f0000000000000000000000003d4e44eb1374240ce5f1b871ab261cd16335b76a73ffffffffffffffffffffffffffffffffffffffff166040518060a0016040528087610120015181526020018573ffffffffffffffffffffffffffffffffffffffff1681526020014281526020018681526020017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8152506040516024016112819190611e1f565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff28c049800000000000000000000000000000000000000000000000000000000179052516112e49190611b82565b6000604051808303816000865af19150503d8060008114611321576040519150601f19603f3d011682016040523d82523d6000602084013e611326565b606091505b509150915081158061137757508051158015611377575073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000003d4e44eb1374240ce5f1b871ab261cd16335b76a163b155b156102a1577f0000000000000000000000003d4e44eb1374240ce5f1b871ab261cd16335b76a816040517f436fa211000000000000000000000000000000000000000000000000000000008152600401610e2a929190611c57565b6000806113e0858585611666565b915091508161140d576113f585856000611666565b509150811561140d57611409858585611666565b5091505b816102a1576102a181610a12565b600082801561144f57508151158061144f5750602082511015801561144f57508180602001905181019061144f9190611e85565b9392505050565b61010081015160e0820151602083015161146f57915091565b60808301516040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009173ffffffffffffffffffffffffffffffffffffffff16906370a0823190602401602060405180830381865afa1580156114e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115049190611b16565b905060018460200151148015611533575060e084015173ffffffffffffffffffffffffffffffffffffffff1630145b1561155357828110156115485780830361154b565b60005b925050915091565b60028460200151036116605760e084015160408086015190517fd283e75f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9182166004820152600092919091169063d283e75f90602401602060405180830381865afa1580156115da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fe9190611b16565b90508084111561163a576040517fb245150100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b9283036101008501819052928382101561165657818403611659565b60005b9350309250505b50915091565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b30000000000000000000000000000000000000000000000000000000017905291516000926060928492839289169161170091611b82565b6000604051808303816000865af19150503d806000811461173d576040519150601f19603f3d011682016040523d82523d6000602084013e611742565b606091505b509150915081801561176c57508051158061176c57508080602001905181019061176c9190611e85565b97909650945050505050565b73ffffffffffffffffffffffffffffffffffffffff8116811461179a57600080fd5b50565b80356117a881611778565b919050565b600080600080608085870312156117c357600080fd5b84356117ce81611778565b935060208501356117de81611778565b92506040850135915060608501356117f581611778565b939692955090935050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610140810167ffffffffffffffff8111828210171561185357611853611800565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561188257611882611800565b604052919050565b600067ffffffffffffffff8211156118a4576118a4611800565b5060051b60200190565b600067ffffffffffffffff8211156118c8576118c8611800565b50601f01601f191660200190565b600082601f8301126118e757600080fd5b81356118fa6118f5826118ae565b611859565b81815284602083860101111561190f57600080fd5b816020850160208301376000918101602001919091529392505050565b6000602080838503121561193f57600080fd5b823567ffffffffffffffff8082111561195757600080fd5b818501915085601f83011261196b57600080fd5b81356119796118f58261188a565b81815260059190911b8301840190848101908883111561199857600080fd5b8585015b838110156119d0578035858111156119b45760008081fd5b6119c28b89838a01016118d6565b84525091860191860161199c565b5098975050505050505050565b6000806000606084860312156119f257600080fd5b83356119fd81611778565b9250602084013591506040840135611a1481611778565b809150509250925092565b600060208284031215611a3157600080fd5b813567ffffffffffffffff80821115611a4957600080fd5b908301906101408286031215611a5e57600080fd5b611a6661182f565b8235815260208301356020820152611a806040840161179d565b6040820152611a916060840161179d565b6060820152611aa26080840161179d565b6080820152611ab360a0840161179d565b60a0820152611ac460c0840161179d565b60c0820152611ad560e0840161179d565b60e082015261010083810135908201526101208084013583811115611af957600080fd5b611b05888287016118d6565b918301919091525095945050505050565b600060208284031215611b2857600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b83811015611b79578181015183820152602001611b61565b50506000910152565b60008251611b94818460208701611b5e565b9190910192915050565b60008060408385031215611bb157600080fd5b8251611bbc81611778565b602084015190925067ffffffffffffffff811115611bd957600080fd5b8301601f81018513611bea57600080fd5b8051611bf86118f5826118ae565b818152866020838501011115611c0d57600080fd5b611c1e826020830160208601611b5e565b8093505050509250929050565b60008151808452611c43816020860160208601611b5e565b601f01601f19169290920160200192915050565b73ffffffffffffffffffffffffffffffffffffffff83168152604060208201526000611c866040830184611c2b565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082611cf3577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500690565b60006020808385031215611d0b57600080fd5b825167ffffffffffffffff811115611d2257600080fd5b8301601f81018513611d3357600080fd5b8051611d416118f58261188a565b81815260059190911b82018301908381019087831115611d6057600080fd5b928401925b82841015611d87578351611d7881611778565b82529284019290840190611d65565b979650505050505050565b600060a08201878352602087602085015260a0604085015281875180845260c08601915060208901935060005b81811015611df157845173ffffffffffffffffffffffffffffffffffffffff1683529383019391830191600101611dbf565b505073ffffffffffffffffffffffffffffffffffffffff969096166060850152505050608001529392505050565b602081526000825160a06020840152611e3b60c0840182611c2b565b905073ffffffffffffffffffffffffffffffffffffffff60208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b600060208284031215611e9757600080fd5b8151801515811461144f57600080fdfea2646970667358221220897e21eaf6bcb14a665794639e836a64c2da3fd4b185cfb220bc8706f55a904664736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000003d4e44eb1374240ce5f1b871ab261cd16335b76a
-----Decoded View---------------
Arg [0] : uniswapRouterV2 (address): 0x0000000000000000000000000000000000000000
Arg [1] : uniswapRouterV3 (address): 0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [1] : 0000000000000000000000003d4e44eb1374240ce5f1b871ab261cd16335b76a
Deployed Bytecode Sourcemap
706:4843:7:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;431:40:11;;;;;;;;190:42:15;178:55;;;160:74;;148:2;133:18;431:40:11;;;;;;;;3514:162:7;;;;;;:::i;:::-;;:::i;:::-;;2930:332;;;;;;:::i;:::-;;:::i;436:40:10:-;;;;;783:60:7;;825:18;783:60;;;;;1292:25:15;;;1280:2;1265:18;783:60:7;1146:177:15;849:65:7;;894:20;849:65;;4013:268;;;;;;:::i;:::-;;:::i;920:65::-;;965:20;920:65;;3297:182;;;;;;:::i;:::-;;:::i;3711:267::-;;;;;;:::i;:::-;;:::i;1869:957::-;;;;;;:::i;:::-;;:::i;3514:162::-;1388:10;1410:4;1388:27;;;;1426:165;;1101:1;1460:14;;:39;1456:72;;1508:20;;;;;;;;;;;;;;1456:72;1101:1;1542:14;:38;1426:165;3627:42:::1;3636:5;3643;3650:9;3661:7;3627:8;:42::i;:::-;1617:10:::0;1613:56;;;1044:1;1629:14;:40;1613:56;1360:316;3514:162;;;;:::o;2930:332::-;1388:10;1410:4;1388:27;;;;1426:165;;1101:1;1460:14;;:39;1456:72;;1508:20;;;;;;;;;;;;;;1456:72;1101:1;1542:14;:38;1426:165;3043:29:::1;3059:5;3066;3043:15;:29::i;:::-;3100:38;::::0;;;;3132:4:::1;3100:38;::::0;::::1;160:74:15::0;3082:15:7::1;::::0;3100:23:::1;::::0;::::1;::::0;::::1;::::0;133:18:15;;3100:38:7::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3082:56;;3162:40;3181:11;3194:7;3162:18;:40::i;:::-;3213:42;::::0;;;;::::1;::::0;::::1;6205:25:15::0;;;3213:20:7::1;6266:55:15::0;;;6246:18;;;6239:83;3148:54:7;;-1:-1:-1;3213:20:7;;::::1;::::0;::::1;::::0;6178:18:15;;3213:42:7::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3033:229;1617:10:::0;1613:56;;;1044:1;1629:14;:40;1360:316;2930:332;;;;:::o;4013:268::-;1388:10;1410:4;1388:27;;;;1426:165;;1101:1;1460:14;;:39;1456:72;;1508:20;;;;;;;;;;;;;;1456:72;1101:1;1542:14;:38;1426:165;4091:9:::1;4086:189;4106:5;:12;4102:1;:16;4086:189;;;4140:12;4154:19:::0;4185:4:::1;4177:18;;4196:5;4202:1;4196:8;;;;;;;;:::i;:::-;;;;;;;4177:28;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4139:66;;;;4224:7;4219:45;;4233:31;4257:6;4233:23;:31::i;:::-;-1:-1:-1::0;;4120:3:7::1;;4086:189;;;;1617:10:::0;1613:56;;;1044:1;1629:14;:40;1613:56;1360:316;4013:268;:::o;3297:182::-;1388:10;1410:4;1388:27;;;;1426:165;;1101:1;1460:14;;:39;1456:72;;1508:20;;;;;;;;;;;;;;1456:72;1101:1;1542:14;:38;1426:165;3420:52:::1;3437:5;3444;3451:11;3464:7;3420:16;:52::i;3711:267::-:0;1388:10;1410:4;1388:27;;;;1426:165;;1101:1;1460:14;;:39;1456:72;;1508:20;;;;;;;;;;;;;;1456:72;1101:1;1542:14;:38;1426:165;3820:38:::1;::::0;;;;3852:4:::1;3820:38;::::0;::::1;160:74:15::0;3802:15:7::1;::::0;3820:23:::1;::::0;::::1;::::0;::::1;::::0;133:18:15;;3820:38:7::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3802:56;;3883:9;3872:7;:20;3868:104;;3908:53;3941:5;3949:2;3953:7;3908:25;:53::i;:::-;3792:186;1617:10:::0;1613:56;;;1044:1;1629:14;:40;1613:56;1360:316;3711:267;;;:::o;1869:957::-;1388:10;1410:4;1388:27;;;;1426:165;;1101:1;1460:14;;:39;1456:72;;1508:20;;;;;;;;;;;;;;1456:72;1101:1;1542:14;:38;1426:165;1022:1:8::1;1943:6:7;:11;;;:29;1939:63;;1981:21;;;;;;;;;;;;;;1939:63;2017:14:::0;;:33;;2013:333:::1;;2066:19;2078:6;2066:11;:19::i;:::-;2013:333;;;2106:14:::0;;:36;;2102:244:::1;;2158:21;2172:6;2158:13;:21::i;2102:244::-;2200:14:::0;;:36;;2196:150:::1;;2252:21;2266:6;2252:13;:21::i;2196:150::-;2311:24;;;;;;;;;;;;;;2196:150;2360:11;::::0;::::1;::::0;2356:41;2390:7:::1;2356:41;944:1:8;2474:6:7;:11;;;:31:::0;2470:217:::1;;2592:84;2609:6;:15;;;2626:6;:15;;;2643:6;:16;;;2661:6;:14;;;2592:16;:84::i;:::-;2758:61;2767:6;:14;;;2783:6;:14;;;2799:1;2802:6;:16;;;2758:8;:61::i;:::-;1617:10:::0;1613:56;;;1044:1;1629:14;:40;1360:316;1869:957;:::o;4304:306::-;4407:29;4423:5;4430;4407:15;:29::i;:::-;4464:38;;;;;4496:4;4464:38;;;160:74:15;4446:15:7;;4464:23;;;;;;133:18:15;;4464:38:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4446:56;;4528:9;4517:7;:20;4513:91;;4553:40;;;;;;;;6205:25:15;;;4553:22:7;6266:55:15;;;6246:18;;;6239:83;4553:22:7;;;;;6178:18:15;;4553:40:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;4397:213;4304:306;;;;:::o;2552:138:8:-;2628:55;2649:5;2656:7;2665:17;2628:20;:55::i;5295:252:7:-;5384:7;5422:17;5407:11;:32;;:57;;;;;5457:7;5443:11;:21;5407:57;5403:109;;;5494:7;5480:21;;5403:109;-1:-1:-1;5529:11:7;;5295:252;-1:-1:-1;5295:252:7:o;327:237:3:-;397:13;;:17;393:126;;487:6;481:13;472:6;468:2;464:15;457:38;393:126;536:21;;;;;;;;;;;;;;4616:458:7;4729:29;4745:5;4752;4729:15;:29::i;:::-;4786:38;;;;;4818:4;4786:38;;;160:74:15;4768:15:7;;4786:23;;;;;;133:18:15;;4786:38:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4768:56;;4848:40;4867:11;4880:7;4848:18;:40::i;:::-;4913:42;;;;;;;;6205:25:15;;;4913:20:7;6266:55:15;;;6246:18;;;6239:83;4834:54:7;;-1:-1:-1;4913:20:7;;;;;;6178:18:15;;4913:42:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4899:56;;4980:11;4970:7;:21;4966:102;;;5007:50;;;;;5030:17;5007:50;;;6205:25:15;5007:22:7;6266:55:15;;;6246:18;;;6239:83;5007:22:7;;;;;6178:18:15;;5007:50:7;6031:297:15;1874:270:4;2012:44;;1992:19;7261:55:15;;;2012:44:4;;;7243:74:15;7333:18;;;7326:34;;;1957:12:4;;;;1992:19;;;7216:18:15;;2012:44:4;;;-1:-1:-1;;2012:44:4;;;;;;;;;;;;;;;;;;;;1992:65;;;2012:44;1992:65;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1956:101;;;;2072:34;2092:7;2101:4;2072:19;:34::i;:::-;2067:70;;2108:29;2132:4;2108:23;:29::i;491:506:9:-;566:14;582:20;617:6;:11;;;606:41;;;;;;;;;;;;:::i;:::-;565:82;;;;944:1:8;662:6:9;:11;;;:31;658:58;;695:21;709:6;695:13;:21::i;:::-;;;658:58;767:39;783:6;:14;;;799:6;767:15;:39::i;:::-;818:12;832:19;855:6;:11;;867:7;855:20;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;817:58;;;;890:7;889:8;:59;;;-1:-1:-1;902:13:9;;:18;:45;;;;-1:-1:-1;924:18:9;;;;:23;902:45;885:105;;;975:6;983;957:33;;;;;;;;;;;;:::i;:::-;;;;;;;;621:980:10;701:11;;;;697:66;;738:25;;;;;;;;;;;;;;697:66;798:2;777:6;:11;;;:18;:23;:55;;;;825:2;804:6;:11;;;:18;:23;;;;:::i;:::-;:28;;777:55;773:98;;;841:30;;;;;;;;;;;;;;773:98;882:48;898:6;:14;;;914:15;882;:48::i;:::-;1007:17;1026:16;1046:21;1060:6;1046:13;:21::i;:::-;1006:61;;-1:-1:-1;1006:61:10;-1:-1:-1;1082:13:10;;1078:517;;1112:12;1126:19;1149:15;:20;;1289:9;1300:17;1330:6;:11;;;1319:36;;;;;;;;;;;;:::i;:::-;1357:8;1367:15;1187:214;;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1187:214:10;;;;;;;;;;;;;;;;;;;;1149:266;;;1187:214;1149:266;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1111:304;;;;1434:7;1433:8;:68;;;-1:-1:-1;1446:13:10;;:18;:54;;;;-1:-1:-1;1468:27:10;:15;:27;;:32;1446:54;1429:156;;;1546:15;1563:6;1528:42;;;;;;;;;;;;:::i;1078:517::-;687:914;;621:980;:::o;616:1223:11:-;696:11;;;;692:66;;733:25;;;;;;;;;;;;;;692:66;817:2;796:6;:11;;;:18;:23;:62;;;;851:2;845;824:6;:11;;;:18;:23;823:30;;;;;:::i;:::-;;:35;;796:62;792:105;;;867:30;;;;;;;;;;;;;;792:105;918:48;934:6;:14;;;950:15;918;:48::i;:::-;1058:17;1077:16;1097:21;1111:6;1097:13;:21::i;:::-;1057:61;;-1:-1:-1;1057:61:11;-1:-1:-1;1133:13:11;;1129:704;;1163:12;1177:19;1200:15;:20;;1321:300;;;;;;;;1385:6;:11;;;1321:300;;;;1433:8;1321:300;;;;;;1583:15;1321:300;;;;1478:9;1321:300;;;;1530:17;1321:300;;;1238:401;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1238:401:11;;;;;;;;;;;;;;;;;;;;1200:453;;;1238:401;1200:453;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1162:491;;;;1672:7;1671:8;:68;;;-1:-1:-1;1684:13:11;;:18;:54;;;;-1:-1:-1;1706:27:11;:15;:27;;:32;1684:54;1667:156;;;1784:15;1801:6;1766:42;;;;;;;;;;;;:::i;3011:492:8:-;3103:12;3117:17;3138:32;3153:5;3160:2;3164:5;3138:14;:32::i;:::-;3102:68;;;;3264:7;3259:184;;3300:28;3315:5;3322:2;3326:1;3300:14;:28::i;:::-;-1:-1:-1;3287:41:8;-1:-1:-1;3342:91:8;;;;3386:32;3401:5;3408:2;3412:5;3386:14;:32::i;:::-;-1:-1:-1;3373:45:8;-1:-1:-1;3342:91:8;3458:7;3453:43;;3467:29;3491:4;3467:23;:29::i;2150:202:4:-;2238:4;2261:11;:84;;;;-1:-1:-1;2277:11:4;;:16;;:67;;;2313:2;2298:4;:11;:17;;:45;;;;;2330:4;2319:24;;;;;;;;;;;;:::i;:::-;2254:91;2150:202;-1:-1:-1;;;2150:202:4:o;1167:1379:8:-;1298:16;;;;1335:15;;;;1365:11;;;;1361:62;;1167:1379;;;:::o;1361:62::-;1462:15;;;;1455:48;;;;;1497:4;1455:48;;;160:74:15;1434:18:8;;1455:33;;;;;133:18:15;;1455:48:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1434:69;;771:1;1653:6;:11;;;:29;:65;;;;-1:-1:-1;1686:15:8;;;;:32;;1713:4;1686:32;1653:65;1649:245;;;1788:9;1774:10;:23;;:52;;1816:10;1804:9;:22;1774:52;;;1800:1;1774:52;1762:64;;1855:28;1167:1379;;;:::o;1649:245::-;944:1;1908:6;:11;;;:31;1904:636;;1978:15;;;;2002:14;;;;;1970:47;;;;;:31;178:55:15;;;1970:47:8;;;160:74:15;1955:12:8;;1970:31;;;;;;;133:18:15;;1970:47:8;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;1955:62;;2092:4;2080:9;:16;2076:49;;;2105:20;;;;;;;;;;;;;;2076:49;2255:16;;;2236;;;:35;;;2255:16;2369:23;;;;:52;;2411:10;2399:9;:22;2369:52;;;2395:1;2369:52;2357:64;;2524:4;2505:24;;1941:599;1904:636;1276:1270;1167:1379;;;:::o;2696:309::-;2857:58;;;2846:10;7261:55:15;;;2857:58:8;;;7243:74:15;7333:18;;;;7326:34;;;2857:58:8;;;;;;;;;;7216:18:15;;;;2857:58:8;;;;;;;;;2880:23;2857:58;;;2846:70;;-1:-1:-1;;2786:12:8;;-1:-1:-1;;;;2846:10:8;;;:70;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2810:106;;;;2934:7;:57;;;;-1:-1:-1;2946:11:8;;:16;;:44;;;2977:4;2966:24;;;;;;;;;;;;:::i;:::-;2926:72;2993:4;;-1:-1:-1;2696:309:8;-1:-1:-1;;;;;2696:309:8:o;245:154:15:-;331:42;324:5;320:54;313:5;310:65;300:93;;389:1;386;379:12;300:93;245:154;:::o;404:134::-;472:20;;501:31;472:20;501:31;:::i;:::-;404:134;;;:::o;543:598::-;629:6;637;645;653;706:3;694:9;685:7;681:23;677:33;674:53;;;723:1;720;713:12;674:53;762:9;749:23;781:31;806:5;781:31;:::i;:::-;831:5;-1:-1:-1;888:2:15;873:18;;860:32;901:33;860:32;901:33;:::i;:::-;953:7;-1:-1:-1;1007:2:15;992:18;;979:32;;-1:-1:-1;1063:2:15;1048:18;;1035:32;1076:33;1035:32;1076:33;:::i;:::-;543:598;;;;-1:-1:-1;543:598:15;;-1:-1:-1;;543:598:15:o;1328:184::-;1380:77;1377:1;1370:88;1477:4;1474:1;1467:15;1501:4;1498:1;1491:15;1517:255;1589:2;1583:9;1631:6;1619:19;;1668:18;1653:34;;1689:22;;;1650:62;1647:88;;;1715:18;;:::i;:::-;1751:2;1744:22;1517:255;:::o;1777:334::-;1848:2;1842:9;1904:2;1894:13;;-1:-1:-1;;1890:86:15;1878:99;;2007:18;1992:34;;2028:22;;;1989:62;1986:88;;;2054:18;;:::i;:::-;2090:2;2083:22;1777:334;;-1:-1:-1;1777:334:15:o;2116:181::-;2174:4;2207:18;2199:6;2196:30;2193:56;;;2229:18;;:::i;:::-;-1:-1:-1;2274:1:15;2270:14;2286:4;2266:25;;2116:181::o;2302:245::-;2350:4;2383:18;2375:6;2372:30;2369:56;;;2405:18;;:::i;:::-;-1:-1:-1;2462:2:15;2450:15;-1:-1:-1;;2446:88:15;2536:4;2442:99;;2302:245::o;2552:462::-;2594:5;2647:3;2640:4;2632:6;2628:17;2624:27;2614:55;;2665:1;2662;2655:12;2614:55;2701:6;2688:20;2732:48;2748:31;2776:2;2748:31;:::i;:::-;2732:48;:::i;:::-;2805:2;2796:7;2789:19;2851:3;2844:4;2839:2;2831:6;2827:15;2823:26;2820:35;2817:55;;;2868:1;2865;2858:12;2817:55;2933:2;2926:4;2918:6;2914:17;2907:4;2898:7;2894:18;2881:55;2981:1;2956:16;;;2974:4;2952:27;2945:38;;;;2960:7;2552:462;-1:-1:-1;;;2552:462:15:o;3019:1129::-;3112:6;3143:2;3186;3174:9;3165:7;3161:23;3157:32;3154:52;;;3202:1;3199;3192:12;3154:52;3242:9;3229:23;3271:18;3312:2;3304:6;3301:14;3298:34;;;3328:1;3325;3318:12;3298:34;3366:6;3355:9;3351:22;3341:32;;3411:7;3404:4;3400:2;3396:13;3392:27;3382:55;;3433:1;3430;3423:12;3382:55;3469:2;3456:16;3492:58;3508:41;3546:2;3508:41;:::i;3492:58::-;3584:15;;;3666:1;3662:10;;;;3654:19;;3650:28;;;3615:12;;;;3690:19;;;3687:39;;;3722:1;3719;3712:12;3687:39;3754:2;3750;3746:11;3766:352;3782:6;3777:3;3774:15;3766:352;;;3868:3;3855:17;3904:2;3891:11;3888:19;3885:109;;;3948:1;3977:2;3973;3966:14;3885:109;4019:56;4067:7;4062:2;4048:11;4044:2;4040:20;4036:29;4019:56;:::i;:::-;4007:69;;-1:-1:-1;4096:12:15;;;;3799;;3766:352;;;-1:-1:-1;4137:5:15;3019:1129;-1:-1:-1;;;;;;;;3019:1129:15:o;4153:456::-;4230:6;4238;4246;4299:2;4287:9;4278:7;4274:23;4270:32;4267:52;;;4315:1;4312;4305:12;4267:52;4354:9;4341:23;4373:31;4398:5;4373:31;:::i;:::-;4423:5;-1:-1:-1;4475:2:15;4460:18;;4447:32;;-1:-1:-1;4531:2:15;4516:18;;4503:32;4544:33;4503:32;4544:33;:::i;:::-;4596:7;4586:17;;;4153:456;;;;;:::o;4614:1223::-;4701:6;4754:2;4742:9;4733:7;4729:23;4725:32;4722:52;;;4770:1;4767;4760:12;4722:52;4810:9;4797:23;4839:18;4880:2;4872:6;4869:14;4866:34;;;4896:1;4893;4886:12;4866:34;4919:22;;;;4975:6;4957:16;;;4953:29;4950:49;;;4995:1;4992;4985:12;4950:49;5021:22;;:::i;:::-;5079:2;5066:16;5059:5;5052:31;5136:2;5132;5128:11;5115:25;5110:2;5103:5;5099:14;5092:49;5173:31;5200:2;5196;5192:11;5173:31;:::i;:::-;5168:2;5161:5;5157:14;5150:55;5237:31;5264:2;5260;5256:11;5237:31;:::i;:::-;5232:2;5225:5;5221:14;5214:55;5302:32;5329:3;5325:2;5321:12;5302:32;:::i;:::-;5296:3;5289:5;5285:15;5278:57;5368:32;5395:3;5391:2;5387:12;5368:32;:::i;:::-;5362:3;5355:5;5351:15;5344:57;5434:32;5461:3;5457:2;5453:12;5434:32;:::i;:::-;5428:3;5421:5;5417:15;5410:57;5500:32;5527:3;5523:2;5519:12;5500:32;:::i;:::-;5494:3;5483:15;;5476:57;5552:3;5600:11;;;5587:25;5571:14;;;5564:49;5632:3;5673:11;;;5660:25;5697:16;;;5694:36;;;5726:1;5723;5716:12;5694:36;5762:44;5798:7;5787:8;5783:2;5779:17;5762:44;:::i;:::-;5746:14;;;5739:68;;;;-1:-1:-1;5750:5:15;4614:1223;-1:-1:-1;;;;;4614:1223:15:o;5842:184::-;5912:6;5965:2;5953:9;5944:7;5940:23;5936:32;5933:52;;;5981:1;5978;5971:12;5933:52;-1:-1:-1;6004:16:15;;5842:184;-1:-1:-1;5842:184:15:o;6333:::-;6385:77;6382:1;6375:88;6482:4;6479:1;6472:15;6506:4;6503:1;6496:15;6522:250;6607:1;6617:113;6631:6;6628:1;6625:13;6617:113;;;6707:11;;;6701:18;6688:11;;;6681:39;6653:2;6646:10;6617:113;;;-1:-1:-1;;6764:1:15;6746:16;;6739:27;6522:250::o;6777:287::-;6906:3;6944:6;6938:13;6960:66;7019:6;7014:3;7007:4;6999:6;6995:17;6960:66;:::i;:::-;7042:16;;;;;6777:287;-1:-1:-1;;6777:287:15:o;7371:783::-;7467:6;7475;7528:2;7516:9;7507:7;7503:23;7499:32;7496:52;;;7544:1;7541;7534:12;7496:52;7576:9;7570:16;7595:31;7620:5;7595:31;:::i;:::-;7694:2;7679:18;;7673:25;7645:5;;-1:-1:-1;7721:18:15;7710:30;;7707:50;;;7753:1;7750;7743:12;7707:50;7776:22;;7829:4;7821:13;;7817:27;-1:-1:-1;7807:55:15;;7858:1;7855;7848:12;7807:55;7887:2;7881:9;7912:48;7928:31;7956:2;7928:31;:::i;7912:48::-;7983:2;7976:5;7969:17;8023:7;8018:2;8013;8009;8005:11;8001:20;7998:33;7995:53;;;8044:1;8041;8034:12;7995:53;8057:67;8121:2;8116;8109:5;8105:14;8100:2;8096;8092:11;8057:67;:::i;:::-;8143:5;8133:15;;;;;7371:783;;;;;:::o;8159:329::-;8200:3;8238:5;8232:12;8265:6;8260:3;8253:19;8281:76;8350:6;8343:4;8338:3;8334:14;8327:4;8320:5;8316:16;8281:76;:::i;:::-;8402:2;8390:15;-1:-1:-1;;8386:88:15;8377:98;;;;8477:4;8373:109;;8159:329;-1:-1:-1;;8159:329:15:o;8493:337::-;8680:42;8672:6;8668:55;8657:9;8650:74;8760:2;8755;8744:9;8740:18;8733:30;8631:4;8780:44;8820:2;8809:9;8805:18;8797:6;8780:44;:::i;:::-;8772:52;8493:337;-1:-1:-1;;;;8493:337:15:o;8835:184::-;8887:77;8884:1;8877:88;8984:4;8981:1;8974:15;9008:4;9005:1;8998:15;9024:266;9056:1;9082;9072:189;;9117:77;9114:1;9107:88;9218:4;9215:1;9208:15;9246:4;9243:1;9236:15;9072:189;-1:-1:-1;9275:9:15;;9024:266::o;9295:954::-;9390:6;9421:2;9464;9452:9;9443:7;9439:23;9435:32;9432:52;;;9480:1;9477;9470:12;9432:52;9513:9;9507:16;9546:18;9538:6;9535:30;9532:50;;;9578:1;9575;9568:12;9532:50;9601:22;;9654:4;9646:13;;9642:27;-1:-1:-1;9632:55:15;;9683:1;9680;9673:12;9632:55;9712:2;9706:9;9735:58;9751:41;9789:2;9751:41;:::i;9735:58::-;9827:15;;;9909:1;9905:10;;;;9897:19;;9893:28;;;9858:12;;;;9933:19;;;9930:39;;;9965:1;9962;9955:12;9930:39;9989:11;;;;10009:210;10025:6;10020:3;10017:15;10009:210;;;10098:3;10092:10;10115:31;10140:5;10115:31;:::i;:::-;10159:18;;10042:12;;;;10197;;;;10009:210;;;10238:5;9295:954;-1:-1:-1;;;;;;;9295:954:15:o;10254:1018::-;10508:4;10556:3;10545:9;10541:19;10587:6;10576:9;10569:25;10613:2;10651:6;10646:2;10635:9;10631:18;10624:34;10694:3;10689:2;10678:9;10674:18;10667:31;10718:6;10753;10747:13;10784:6;10776;10769:22;10822:3;10811:9;10807:19;10800:26;;10861:2;10853:6;10849:15;10835:29;;10882:1;10892:218;10906:6;10903:1;10900:13;10892:218;;;10971:13;;10986:42;10967:62;10955:75;;11085:15;;;;11050:12;;;;10928:1;10921:9;10892:218;;;-1:-1:-1;;11178:42:15;11166:55;;;;11161:2;11146:18;;11139:83;-1:-1:-1;;;11253:3:15;11238:19;11231:35;11127:3;10254:1018;-1:-1:-1;;;10254:1018:15:o;11277:677::-;11476:2;11465:9;11458:21;11439:4;11514:6;11508:13;11557:4;11552:2;11541:9;11537:18;11530:32;11585:51;11631:3;11620:9;11616:19;11602:12;11585:51;:::i;:::-;11571:65;;11700:42;11694:2;11686:6;11682:15;11676:22;11672:71;11667:2;11656:9;11652:18;11645:99;11798:2;11790:6;11786:15;11780:22;11775:2;11764:9;11760:18;11753:50;11858:2;11850:6;11846:15;11840:22;11834:3;11823:9;11819:19;11812:51;11919:3;11911:6;11907:16;11901:23;11894:4;11883:9;11879:20;11872:53;11942:6;11934:14;;;11277:677;;;;:::o;11959:277::-;12026:6;12079:2;12067:9;12058:7;12054:23;12050:32;12047:52;;;12095:1;12092;12085:12;12047:52;12127:9;12121:16;12180:5;12173:13;12166:21;12159:5;12156:32;12146:60;;12202:1;12199;12192:12
Swarm Source
ipfs://897e21eaf6bcb14a665794639e836a64c2da3fd4b185cfb220bc8706f55a9046
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
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.