The Vault is a contract for storing and transferring funds for liquidity pools. It is designed to support internal transfers between liquidity pools to reduce gas costs and potential transfer taxes.
The Vault supports deposit, withdrawal, and transfers with native ETH and ERC20 tokens. Additionally, the Vault has integrated the flash loan feature.
wETH
The vault integrates wETH by nature. All wETH deposits will be immediately unwrapped to native ETH and will wrap ETH on withdrawing wETH. The reserve and balance of wETH and ETH are the same value.
For native ETH, the vault uses the zero address as its address placeholder.
You can use the following functions to get the wETH address.
Copy
// Returns address of the wETH contract.
function wETH() external view returns (address);
Balance
You can use the following functions to get the token balance of an account in the vault. The balance of wETH and ETH is the same value.
Copy
// Returns token balance of the owner.
// Use `address(0)` or wETH address for ETH balance.
function balanceOf(address token, address owner) external view returns (uint balance);
Reserve
The reserve is the total amount of specific token in the vault since the token's last event (deposit, transfer, or withdraw).
You can use the following functions to query the reserve of a token.
Copy
// Returns reserve of the token. Use `address(0)` or wETH address for ETH.
function reserves(address token) external view returns (uint);
Deposit
By depositing to the vault, the corresponding token balance of the account will be increased. All wETH deposits will be immediately unwrapped to native ETH.
You can use the following functions to deposit.
Copy
// Deposit ETH or ERC20 tokens with recipient.
// Use `address(0)` as `token` with value to deposit native ETH.
// Returns `msg.value` for ETH and actual amount received for ERC20 tokens.
function deposit(address token, address to) public payable returns (uint amount);
// Deposit ETH with recipient, returns `msg.value`.
function depositETH(address to) external payable returns (uint amount);
// Transfer ERC20 tokens of given amount from `msg.sender` and deposit with recipient.
// This requires pre-approval of the ERC20 token.
// This function also supports ETH deposit, use `address(0)` as `token` for ETH.
// For ETH deposits, `amount` must match `msg.value`.
// Returns `msg.value` for ETH and actual amount received for ERC20 tokens.
function transferAndDeposit(address token, address to, uint amount) external payable returns (uint);
Transfer
The vault transfer allows moving balances between accounts without actually transferring the token to reduce gas costs or avoid transfer taxes.
You can use the following functions to transfer.
Copy
// Transfer ETH or ERC20 tokens to recipient.
// Use `address(0)` or wETH address for ETH.
function transfer(address token, address to, uint amount) external;
Withdraw
By withdrawing, the account's balance will be decreased, and the underlying assets will be transferred out.
You can use the following functions to withdraw.
Copy
// Withdraw ETH or ERC20 tokens to recipient.
// Use `address(0)` to withdraw native ETH, and use the wETH address to withdraw wETH.
function withdraw(address token, address to, uint amount) external;
// Withdraw ETH or ERC20 tokens to recipient with mode.
// The mode has no effects for ERC20 tokens, and is only for ETH/wETH.
// Supported modes:
// `0` - default behavior, withdraw native ETH when the `token` is `address(0)`, and wETH when `token` is the wETH.
// `1` - unwrapped, always withdraw native ETH.
// `2` - wrapped, always withdraw wETH.
function withdrawAlternative(address token, address to, uint amount, uint8 mode) external;
// Withdraw some native ETH to recipient.
function withdrawETH(address to, uint amount) external;
Interface
Copy
interface IVault is IFlashLoan {
function wETH() external view returns (address);
function reserves(address token) external view returns (uint reserve);
function balanceOf(address token, address owner) external view returns (uint balance);
function deposit(address token, address to) external payable returns (uint amount);
function depositETH(address to) external payable returns (uint amount);
function transferAndDeposit(address token, address to, uint amount) external payable;
function transfer(address token, address to, uint amount) external;
function withdraw(address token, address to, uint amount) external;
function withdrawAlternative(address token, address to, uint amount, uint8 mode) external;
function withdrawETH(address to, uint amount) external;
}
interface IFlashLoan {
// Balancer style multiple flashloan
/**
* @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it,
* and then reverting unless the tokens plus a proportional protocol fee have been returned.
*
* The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount
* for each token contract. `tokens` must be sorted in ascending order.
*
* The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the
* `receiveFlashLoan` call.
*
* Emits `FlashLoan` events.
*/
function flashLoanMultiple(
IFlashLoanRecipient recipient,
address[] memory tokens,
uint[] memory amounts,
bytes memory userData
) external;
// EIP-3156 style flashloan
/**
* @dev The amount of currency available to be lent.
* @param token The loan currency.
* @return The amount of `token` that can be borrowed.
*/
// Returns `IERC20(token).balanceOf(address(this))`
function maxFlashLoan(address token) external view returns (uint256);
/**
* @dev The fee to be charged for a given loan.
* @param amount The amount of tokens lent.
* @return The amount of `token` to be charged for the loan, on top of the returned principal.
*/
// Returns `amount * flashLoanFeePercentage / 1e18`
function flashFee(address token, uint256 amount) external view returns (uint256);
/**
* @dev Initiate a flash loan.
* @param receiver The receiver of the tokens in the loan, and the receiver of the callback.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param userData Arbitrary data structure, intended to contain user-defined parameters.
*/
function flashLoan(
IERC3156FlashBorrower receiver,
address token,
uint amount,
bytes memory userData
) external returns (bool);
// The fee percentage is in 18 decimals.
// Fees will be applied to the surplus balance (postLoanBalance - preLoanBalance).
function flashLoanFeePercentage() external view returns (uint);
/**
* @dev Emitted for each individual flash loan performed by `flashLoan`.
*/
event FlashLoan(IFlashLoanRecipient indexed recipient, address indexed token, uint amount, uint feeAmount);
}
// Callback for multiple flashloan
interface IFlashLoanRecipient {
/**
* @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient.
*
* At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this
* call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the
* Vault, or else the entire flash loan will revert.
*
* `userData` is the same value passed in the `IVault.flashLoan` call.
*/
function receiveFlashLoan(
address[] memory tokens,
uint[] memory amounts,
uint[] memory feeAmounts,
bytes memory userData
) external;
}
// Callback for ERC3156 flashloan
interface IERC3156FlashBorrower {
/**
* @dev Receive a flash loan.
* @param initiator The initiator of the loan.
* @param token The loan currency.
* @param amount The amount of tokens lent.
* @param fee The additional amount of tokens to repay.
* @param data Arbitrary data structure, intended to contain user-defined parameters.
* @return The keccak256 hash of "ERC3156FlashBorrower.onFlashLoan"
*/
function onFlashLoan(
address initiator,
address token,
uint256 amount,
uint256 fee,
bytes calldata data
) external returns (bytes32);
}