Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00Latest 25 from a total of 29 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Deposit With Tok... | 24504580 | 16 days ago | IN | 0 ETH | 0.00002999 | ||||
| Deposit With Tok... | 24497274 | 17 days ago | IN | 0 ETH | 0.00004799 | ||||
| Deposit With Tok... | 24496723 | 17 days ago | IN | 0 ETH | 0.00003618 | ||||
| Deposit With Tok... | 24491012 | 18 days ago | IN | 0 ETH | 0.00008185 | ||||
| Deposit With Tok... | 24482479 | 19 days ago | IN | 0 ETH | 0.00003498 | ||||
| Deposit With Tok... | 24439158 | 25 days ago | IN | 0 ETH | 0.00006563 | ||||
| Deposit With Tok... | 24419252 | 28 days ago | IN | 0 ETH | 0.00000327 | ||||
| Deposit With Tok... | 24419251 | 28 days ago | IN | 0 ETH | 0.00005434 | ||||
| Deposit With Tok... | 24419054 | 28 days ago | IN | 0 ETH | 0.00005881 | ||||
| Deposit With Tok... | 24418295 | 28 days ago | IN | 0 ETH | 0.00006893 | ||||
| Deposit With Tok... | 24405051 | 30 days ago | IN | 0 ETH | 0.00010953 | ||||
| Deposit With Tok... | 24404711 | 30 days ago | IN | 0 ETH | 0.00009934 | ||||
| Deposit With Tok... | 24397123 | 31 days ago | IN | 0 ETH | 0.00031388 | ||||
| Deposit With Tok... | 24397068 | 31 days ago | IN | 0 ETH | 0.00034281 | ||||
| Deposit With Tok... | 24396959 | 31 days ago | IN | 0 ETH | 0.00035842 | ||||
| Deposit With Tok... | 24396867 | 31 days ago | IN | 0 ETH | 0.00026649 | ||||
| Deposit With Tok... | 24396116 | 31 days ago | IN | 0 ETH | 0.00044635 | ||||
| Deposit With Tok... | 24390015 | 32 days ago | IN | 0 ETH | 0.00016143 | ||||
| Deposit With Tok... | 24389470 | 32 days ago | IN | 0 ETH | 0.00022473 | ||||
| Deposit With Tok... | 24389386 | 32 days ago | IN | 0 ETH | 0.00012807 | ||||
| Deposit With Tok... | 24389233 | 32 days ago | IN | 0 ETH | 0.00021197 | ||||
| Deposit With Tok... | 24383571 | 33 days ago | IN | 0 ETH | 0.00018771 | ||||
| Deposit With Tok... | 24383543 | 33 days ago | IN | 0 ETH | 0.00024054 | ||||
| Deposit With Tok... | 24383242 | 33 days ago | IN | 0 ETH | 0.00030383 | ||||
| Deposit With Tok... | 24382408 | 33 days ago | IN | 0 ETH | 0.00012642 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
VaultRouter
Compiler Version
v0.8.27+commit.40a35a09
Optimization Enabled:
Yes with 10000 runs
Other Settings:
prague EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {IERC4626} from "openzeppelin-contracts/contracts/interfaces/IERC4626.sol";
import {Ownable} from "openzeppelin-contracts/contracts/access/Ownable.sol";
import {IUniversalDexModule} from "../interfaces/IUniversalDexModule.sol";
import {IERC20} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol";
import {Errors} from "../common/Errors.sol";
import {DataTypes} from "../common/DataTypes.sol";
import {IDepositManager} from "../interfaces/IDepositManager.sol";
/**
* @title VaultRouter
* @author Superlend
* @notice Router contract for vault deposits with optional token swapping
* @dev Handles deposits into vaults with automatic token conversion when needed
*/
contract VaultRouter is Ownable {
/**
* @notice Emitted when a vault is whitelisted or unwhitelisted
* @param vault The address of the vault
* @param isWhitelisted True if the vault is whitelisted, false if it is unwhitelisted
*/
event VaultWhitelisted(address indexed vault, bool isWhitelisted);
/**
* @notice Emitted when a token is whitelisted or unwhitelisted
* @param token The address of the token
* @param isWhitelisted True if the token is whitelisted, false if it is unwhitelisted
*/
event TokenWhitelisted(address indexed token, bool isWhitelisted);
/**
* @notice Emitted when a deposit manager is whitelisted or unwhitelisted
* @param depositManager The address of the deposit manager
* @param isWhitelisted True if the deposit manager is whitelisted, false if it is unwhitelisted
*/
event DepositManagerWhitelisted(address indexed depositManager, bool isWhitelisted);
/**
* @notice Mapping of supported vault addresses to their whitelist status
*/
mapping(address => bool) public supportedVaults;
/**
* @notice Mapping of supported token addresses to their whitelist status
*/
mapping(address => bool) public supportedTokens;
/**
* @notice Mapping of supported deposit manager addresses to their whitelist status
*/
mapping(address => bool) public supportedDepositManagers;
/**
* @notice The universal DEX module for token swaps
*/
IUniversalDexModule public universalDexModule;
/**
* @notice Constructor to initialize the vault router
* @param _supportedVaults Array of initially supported vault addresses
* @param _supportedTokens Array of initially supported token addresses
* @param _universalDexModule The address of the universal DEX module
* @param _supportedDepositManagers Array of initially supported deposit manager addresses
*/
constructor(
address[] memory _supportedVaults,
address[] memory _supportedTokens,
address _universalDexModule,
address[] memory _supportedDepositManagers
) Ownable(_msgSender()) {
for (uint256 i = 0; i < _supportedVaults.length; i++) {
supportedVaults[_supportedVaults[i]] = true;
emit VaultWhitelisted(_supportedVaults[i], true);
}
for (uint256 i = 0; i < _supportedTokens.length; i++) {
supportedTokens[_supportedTokens[i]] = true;
emit TokenWhitelisted(_supportedTokens[i], true);
}
for (uint256 i = 0; i < _supportedDepositManagers.length; i++) {
supportedDepositManagers[_supportedDepositManagers[i]] = true;
emit DepositManagerWhitelisted(_supportedDepositManagers[i], true);
}
universalDexModule = IUniversalDexModule(_universalDexModule);
}
/**
* @notice Deposits tokens into a vault with optional swap functionality
* @param vault The address of the target vault
* @param tokenIn The address of the input token
* @param amountIn The amount of input tokens to deposit
* @param swapParams Parameters for executing a swap if needed
*/
function depositWithToken(
address vault,
address depositManager,
address tokenIn,
uint256 amountIn,
DataTypes.DepositType depositType,
DataTypes.ExecuteSwapParams memory swapParams
) external {
require(supportedVaults[vault], Errors.VAULT_NOT_WHITELISTED);
require(supportedTokens[tokenIn], Errors.TOKEN_NOT_WHITELISTED);
require(supportedDepositManagers[depositManager], Errors.DEPOSIT_MANAGER_NOT_WHITELISTED);
address vaultAsset = IERC4626(vault).asset();
uint256 tokenInBalanceBefore = IERC20(tokenIn).balanceOf(address(this));
SafeERC20.safeTransferFrom(IERC20(tokenIn), _msgSender(), address(this), amountIn);
if (vaultAsset == tokenIn) {
_handleDeposit(vault, depositManager, tokenIn, amountIn, depositType);
return;
}
SafeERC20.forceApprove(IERC20(tokenIn), address(universalDexModule), amountIn);
uint256 amountOut = universalDexModule.executeAndExit(swapParams, address(this));
uint256 tokenInBalanceAfter = IERC20(tokenIn).balanceOf(address(this));
uint256 tokenInAmountLeft = tokenInBalanceAfter - tokenInBalanceBefore;
if (tokenInAmountLeft > 0) {
SafeERC20.safeTransfer(IERC20(tokenIn), _msgSender(), tokenInAmountLeft);
}
_handleDeposit(vault, depositManager, vaultAsset, amountOut, depositType);
}
/**
* @notice Adds or removes a vault from the whitelist (restricted to owner)
* @param vault The address of the vault to whitelist/unwhitelist
* @param isWhitelisted True to whitelist, false to remove from whitelist
*/
function whitelistVault(address vault, bool isWhitelisted) external onlyOwner {
supportedVaults[vault] = isWhitelisted;
emit VaultWhitelisted(vault, isWhitelisted);
}
/**
* @notice Adds or removes a token from the whitelist (restricted to owner)
* @param token The address of the token to whitelist/unwhitelist
* @param isWhitelisted True to whitelist, false to remove from whitelist
*/
function whitelistToken(address token, bool isWhitelisted) external onlyOwner {
supportedTokens[token] = isWhitelisted;
emit TokenWhitelisted(token, isWhitelisted);
}
/**
* @notice Adds or removes a deposit manager from the whitelist (restricted to owner)
* @param depositManager The address of the deposit manager to whitelist/unwhitelist
* @param isWhitelisted True to whitelist, false to remove from whitelist
*/
function whitelistDepositManager(address depositManager, bool isWhitelisted) external onlyOwner {
supportedDepositManagers[depositManager] = isWhitelisted;
emit DepositManagerWhitelisted(depositManager, isWhitelisted);
}
/**
* @notice Sets the universal DEX module address (restricted to owner)
* @param _universalDexModule The address of the universal DEX module
*/
function setUniversalDexModule(address _universalDexModule) external onlyOwner {
universalDexModule = IUniversalDexModule(_universalDexModule);
}
/**
* @notice Handles the deposit based on the deposit type
* @param vault The address of the vault
* @param depositManager The address of the deposit manager
* @param tokenIn The address of the input token
* @param amountIn The amount of input tokens to deposit
* @param depositType The type of deposit
*/
function _handleDeposit(
address vault,
address depositManager,
address tokenIn,
uint256 amountIn,
DataTypes.DepositType depositType
) internal {
if (depositType == DataTypes.DepositType.INSTANT) {
_instantDeposit(vault, tokenIn, amountIn);
} else {
_requestedDeposit(depositManager, tokenIn, amountIn);
}
}
/**
* @notice Handles the instant deposit
* @param vault The address of the vault
* @param tokenIn The address of the input token
* @param amountIn The amount of input tokens to deposit
*/
function _instantDeposit(address vault, address tokenIn, uint256 amountIn) internal {
SafeERC20.forceApprove(IERC20(tokenIn), vault, amountIn);
IERC4626(vault).deposit(amountIn, _msgSender());
}
/**
* @notice Handles the requested deposit
* @param depositManager The address of the deposit manager
* @param tokenIn The address of the input token
* @param amountIn The amount of input tokens to deposit
*/
function _requestedDeposit(address depositManager, address tokenIn, uint256 amountIn) internal {
SafeERC20.forceApprove(IERC20(tokenIn), depositManager, amountIn);
IDepositManager(depositManager).requestDeposit(amountIn, _msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (interfaces/IERC4626.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";
import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol";
/**
* @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in
* https://eips.ethereum.org/EIPS/eip-4626[ERC-4626].
*/
interface IERC4626 is IERC20, IERC20Metadata {
event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares);
event Withdraw(
address indexed sender,
address indexed receiver,
address indexed owner,
uint256 assets,
uint256 shares
);
/**
* @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
*
* - MUST be an ERC-20 token contract.
* - MUST NOT revert.
*/
function asset() external view returns (address assetTokenAddress);
/**
* @dev Returns the total amount of the underlying asset that is “managed” by Vault.
*
* - SHOULD include any compounding that occurs from yield.
* - MUST be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT revert.
*/
function totalAssets() external view returns (uint256 totalManagedAssets);
/**
* @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToShares(uint256 assets) external view returns (uint256 shares);
/**
* @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal
* scenario where all the conditions are met.
*
* - MUST NOT be inclusive of any fees that are charged against assets in the Vault.
* - MUST NOT show any variations depending on the caller.
* - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange.
* - MUST NOT revert.
*
* NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the
* “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and
* from.
*/
function convertToAssets(uint256 shares) external view returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver,
* through a deposit call.
*
* - MUST return a limited value if receiver is subject to some deposit limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
* - MUST NOT revert.
*/
function maxDeposit(address receiver) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit
* call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called
* in the same transaction.
* - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the
* deposit would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewDeposit(uint256 assets) external view returns (uint256 shares);
/**
* @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* deposit execution, and are accounted for during deposit.
* - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function deposit(uint256 assets, address receiver) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
* - MUST return a limited value if receiver is subject to some mint limit.
* - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
* - MUST NOT revert.
*/
function maxMint(address receiver) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given
* current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call
* in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the
* same transaction.
* - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint
* would be accepted, regardless if the user has enough tokens approved, etc.
* - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by minting.
*/
function previewMint(uint256 shares) external view returns (uint256 assets);
/**
* @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
*
* - MUST emit the Deposit event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint
* execution, and are accounted for during mint.
* - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not
* approving enough underlying tokens to the Vault contract, etc).
*
* NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
*/
function mint(uint256 shares, address receiver) external returns (uint256 assets);
/**
* @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the
* Vault, through a withdraw call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxWithdraw(address owner) external view returns (uint256 maxAssets);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw
* call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if
* called
* in the same transaction.
* - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though
* the withdrawal would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by depositing.
*/
function previewWithdraw(uint256 assets) external view returns (uint256 shares);
/**
* @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* withdraw execution, and are accounted for during withdraw.
* - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
/**
* @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault,
* through a redeem call.
*
* - MUST return a limited value if owner is subject to some withdrawal limit or timelock.
* - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock.
* - MUST NOT revert.
*/
function maxRedeem(address owner) external view returns (uint256 maxShares);
/**
* @dev Allows an on-chain or off-chain user to simulate the effects of their redemption at the current block,
* given current on-chain conditions.
*
* - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call
* in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the
* same transaction.
* - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the
* redemption would be accepted, regardless if the user has enough shares, etc.
* - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees.
* - MUST NOT revert.
*
* NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in
* share price or some other type of condition, meaning the depositor will lose assets by redeeming.
*/
function previewRedeem(uint256 shares) external view returns (uint256 assets);
/**
* @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver.
*
* - MUST emit the Withdraw event.
* - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the
* redeem execution, and are accounted for during redeem.
* - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner
* not having enough shares, etc).
*
* NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed.
* Those methods should be performed separately.
*/
function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import {DataTypes} from "../common/DataTypes.sol";
/**
* @title IUniversalDexModule
* @author Superlend
* @notice Interface for universal DEX module operations
* @dev Handles token swaps and exchange operations across multiple DEX protocols
*/
interface IUniversalDexModule {
/**
* @notice Executes a token swap operation
* @param params The parameters for the swap operation
* @return The amount of output tokens received
*/
function execute(DataTypes.ExecuteSwapParams memory params) external returns (uint256);
/**
* @notice Executes a token swap and transfers the result to a specified address
* @param params The parameters for the swap operation
* @param to The address to receive the swapped tokens
* @return The amount of output tokens received
*/
function executeAndExit(DataTypes.ExecuteSwapParams memory params, address to) external returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-20 standard as defined in the ERC.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC-20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
/**
* @dev An operation with an ERC-20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Variant of {safeTransfer} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransfer(IERC20 token, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Variant of {safeTransferFrom} that returns a bool instead of reverting if the operation is not successful.
*/
function trySafeTransferFrom(IERC20 token, address from, address to, uint256 value) internal returns (bool) {
return _callOptionalReturnBool(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*
* IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
* smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
* this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
* that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*
* NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
* only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
* set here.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
safeTransfer(token, to, value);
} else if (!token.transferAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
* has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* Reverts if the returned value is other than `true`.
*/
function transferFromAndCallRelaxed(
IERC1363 token,
address from,
address to,
uint256 value,
bytes memory data
) internal {
if (to.code.length == 0) {
safeTransferFrom(token, from, to, value);
} else if (!token.transferFromAndCall(from, to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
* code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
* targeting contracts.
*
* NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
* Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
* once without retrying, and relies on the returned value to be true.
*
* Reverts if the returned value is other than `true`.
*/
function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
if (to.code.length == 0) {
forceApprove(token, to, value);
} else if (!token.approveAndCall(to, value, data)) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
// bubble errors
if iszero(success) {
let ptr := mload(0x40)
returndatacopy(ptr, 0, returndatasize())
revert(ptr, returndatasize())
}
returnSize := returndatasize()
returnValue := mload(0)
}
if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
bool success;
uint256 returnSize;
uint256 returnValue;
assembly ("memory-safe") {
success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
returnSize := returndatasize()
returnValue := mload(0)
}
return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
/**
* @title Errors
* @author Superlend
* @notice Library containing all error constants used throughout the Superloop protocol
* @dev Centralized error definitions for consistent error handling across contracts
*/
library Errors {
string public constant INVALID_ADDRESS = "1"; // address must not be 0
string public constant INVALID_MODULE_NAME = "2"; // module name empty
string public constant INVALID_AMOUNT = "3"; // amount cannot be 0
string public constant WITHDRAW_REQUEST_ACTIVE = "5"; // one acitve withdraw request already exist
string public constant INVALID_WITHDRAW_RESOLVED_START_ID_LIMIT = "6"; // new start id should be = old end id + 1
string public constant INVALID_WITHDRAW_RESOLVED_END_ID_LIMIT = "7"; // new end id should be < current id
string public constant CALLER_NOT_VAULT = "8"; // the caller of function is not vault
string public constant INVALID_WITHDRAW_REQUEST_STATE = "9"; // incorrect withdraw request state
string public constant INVALID_ASSETS_DISTRIBUTED = "10"; // total assets distributed does not match total assets redeemed
string public constant WITHDRAW_REQUEST_NOT_FOUND = "11"; // withdraw request not found
string public constant WITHDRAW_REQUEST_ALREADY_CLAIMED = "12"; // withdraw request already claimed
string public constant WITHDRAW_REQUEST_NOT_RESOLVED = "13"; // withdraw request not resolved
string public constant CALLER_NOT_WITHDRAW_REQUEST_OWNER = "14"; // the caller of function is not the owner of the withdraw request
string public constant INVALID_PERFORMANCE_FEE = "15"; // performance fee is greater than max performance fee
string public constant INVALID_MODULE = "16"; // module is not whitelisted
string public constant INVALID_SWAP_DATA = "17"; // invalid swap data
string public constant INVALID_AMOUNT_IN = "18"; // amount in is greater than max amount in
string public constant INVALID_AMOUNT_OUT = "19"; // amount out is less than min amount out
string public constant SUPPLY_CAP_EXCEEDED = "21"; // supply cap exceeded
string public constant INVALID_SHARES_AMOUNT = "22"; // shares amount cannot be 0
string public constant INSUFFICIENT_BALANCE = "23"; // insufficient balance
string public constant CALLER_NOT_PRIVILEGED = "24"; // the caller of function is not privileged
string public constant NOT_IN_EXECUTION_CONTEXT = "25"; // the caller of function is not in execution context
string public constant MODULE_NOT_REGISTERED = "26"; // module is not registered
string public constant CALLBACK_HANDLER_NOT_FOUND = "27"; // callback handler not found
string public constant CALLER_NOT_SELF = "28"; // the caller of function is not self
string public constant CALLER_NOT_VAULT_ADMIN = "29"; // the caller of function is not vault admin
string public constant INVALID_SKIM_ASSET = "30"; // invalid asset
string public constant VAULT_NOT_WHITELISTED = "31"; // vault is not whitelisted
string public constant TOKEN_NOT_WHITELISTED = "32"; // token is not whitelisted
string public constant INSTANT_WITHDRAW_NOT_ENABLED = "33"; // instant withdraw is not enabled
string public constant WITHDRAW_REQUEST_UNCLAIMED = "34"; // withdraw request is unclaimed
string public constant INVALID_CASH_RESERVE = "35"; // invalid cash reserve
string public constant INSUFFICIENT_CASH_SHORTFALL = "36"; // insufficient cash shortfall
string public constant DEPOSIT_REQUEST_ACTIVE = "37"; // deposit request is active
string public constant DEPOSIT_REQUEST_ALREADY_CANCELLED = "38"; // deposit request already cancelled
string public constant CALLER_NOT_DEPOSIT_REQUEST_OWNER = "39"; // the caller of function is not the owner of the deposit request
string public constant DEPOSIT_REQUEST_ALREADY_PROCESSED = "40"; // deposit request already processed
string public constant INVALID_ASSET = "41"; // invalid asset
string public constant CALLER_NOT_DEPOSIT_MANAGER = "42"; // the caller of function is not deposit manager
string public constant DEPOSIT_REQUEST_NOT_FOUND = "43"; // deposit request not found
string public constant CANNOT_CLAIM_ZERO_AMOUNT = "44"; // cannot claim zero amount
string public constant CALLER_NOT_WITHDRAW_MANAGER = "45"; // the caller of function is not withdraw manager
string public constant CALLER_NOT_VAULT_OPERATOR_OR_VAULT_ADMIN = "46"; // the caller of function is not vault operator
string public constant VAULT_PAUSED = "47"; // vault is paused
string public constant VAULT_FROZEN = "48"; // vault is frozen
string public constant DEPOSIT_MANAGER_NOT_WHITELISTED = "49"; // deposit manager is not whitelisted
string public constant FALLBACK_HANDLER_NOT_FOUND = "50"; // fallback handler not found
string public constant INVALID_FALLBACK_DATA = "51"; // invalid fallback data
// Preliquidation
string public constant PRELIQUIDATION_PRELTV_TOO_HIGH = "52"; // preltv is too high
string public constant PRELIQUIDATION_LCF_DECREASING = "53"; // lcf is decreasing
string public constant PRELIQUIDATION_LCF_TOO_HIGH = "54"; // lcf is too high
string public constant PRELIQUIDATION_LIF_TOO_LOW = "55"; // lif is too low
string public constant PRELIQUIDATION_LIF_DECREASING = "56"; // lif is decreasing
string public constant PRELIQUIDATION_LIF_TOO_HIGH = "57"; // lif is too high
string public constant PRELIQUIDATION_INVALID_ID = "58"; // id is invalid
string public constant PRELIQUIDATION_INVALID_USER = "59"; // user is invalid
string public constant PRELIQUIDATION_POSSIBLE_BAD_DEBT = "60"; // possible bad debt
string public constant PRELIQUIDATION_NOT_IN_PRELIQUIDATION_STATE = "61"; // not in preliquidation state
// Aave V3 Preliquidation
string public constant AAVE_V3_PRELIQUIDATION_INVALID_EMODE_CATEGORY = "62"; // reserve is not in the correct emode category
string public constant AAVE_V3_PRELIQUIDATION_INVALID_LLTV = "63"; // lltv is invalid
// Superloop
string public constant VAULT_ALREADY_SEEDED = "64"; // vault already seeded
string public constant INVALID_INSTANT_WITHDRAW_FEE = "65"; // instant withdraw fee is greater than max instant withdraw fee
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
/**
* @title DataTypes
* @author Superlend
* @notice Library containing all data structures and enums used throughout the Superloop protocol
* @dev Centralized data type definitions for consistent usage across contracts
*/
library DataTypes {
/**
* @notice Structure for storing module information
* @param moduleName The name identifier of the module
* @param moduleAddress The contract address of the module
*/
struct ModuleData {
string moduleName;
address moduleAddress;
}
struct ExchangeRateSnapshot {
uint256 totalSupplyBefore;
uint256 totalSupplyAfter;
uint256 totalAssetsBefore;
uint256 totalAssetsAfter;
}
enum RequestProcessingState {
NOT_EXIST,
UNPROCESSED,
PARTIALLY_PROCESSED, // partially processed means that the deposit request has been partially processed
PARTIALLY_CANCELLED, // partially cancelled means that the deposit request has been partially cancelled
FULLY_PROCESSED,
CANCELLED
}
struct DepositRequestData {
uint256 amount;
uint256 amountProcessed; // amoutn remaining => amount - amountProcessed
uint256 sharesMinted;
address user;
RequestProcessingState state;
}
struct ResolveDepositRequestsData {
address asset;
uint256 amount;
bytes callbackExecutionData;
}
enum WithdrawRequestType {
GENERAL, // general queue
DEFERRED, // low slippage queue
PRIORITY, // medium slippage queue
INSTANT // high slippage queue
}
struct WithdrawQueue {
uint256 nextWithdrawRequestId;
uint256 resolutionIdPointer;
mapping(uint256 => DataTypes.WithdrawRequestData) withdrawRequest;
mapping(address => uint256) userWithdrawRequestId;
uint256 totalPendingWithdraws;
}
struct WithdrawRequestData {
uint256 shares;
uint256 sharesProcessed;
uint256 amountClaimable;
uint256 amountClaimed;
address user;
RequestProcessingState state;
}
struct ResolveWithdrawRequestsData {
uint256 shares;
WithdrawRequestType requestType;
bytes callbackExecutionData;
}
/**
* @notice Structure for storing withdrawal request information
* @param shares The number of shares requested for withdrawal
* @param amount The amount of underlying asset for withdrawal
* @param user The address of the user making the withdrawal request
* @param claimed Whether the withdrawal has been claimed
* @param cancelled Whether the withdrawal request has been cancelled
*/
struct WithdrawRequestDataLegacy {
uint256 shares;
uint256 amount;
address user;
bool claimed;
bool cancelled;
}
/**
* @notice Enumeration of possible withdrawal request states
*/
enum WithdrawRequestStateLegacy {
NOT_EXIST, // Request does not exist
CLAIMED, // Request has been claimed
UNPROCESSED, // Request is pending processing
CLAIMABLE, // Request is ready to be claimed
CANCELLED // Request has been cancelled
}
/**
* @notice Structure for vault initialization data
* @param asset The address of the underlying asset
* @param name The name of the vault
* @param symbol The symbol of the vault
* @param supplyCap The maximum supply cap for the vault
* @param minimumDepositAmount The minimum deposit amount for the vault
* @param instantWithdrawFee The instant withdraw fee for the vault
* @param superloopModuleRegistry The address of the module registry
* @param modules Array of module addresses to register
* @param cashReserve The amount of cash reserve for the vault. Represented in BPS
* @param accountant The address of the accountant module
* @param withdrawManager The address of the withdraw manager module
* @param vaultAdmin The address of the vault admin
* @param treasury The address of the treasury
* @param vaultOperator The address of the vault operator
*/
struct VaultInitData {
// vault specific
address asset;
string name;
string symbol;
// superloop specific
uint256 supplyCap;
uint256 minimumDepositAmount;
uint256 instantWithdrawFee;
address superloopModuleRegistry;
address[] modules;
uint256 cashReserve;
// essential roles
address accountant;
address withdrawManager;
address depositManager;
address vaultAdmin;
address treasury;
address vaultOperator;
}
/**
* @notice Structure for universal DEX module swap execution data
* @param target The target contract address for the swap
* @param data The encoded function call data
*/
struct ExecuteSwapParamsData {
address target;
bytes data;
}
/**
* @notice Structure for complete swap execution parameters
* @param tokenIn The address of the input token
* @param tokenOut The address of the output token
* @param amountIn The amount of input tokens
* @param maxAmountIn The maximum amount of input tokens allowed
* @param minAmountOut The minimum amount of output tokens expected
* @param data Array of swap execution data for multi-step swaps
*/
struct ExecuteSwapParams {
address tokenIn;
address tokenOut;
uint256 amountIn;
uint256 maxAmountIn;
uint256 minAmountOut;
ExecuteSwapParamsData[] data;
}
/**
* @notice Structure for tracking balance differences before and after operations
* @param tokenInBalanceBefore Balance of input token before operation
* @param tokenOutBalanceBefore Balance of output token before operation
* @param tokenInBalanceAfter Balance of input token after operation
* @param tokenOutBalanceAfter Balance of output token after operation
*/
struct BalancesDifference {
uint256 tokenInBalanceBefore;
uint256 tokenOutBalanceBefore;
uint256 tokenInBalanceAfter;
uint256 tokenOutBalanceAfter;
}
/**
* @notice Structure for Aave V3 accountant module initialization
* @param poolAddressesProvider The Aave pool addresses provider
* @param lendAssets Array of assets available for lending
* @param borrowAssets Array of assets available for borrowing
* @param performanceFee The performance fee percentage
* @param vault The address of the associated vault
*/
struct AaveV3AccountantModuleInitData {
address poolAddressesProvider;
address[] lendAssets;
address[] borrowAssets;
uint16 performanceFee;
address vault;
}
/**
* @notice Structure for module execution data
* @param executionType The type of call to execute (CALL or DELEGATECALL)
* @param module The address of the module to execute
* @param data The encoded function call data
*/
struct ModuleExecutionData {
CallType executionType;
address module;
bytes data;
}
/**
* @notice Enumeration of call types for module execution
*/
enum CallType {
CALL, // Regular call to external contract
DELEGATECALL // Delegate call to external contract
}
/**
* @notice Structure for Aave V3 flashloan parameters
* @param asset The address of the asset to flashloan
* @param amount The amount to flashloan
* @param referralCode The referral code for Aave
* @param callbackExecutionData The data to execute in the flashloan callback
*/
struct AaveV3FlashloanParams {
address asset;
uint256 amount;
uint16 referralCode;
bytes callbackExecutionData;
}
/**
* @notice Structure for callback execution data
* @param asset The address of the asset involved
* @param addressToApprove The address to approve tokens for
* @param amountToApprove The amount to approve
* @param executionData The data to execute in the callback
*/
struct CallbackData {
address asset;
address addressToApprove;
uint256 amountToApprove;
bytes executionData;
}
/**
* @notice Structure for Aave V3 eMode parameters
* @param emodeCategory The eMode category to set
*/
struct AaveV3EmodeParams {
uint8 emodeCategory;
}
/**
* @notice Structure for Aave V3 action parameters
* @param asset The address of the asset
* @param amount The amount of the asset
*/
struct AaveV3ActionParams {
address asset;
uint256 amount;
}
/**
* @notice Structure for Aave V3 accountant module initialization
* @param registeredAccountants Array of registered accountant addresses
* @param performanceFee The performance fee percentage
* @param vault The address of the associated vault
*/
struct UniversalAccountantModuleInitData {
address[] registeredAccountants;
uint16 performanceFee;
address vault;
}
/**
* @notice Structure for Aave V3 accountant plugin module initialization
* @param poolAddressesProvider The Aave pool addresses provider
* @param lendAssets Array of assets available for lending
* @param borrowAssets Array of assets available for borrowing
*/
struct AaveV3AccountantPluginModuleInitData {
address poolAddressesProvider;
address[] lendAssets;
address[] borrowAssets;
}
/**
* @notice Structure for stake parameters
* @param assets The amount of assets to stake
* @param data Any additional data to pass to the stake module
*/
struct StakeParams {
uint256 assets;
bytes data;
}
enum DepositType {
INSTANT,
REQUESTED
}
/**
* @notice Structure for Aave V3 preliquidation parameters
* @param user The address of the user
* @param debtToCover The amount of debt to cover
*/
struct AaveV3ExecutePreliquidationParams {
address user;
uint256 debtToCover;
}
/**
* @notice Structure for Aave V3 preliquidation initialization parameters
* @param id The id of the preliquidation contract, used to make sure fallback handler is configured correctly
* @param lendReserve The address of the lend reserve
* @param borrowReserve The address of the borrow reserve
* @param preLltv The preliquidation ltv
* @param preCF1 The preliquidation c1
* @param preCF2 The preliquidation c2
* @param preIF1 The preliquidation i1
* @param preIF2 The preliquidation i2
*/
struct AaveV3PreliquidationParamsInit {
bytes32 id;
address lendReserve;
address borrowReserve;
uint256 preLltv;
uint256 preCF1;
uint256 preCF2;
uint256 preIF1;
uint256 preIF2;
}
/**
* @notice Structure for Aave V3 preliquidation parameters
* @param lendReserve The address of the lend reserve
* @param borrowReserve The address of the borrow reserve
* @param Lltv The ltv
* @param preLltv The preliquidation ltv
* @param preCF1 The preliquidation c1
* @param preCF2 The preliquidation c2
* @param preIF1 The preliquidation i1
* @param preIF2 The preliquidation i2
*/
struct AaveV3PreliquidationParams {
address lendReserve;
address borrowReserve;
uint256 Lltv;
uint256 preLltv;
uint256 preCF1;
uint256 preCF2;
uint256 preIF1;
uint256 preIF2;
}
/**
* @notice Structure for Merkl claim parameters
* @param users The addresses of the users to claim rewards for
* @param tokens The addresses of the tokens to claim rewards for
* @param amounts The amounts of the tokens to claim rewards for
* @param proofs The proofs of the Merkle tree
*/
struct MerklClaimParams {
address[] users;
address[] tokens;
uint256[] amounts;
bytes32[][] proofs;
}
/**
* @notice Structure for vault action parameters
* @param vault The address of the vault
* @param amount The amount of the vault to supply
*/
struct VaultActionParams {
address vault;
uint256 amount;
}
/**
* @notice Structure for Morpho flashloan parameters
* @param asset The address of the asset to flashloan
* @param amount The amount to flashloan
* @param callbackExecutionData The data to execute in the flashloan callback
*/
struct MorphoFlashloanParams {
address asset;
uint256 amount;
bytes callbackExecutionData;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
/**
* @title IDepositManager
* @author Superlend
* @notice Interface for deposit manager operations
* @dev Handles deposit request creation and management
*/
interface IDepositManager {
/**
* @notice Creates a deposit request for the specified amount
* @param amount The amount of assets to deposit
* @param onBehalfOf The address to deposit on behalf of
*/
function requestDeposit(uint256 amount, address onBehalfOf) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC-20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (interfaces/IERC1363.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";
/**
* @title IERC1363
* @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
*
* Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
* after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
*/
interface IERC1363 is IERC20, IERC165 {
/*
* Note: the ERC-165 identifier for this interface is 0xb0202a11.
* 0xb0202a11 ===
* bytes4(keccak256('transferAndCall(address,uint256)')) ^
* bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
* bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
* bytes4(keccak256('approveAndCall(address,uint256)')) ^
* bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
*/
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
* and then calls {IERC1363Receiver-onTransferReceived} on `to`.
* @param from The address which you want to send tokens from.
* @param to The address which you want to transfer to.
* @param value The amount of tokens to be transferred.
* @param data Additional data with no specified format, sent in call to `to`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value) external returns (bool);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
* @param spender The address which will spend the funds.
* @param value The amount of tokens to be spent.
* @param data Additional data with no specified format, sent in call to `spender`.
* @return A boolean value indicating whether the operation succeeded unless throwing.
*/
function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../token/ERC20/IERC20.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../utils/introspection/IERC165.sol";// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"aave-v3-core/=lib/aave-v3-core/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"morpho-blue/=lib/morpho-blue/src/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"ds-test/=lib/morpho-blue/lib/forge-std/lib/ds-test/src/"
],
"optimizer": {
"enabled": true,
"runs": 10000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "prague",
"viaIR": true
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address[]","name":"_supportedVaults","type":"address[]"},{"internalType":"address[]","name":"_supportedTokens","type":"address[]"},{"internalType":"address","name":"_universalDexModule","type":"address"},{"internalType":"address[]","name":"_supportedDepositManagers","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"depositManager","type":"address"},{"indexed":false,"internalType":"bool","name":"isWhitelisted","type":"bool"}],"name":"DepositManagerWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"isWhitelisted","type":"bool"}],"name":"TokenWhitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":false,"internalType":"bool","name":"isWhitelisted","type":"bool"}],"name":"VaultWhitelisted","type":"event"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"address","name":"depositManager","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"enum DataTypes.DepositType","name":"depositType","type":"uint8"},{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"maxAmountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct DataTypes.ExecuteSwapParamsData[]","name":"data","type":"tuple[]"}],"internalType":"struct DataTypes.ExecuteSwapParams","name":"swapParams","type":"tuple"}],"name":"depositWithToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_universalDexModule","type":"address"}],"name":"setUniversalDexModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supportedDepositManagers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supportedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"supportedVaults","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"universalDexModule","outputs":[{"internalType":"contract IUniversalDexModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"depositManager","type":"address"},{"internalType":"bool","name":"isWhitelisted","type":"bool"}],"name":"whitelistDepositManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"isWhitelisted","type":"bool"}],"name":"whitelistToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"bool","name":"isWhitelisted","type":"bool"}],"name":"whitelistVault","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
6080604052346102875761161d803803806100198161028b565b9283398101906080818303126102875780516001600160401b03811161028757826100459183016102d8565b60208201516001600160401b03811161028757836100649184016102d8565b91610071604082016102c4565b60608201519094906001600160401b0381116102875761009192016102d8565b3315610274575f8054336001600160a01b0319821681178355916001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09080a35f5b8251811015610153576001906001600160a01b036100fb8286610342565b51165f528160205260405f208260ff19825416179055818060a01b036101218286610342565b51167f9652e0d255e1984241157f0e5f65c662604b493e181fde308bc5b66d116d63fe6020604051858152a2016100dd565b8482855f5b81518110156101cf576001906001600160a01b036101768285610342565b51165f52600260205260405f208260ff19825416179055818060a01b0361019d8285610342565b51167fef81a9943b96c8df4ef243401c9bf5159146166211356898b52d382086168d926020604051858152a201610158565b50505f5b815181101561024a576001906001600160a01b036101f18285610342565b51165f52600360205260405f208260ff19825416179055818060a01b036102188285610342565b51167fa97560bd93588927d79d92af36657c64b68481447620f4696e4fe9bf7ce2439a6020604051858152a2016101d3565b600480546001600160a01b0319166001600160a01b0385161790556040516112b2908161036b8239f35b631e4fbdf760e01b5f525f60045260245ffd5b5f80fd5b6040519190601f01601f191682016001600160401b038111838210176102b057604052565b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b038216820361028757565b9080601f83011215610287578151916001600160401b0383116102b0578260051b9060208061030881850161028b565b80968152019282010192831161028757602001905b82821061032a5750505090565b60208091610337846102c4565b81520191019061031d565b80518210156103565760209160051b010190565b634e487b7160e01b5f52603260045260245ffdfe60806040526004361015610011575f80fd5b5f3560e01c80630ffb1d8b1461076157806338fcfe7a146107175780634133f100146106b357806368c4ac2614610669578063715018a6146105ed578063750b1537146105ba5780638da5cb5b14610588578063b5c3d68d146104f7578063b71b73c3146104ad578063e0f8a1d21461020b578063e6e66c681461016f5763f2fde38b1461009d575f80fd5b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6100cb6107f2565b6100d3610f04565b16801561013f5773ffffffffffffffffffffffffffffffffffffffff5f54827fffffffffffffffffffffffff00000000000000000000000000000000000000008216175f55167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b7f1e4fbdf7000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b5f80fd5b3461016b5773ffffffffffffffffffffffffffffffffffffffff7f9652e0d255e1984241157f0e5f65c662604b493e181fde308bc5b66d116d63fe60206101b536610836565b93906101bf610f04565b1692835f52600182526102008160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6040519015158152a2005b3461016b5760c060031936011261016b576102246107f2565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361016b576044359073ffffffffffffffffffffffffffffffffffffffff8216820361016b5760843590600282101561016b5760a4359267ffffffffffffffff841161016b5760c0600319853603011261016b576040519360c0850185811067ffffffffffffffff821117610480576040526102be81600401610815565b85526102cc60248201610815565b602086015260448101356040860152606481013560608601526084810135608086015260a48101359067ffffffffffffffff821161016b5701943660238701121561016b57600486013567ffffffffffffffff8111610480578060051b966040519161033b60208a0184610872565b8252602082019781016024019036821161016b5760248101985b828a1061037457505050610372965060a08601526064359261094f565b005b893567ffffffffffffffff811161016b576004908301019060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0833603011261016b57604051916040830183811067ffffffffffffffff821117610480576040526103e260208201610815565b8352604081013567ffffffffffffffff811161016b5760209101019036601f8301121561016b5781359267ffffffffffffffff841161048057604051610450601f86017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200182610872565b848152366020868601011161016b575f602086819782809801838601378301015283820152815201990198610355565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6104db6107f2565b165f526001602052602060ff60405f2054166040519015158152f35b3461016b5773ffffffffffffffffffffffffffffffffffffffff7fa97560bd93588927d79d92af36657c64b68481447620f4696e4fe9bf7ce2439a602061053d36610836565b9390610547610f04565b1692835f52600382526102008160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b3461016b575f60031936011261016b57602073ffffffffffffffffffffffffffffffffffffffff5f5416604051908152f35b3461016b575f60031936011261016b57602073ffffffffffffffffffffffffffffffffffffffff60045416604051908152f35b3461016b575f60031936011261016b57610605610f04565b5f73ffffffffffffffffffffffffffffffffffffffff81547fffffffffffffffffffffffff000000000000000000000000000000000000000081168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6106976107f2565b165f526002602052602060ff60405f2054166040519015158152f35b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6106e16107f2565b6106e9610f04565b167fffffffffffffffffffffffff000000000000000000000000000000000000000060045416176004555f80f35b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6107456107f2565b165f526003602052602060ff60405f2054166040519015158152f35b3461016b5773ffffffffffffffffffffffffffffffffffffffff7fef81a9943b96c8df4ef243401c9bf5159146166211356898b52d382086168d9260206107a736610836565b93906107b1610f04565b1692835f52600282526102008160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361016b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361016b57565b600319604091011261016b5760043573ffffffffffffffffffffffffffffffffffffffff8116810361016b5790602435801515810361016b5790565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761048057604052565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602080948051918291828752018686015e5f8582860101520116010190565b156108fe5750565b61093c906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906108b3565b0390fd5b9081602091031261016b575190565b600492959373ffffffffffffffffffffffffffffffffffffffff821696875f52600160205260ff60405f205416916109bf6040938451906109908683610872565b600282527f333100000000000000000000000000000000000000000000000000000000000060208301526108f6565b602073ffffffffffffffffffffffffffffffffffffffff8316998a5f5260028252610a2560ff865f2054168651906109f78883610872565b600282527f3332000000000000000000000000000000000000000000000000000000000000858301526108f6565b73ffffffffffffffffffffffffffffffffffffffff87165f5260038252610a8760ff865f205416865190610a598883610872565b600282527f3439000000000000000000000000000000000000000000000000000000000000858301526108f6565b8451978880927f38d52e0f0000000000000000000000000000000000000000000000000000000082525afa958615610dac575f96610eb3575b508251917f70a082310000000000000000000000000000000000000000000000000000000083523060048401526020836024818d5afa928315610ea9575f93610e75575b50610b5784517f23b872dd00000000000000000000000000000000000000000000000000000000602082015233602482015230604482015283606482015260648152610b51608482610872565b8b6111f5565b8973ffffffffffffffffffffffffffffffffffffffff881614610e655750610b989073ffffffffffffffffffffffffffffffffffffffff600454168a6110db565b73ffffffffffffffffffffffffffffffffffffffff60045416825180977f29adffad00000000000000000000000000000000000000000000000000000000825284600483015260a061010483019173ffffffffffffffffffffffffffffffffffffffff815116604485015273ffffffffffffffffffffffffffffffffffffffff6020820151166064850152868101516084850152606081015160a4850152608081015160c485015201519060c060e4840152815180915261012483019060206101248260051b8601019301915f905b828210610df4575050505091815f8160209530602483015203925af1958615610dea575f96610db6575b508151977f70a082310000000000000000000000000000000000000000000000000000000089523060048a0152602089602481845afa988915610dac575f99610d78575b5081890391898311610d4b57610cf39903610cf5575b505050610f50565b565b91517fa9059cbb000000000000000000000000000000000000000000000000000000006020820152336024820152604480820192909252908152610d4391610d3e606483610872565b6111f5565b5f8080610ceb565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b9098506020813d602011610da4575b81610d9460209383610872565b8101031261016b5751975f610cd5565b3d9150610d87565b83513d5f823e3d90fd5b9095506020813d602011610de2575b81610dd260209383610872565b8101031261016b5751945f610c91565b3d9150610dc5565b82513d5f823e3d90fd5b91936020610e55827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedc60019597998495030186528b838a5173ffffffffffffffffffffffffffffffffffffffff8151168452015191818582015201906108b3565b9601920192018b94939192610c67565b955095505050610cf39550610f50565b9092506020813d602011610ea1575b81610e9160209383610872565b8101031261016b5751915f610b04565b3d9150610e84565b84513d5f823e3d90fd5b9095506020813d602011610efc575b81610ecf60209383610872565b8101031261016b575173ffffffffffffffffffffffffffffffffffffffff8116810361016b57945f610ac0565b3d9150610ec2565b73ffffffffffffffffffffffffffffffffffffffff5f54163303610f2457565b7f118cdaa7000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b91909392935f9360028110156110ae5761101d57508184610f8e73ffffffffffffffffffffffffffffffffffffffff9660209588610fd296166110db565b6040517f6e553f6500000000000000000000000000000000000000000000000000000000815260048101919091523360248201529485928391869183906044820190565b0393165af19081156110115750610fe65750565b6110079060203d60201161100a575b610fff8183610872565b810190610940565b50565b503d610ff5565b604051903d90823e3d90fd5b915073ffffffffffffffffffffffffffffffffffffffff925083828461104393166110db565b16803b1561016b576040517f29344f0800000000000000000000000000000000000000000000000000000000815260048101929092523360248301525f908290604490829084905af180156110a3576110995750565b5f610cf391610872565b6040513d5f823e3d90fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6040517f095ea7b300000000000000000000000000000000000000000000000000000000602080830191825273ffffffffffffffffffffffffffffffffffffffff85166024840152604480840196909652948252929390925f90611140606486610872565b84519082855af15f513d826111c3575b50501561115c57505050565b610d3e610cf39373ffffffffffffffffffffffffffffffffffffffff604051917f095ea7b30000000000000000000000000000000000000000000000000000000060208401521660248201525f6044820152604481526111bd606482610872565b826111f5565b9091506111ed575073ffffffffffffffffffffffffffffffffffffffff81163b15155b5f80611150565b6001146111e6565b905f602091828151910182855af1156110a3575f513d611273575073ffffffffffffffffffffffffffffffffffffffff81163b155b6112315750565b73ffffffffffffffffffffffffffffffffffffffff907f5274afe7000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b6001141561122a56fea26469706673582212203d9c4b6eebcc8ce872cc1748f924bf0bb16c1dec35b38534d4d46a9a637f7c3664736f6c634300081b0033000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000004c582a0d5552a906c48d9ba647519570c69ba09500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b402e0479579b00f9dafc0526234bbc4583920b400000000000000000000000000000000000000000000000000000000000000030000000000000000000000004c9edd5852cd905f086c759e8383e09bff1e68b3000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000000000010000000000000000000000001eda32cec481f92e99fea8bf74a9c98c589d498d
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c80630ffb1d8b1461076157806338fcfe7a146107175780634133f100146106b357806368c4ac2614610669578063715018a6146105ed578063750b1537146105ba5780638da5cb5b14610588578063b5c3d68d146104f7578063b71b73c3146104ad578063e0f8a1d21461020b578063e6e66c681461016f5763f2fde38b1461009d575f80fd5b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6100cb6107f2565b6100d3610f04565b16801561013f5773ffffffffffffffffffffffffffffffffffffffff5f54827fffffffffffffffffffffffff00000000000000000000000000000000000000008216175f55167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3005b7f1e4fbdf7000000000000000000000000000000000000000000000000000000005f525f60045260245ffd5b5f80fd5b3461016b5773ffffffffffffffffffffffffffffffffffffffff7f9652e0d255e1984241157f0e5f65c662604b493e181fde308bc5b66d116d63fe60206101b536610836565b93906101bf610f04565b1692835f52600182526102008160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6040519015158152a2005b3461016b5760c060031936011261016b576102246107f2565b6024359073ffffffffffffffffffffffffffffffffffffffff8216820361016b576044359073ffffffffffffffffffffffffffffffffffffffff8216820361016b5760843590600282101561016b5760a4359267ffffffffffffffff841161016b5760c0600319853603011261016b576040519360c0850185811067ffffffffffffffff821117610480576040526102be81600401610815565b85526102cc60248201610815565b602086015260448101356040860152606481013560608601526084810135608086015260a48101359067ffffffffffffffff821161016b5701943660238701121561016b57600486013567ffffffffffffffff8111610480578060051b966040519161033b60208a0184610872565b8252602082019781016024019036821161016b5760248101985b828a1061037457505050610372965060a08601526064359261094f565b005b893567ffffffffffffffff811161016b576004908301019060407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0833603011261016b57604051916040830183811067ffffffffffffffff821117610480576040526103e260208201610815565b8352604081013567ffffffffffffffff811161016b5760209101019036601f8301121561016b5781359267ffffffffffffffff841161048057604051610450601f86017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200182610872565b848152366020868601011161016b575f602086819782809801838601378301015283820152815201990198610355565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6104db6107f2565b165f526001602052602060ff60405f2054166040519015158152f35b3461016b5773ffffffffffffffffffffffffffffffffffffffff7fa97560bd93588927d79d92af36657c64b68481447620f4696e4fe9bf7ce2439a602061053d36610836565b9390610547610f04565b1692835f52600382526102008160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b3461016b575f60031936011261016b57602073ffffffffffffffffffffffffffffffffffffffff5f5416604051908152f35b3461016b575f60031936011261016b57602073ffffffffffffffffffffffffffffffffffffffff60045416604051908152f35b3461016b575f60031936011261016b57610605610f04565b5f73ffffffffffffffffffffffffffffffffffffffff81547fffffffffffffffffffffffff000000000000000000000000000000000000000081168355167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6106976107f2565b165f526002602052602060ff60405f2054166040519015158152f35b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6106e16107f2565b6106e9610f04565b167fffffffffffffffffffffffff000000000000000000000000000000000000000060045416176004555f80f35b3461016b57602060031936011261016b5773ffffffffffffffffffffffffffffffffffffffff6107456107f2565b165f526003602052602060ff60405f2054166040519015158152f35b3461016b5773ffffffffffffffffffffffffffffffffffffffff7fef81a9943b96c8df4ef243401c9bf5159146166211356898b52d382086168d9260206107a736610836565b93906107b1610f04565b1692835f52600282526102008160405f209060ff7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0083541691151516179055565b6004359073ffffffffffffffffffffffffffffffffffffffff8216820361016b57565b359073ffffffffffffffffffffffffffffffffffffffff8216820361016b57565b600319604091011261016b5760043573ffffffffffffffffffffffffffffffffffffffff8116810361016b5790602435801515810361016b5790565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761048057604052565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602080948051918291828752018686015e5f8582860101520116010190565b156108fe5750565b61093c906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906108b3565b0390fd5b9081602091031261016b575190565b600492959373ffffffffffffffffffffffffffffffffffffffff821696875f52600160205260ff60405f205416916109bf6040938451906109908683610872565b600282527f333100000000000000000000000000000000000000000000000000000000000060208301526108f6565b602073ffffffffffffffffffffffffffffffffffffffff8316998a5f5260028252610a2560ff865f2054168651906109f78883610872565b600282527f3332000000000000000000000000000000000000000000000000000000000000858301526108f6565b73ffffffffffffffffffffffffffffffffffffffff87165f5260038252610a8760ff865f205416865190610a598883610872565b600282527f3439000000000000000000000000000000000000000000000000000000000000858301526108f6565b8451978880927f38d52e0f0000000000000000000000000000000000000000000000000000000082525afa958615610dac575f96610eb3575b508251917f70a082310000000000000000000000000000000000000000000000000000000083523060048401526020836024818d5afa928315610ea9575f93610e75575b50610b5784517f23b872dd00000000000000000000000000000000000000000000000000000000602082015233602482015230604482015283606482015260648152610b51608482610872565b8b6111f5565b8973ffffffffffffffffffffffffffffffffffffffff881614610e655750610b989073ffffffffffffffffffffffffffffffffffffffff600454168a6110db565b73ffffffffffffffffffffffffffffffffffffffff60045416825180977f29adffad00000000000000000000000000000000000000000000000000000000825284600483015260a061010483019173ffffffffffffffffffffffffffffffffffffffff815116604485015273ffffffffffffffffffffffffffffffffffffffff6020820151166064850152868101516084850152606081015160a4850152608081015160c485015201519060c060e4840152815180915261012483019060206101248260051b8601019301915f905b828210610df4575050505091815f8160209530602483015203925af1958615610dea575f96610db6575b508151977f70a082310000000000000000000000000000000000000000000000000000000089523060048a0152602089602481845afa988915610dac575f99610d78575b5081890391898311610d4b57610cf39903610cf5575b505050610f50565b565b91517fa9059cbb000000000000000000000000000000000000000000000000000000006020820152336024820152604480820192909252908152610d4391610d3e606483610872565b6111f5565b5f8080610ceb565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b9098506020813d602011610da4575b81610d9460209383610872565b8101031261016b5751975f610cd5565b3d9150610d87565b83513d5f823e3d90fd5b9095506020813d602011610de2575b81610dd260209383610872565b8101031261016b5751945f610c91565b3d9150610dc5565b82513d5f823e3d90fd5b91936020610e55827ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffedc60019597998495030186528b838a5173ffffffffffffffffffffffffffffffffffffffff8151168452015191818582015201906108b3565b9601920192018b94939192610c67565b955095505050610cf39550610f50565b9092506020813d602011610ea1575b81610e9160209383610872565b8101031261016b5751915f610b04565b3d9150610e84565b84513d5f823e3d90fd5b9095506020813d602011610efc575b81610ecf60209383610872565b8101031261016b575173ffffffffffffffffffffffffffffffffffffffff8116810361016b57945f610ac0565b3d9150610ec2565b73ffffffffffffffffffffffffffffffffffffffff5f54163303610f2457565b7f118cdaa7000000000000000000000000000000000000000000000000000000005f523360045260245ffd5b91909392935f9360028110156110ae5761101d57508184610f8e73ffffffffffffffffffffffffffffffffffffffff9660209588610fd296166110db565b6040517f6e553f6500000000000000000000000000000000000000000000000000000000815260048101919091523360248201529485928391869183906044820190565b0393165af19081156110115750610fe65750565b6110079060203d60201161100a575b610fff8183610872565b810190610940565b50565b503d610ff5565b604051903d90823e3d90fd5b915073ffffffffffffffffffffffffffffffffffffffff925083828461104393166110db565b16803b1561016b576040517f29344f0800000000000000000000000000000000000000000000000000000000815260048101929092523360248301525f908290604490829084905af180156110a3576110995750565b5f610cf391610872565b6040513d5f823e3d90fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b6040517f095ea7b300000000000000000000000000000000000000000000000000000000602080830191825273ffffffffffffffffffffffffffffffffffffffff85166024840152604480840196909652948252929390925f90611140606486610872565b84519082855af15f513d826111c3575b50501561115c57505050565b610d3e610cf39373ffffffffffffffffffffffffffffffffffffffff604051917f095ea7b30000000000000000000000000000000000000000000000000000000060208401521660248201525f6044820152604481526111bd606482610872565b826111f5565b9091506111ed575073ffffffffffffffffffffffffffffffffffffffff81163b15155b5f80611150565b6001146111e6565b905f602091828151910182855af1156110a3575f513d611273575073ffffffffffffffffffffffffffffffffffffffff81163b155b6112315750565b73ffffffffffffffffffffffffffffffffffffffff907f5274afe7000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b6001141561122a56fea26469706673582212203d9c4b6eebcc8ce872cc1748f924bf0bb16c1dec35b38534d4d46a9a637f7c3664736f6c634300081b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000004c582a0d5552a906c48d9ba647519570c69ba09500000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000b402e0479579b00f9dafc0526234bbc4583920b400000000000000000000000000000000000000000000000000000000000000030000000000000000000000004c9edd5852cd905f086c759e8383e09bff1e68b3000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec700000000000000000000000000000000000000000000000000000000000000010000000000000000000000001eda32cec481f92e99fea8bf74a9c98c589d498d
-----Decoded View---------------
Arg [0] : _supportedVaults (address[]): 0xB402e0479579b00f9DAfc0526234BBC4583920B4
Arg [1] : _supportedTokens (address[]): 0x4c9EDD5852cd905f086C759E8383e09bff1E68B3,0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48,0xdAC17F958D2ee523a2206206994597C13D831ec7
Arg [2] : _universalDexModule (address): 0x4c582A0d5552a906C48D9ba647519570C69bA095
Arg [3] : _supportedDepositManagers (address[]): 0x1EDA32cec481f92E99fEa8bf74A9c98C589d498d
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [2] : 0000000000000000000000004c582a0d5552a906c48d9ba647519570c69ba095
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 000000000000000000000000b402e0479579b00f9dafc0526234bbc4583920b4
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [7] : 0000000000000000000000004c9edd5852cd905f086c759e8383e09bff1e68b3
Arg [8] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [9] : 000000000000000000000000dac17f958d2ee523a2206206994597c13d831ec7
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [11] : 0000000000000000000000001eda32cec481f92e99fea8bf74a9c98c589d498d
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.