Overview
The Euler Vault Kit (EVK) is a system for constructing credit vaults - ERC-4626 vaults with added borrowing functionality. Unlike typical ERC-4626 vaults which earn yield by actively investing deposited funds, credit vaults are passive lending pools. Users can borrow from a credit vault as long as they have sufficient collateral deposited in other credit vaults. The liability vault (the one that was borrowed from) decides which credit vaults are acceptable as collateral.
Key Components
Vault Architecture
A vault consists of several components:
- Underlying Asset: The ERC-20 token held by the vault. Each vault holds exactly one underlying asset.
- EVault: The primary entry-point contract implementing common vault logic:
- Tracks deposits and borrows
- Accures interest rate
- Validates position health
- Permits liquidations
- Price Oracle: Interfaces with external pricing systems to compute collateral and liability values
- IRM (Interest Rate Model): Computes interest rates to incentivize borrowing behavior
- ProtocolConfig: Global protocol-level configuration controlling interest fee destinations and splits
- Hook Target: Optional contract that can implement custom logic for vault operations through hooks
- DToken: A read-only ERC-20 interface for debt amounts, making debt modifications visible in block explorers and trackable by tax-accounting software
Vault Creation and Governance
Vaults are created through a factory contract, which deploys a proxy pointing to the implementation contract. This pattern enables gas-efficient deployment, ensures code provenance and trust in vault code through factory. After creation, vaults can be either governed, where the creator retains or transfers governance rights, or finalized, where governance is revoked by setting governor to address(0)
.
Upgradeability vs Immutability
When creating a vault, a boolean upgradeable
flag is specified:
- If
upgradeable
is true, the factory creates a beacon proxy, allowing the factory admin to upgrade the vault's implementation - If
upgradeable
is false, the factory creates a minimal proxy contract, making the vault immutable
The factory has an upgradeAdmin
address controlled by Euler DAO that can change the implementation, but this only affects upgradeable vaults. This allows vault creators to choose whether they want the factory admin to be able to upgrade their vaults, or if they should be immutable. The upgrade functionality will only be used in case of a critical bug discovered in the vault implementation.
Governance Risk
The combination of upgradeability and governance creates different risk profiles:
Upgradeable | Immutable | |
---|---|---|
Governed | Factory Admin + Governor | Governor |
Finalized | Factory Admin | None |
Note that immutable/finalized vaults also carry risks:
- If market conditions change making a collateral asset or price oracle unsafe, only governed vaults can be reconfigured
- If critical bugs are found in the Vault Kit code, only upgradeable vaults can be fixed
Core Functionality
Exchange Rate and Shares
Vaults implement the ERC-4626 standard, where shares represent proportional claims on vault assets. The exchange rate grows as interest accrues, and shares maintain the same decimals as the underlying asset. The exchange rate is calculated as:
exchangeRate = (cash + totalBorrows + VIRTUAL_DEPOSIT) / (totalShares + VIRTUAL_DEPOSIT)
The virtual deposit mechanism prevents manipulation through rounding-based "stealth deposits" and ensures the exchange rate is well-defined even with zero shares.
Token Transfers
Vaults use two internal abstractions for token movements:
pullAssets
: First attempts to use Permit2 for gasless approvals, then falls back to the underlying assettransferFrom
pushAssets
: Usestransfer
on the underlying asset, with checks to prevent transfers to virtual sub-accounts
Permit2 enables better user experiences by allowing approvals to be created as signed messages bundled into the same EVC batch as operations like deposit
. While users need to approve the Permit2 contract once, many will already have done this when interacting with Uniswap or other apps.
With the advent of EIP-7702, the need for Permit2 is reduced, as EIP-7702 allows approvals to be seamlessly bundled with transactions in a more native way. However, not all networks support EIP-7702 yet, and many wallets are still catching up. As a result, Permit2 remains an important tool for ensuring smooth user experiences across different environments and wallet implementations.
Internal Balance Tracking
The vault uses internal balance tracking instead of reading its own balance from the underlying asset. This prevents users from manipulating the exchange rate through direct transfers and is more gas efficient. However, this means that rebasing/fee-on-transfer tokens are not supported, as the vault cannot track unexpected balance changes.
Balance Forwarding
Balance forwarding enables instant and trustless distribution of rewards while keeping gas costs low. When an account opts in, every time its balance changes an external contract is notified of the updated balance. This external contract has no special privileges in the vault but must ensure its balanceTrackerHook
method doesn't revert or use up all gas.
The default implementation for the balance forwarding contract is Reward Streams, which allows anyone to permissionlessly incentivize any vault with any token at any time.
Interest Rate Models and Compounding
Interest Rate Models (IRMs) determine the interest rate based on the vault's state, typically using a function of utilization. The most common function is a "linear-kink" model that starts with a gradual slope and becomes steep at a target utilization value.
Interest is compounded deterministically every second using exponentiation. Because accrued interest is added to totalBorrows
, it increases utilization. The amount of interest owed/earned is independent of how frequently the contract is interacted with, except for the effect of accumulator rounding.
IRMs return interest rates in terms of "second percent yield" (SPY) values, which are per-second compounded interest rates scaled by 1e27
. For consistency, conversion to annualized equivalents should use the number of seconds in the average Gregorian calendar year (365.2425 days).
Fees
When interest is accrued, a portion is allocated to fees, controlled by the governor as the parameter interestFee
. The fees are charged by creating shares that dilute depositors by the interestFee
fraction of the interest. Since fees are denominated in vault shares, unwithdrawn fees themselves earn compound interest over time.
The ProtocolConfig
contract determines the fee share between the vault governor and the Euler DAO. The fee share can be changed at any time, but the portion sent to the Euler DAO is not finalized until convertFees
is invoked.
Supply and Borrow Caps
Vault governors can configure:
- Supply cap: Limit on the amount of underlying assets that can be deposited
- Borrow cap: Limit on the amount that can be borrowed
Both caps are denominated in the underlying asset and are packed into 2-byte decimal floating point values. Caps can be transiently violated since they are only enforced at the end of a batch. If a cap was not in violation at the start of a batch but is at the end, the transaction will be reverted.
DToken (Debt Token)
Vaults provide a read-only ERC-20 interface for debts through the DToken contract. This interface tracks debt modifications through Transfer events and supports off-chain analysis and tax accounting. The DToken contract is the first (and only) contract created by EVault, so its address can be calculated from the vault's address and the nonce 1
.
Sub-Accounts
The EVC provides each user with 256 virtual account addresses (sub-accounts) that are entirely isolated from one another. This powerful feature enables users to manage multiple positions with different risk parameters while maintaining the convenience of using a single wallet.
How Sub-Accounts Work
In the EVC, every Ethereum address is associated with 256 accounts, which includes the primary account (referred to as the owner). These accounts are identified by IDs ranging from 0 to 255, with ID 0 specifically assigned to the owner account. To generate sub-account addresses, the system performs an XOR operation between the account ID and the Ethereum address. Additionally, the EVC keeps track of sub-account ownership through a look-up mapping called ownerLookup
, which helps resolve sub-accounts back to their respective owner addresses.
Important Considerations
- Sub-account addresses are internal to the EVC and compatible vaults
- Never use sub-accounts for regular ERC20 token transfers or external contract interactions
- The EVC maintains a look-up mapping to resolve sub-accounts to their owner addresses
- Sub-accounts are the only way an account can hold multiple Vault borrows concurrently in the EVK
Risk Management
Health Checks
Vaults implement two critical health check methods:
checkAccountStatus
: Verifies account solvencycheckVaultStatus
: Ensures vault-level limits are respected
These methods are invoked by the EVC at appropriate times, typically after all operations in a batch have been performed.
LTV (Loan-to-Value)
Each collateral vault is configured with an LTV that determines the maximum borrow amount against collateral. The system supports separate borrowing and liquidation LTVs. The borrowing LTV is used to limit new borrows, while the liquidation LTV is used when liquidating existing positions. This gap helps compensate for pricing delays and uncertainty, requiring larger price movements to get liquidated right after the position was created. The liquidation LTV can be smoothly ramped down by the vault governor when a collateral needs to be phased out.
Liquidations
When an account's risk-adjusted collateral value reaches or falls below its liability value, the account becomes eligible for liquidation. The liquidation system uses a reverse dutch auction mechanism that scales the discount proportionally with how deeply in violation the position is. This ensures that:
- Slightly unhealthy positions may not be profitable to liquidate
- As prices move against the position, the discount increases
- At some level, a bot will detect that liquidation is profitable and execute it
The liquidation discount is limited by a maximum liquidation discount parameter that vault creators must set appropriately. The discount is proportional to how unhealthy the user is, which means that in some cases, a liquidator may improve their total yield by performing many small liquidations rather than one large liquidation.
Bad Debt Socialization
When enabled, bad debt socialization cancels uncollateralized debt and socializes the loss to all depositors, preventing bank-run scenarios. Vault governors who don't want debt socialization can disable this functionality.
Advanced Features
Hooks System
The hooks system provides vault governors with flexible control over vault operations. It can be used to pause specific operations, implement custom restrictions (such as KYC requirements), add flash loan fees, enforce utilization caps, and set minimum debt sizes. The hook system allows vault governors to disable functionality either permanently or under certain conditions, without breaking core accounting invariants.
For a full technical reference, see the EVK whitepaper or the EVK repository.