A modular, upgradeable ERC4626 vault system that enables flexible asset management through multiple investment strategies.
Very Liquid Vault is a "meta" vault that allows users to deposit assets and have them automatically allocated across multiple investment strategies. The system is built with upgradeability and modularity in mind, featuring role-based access control and comprehensive strategy management. The design is influenced by yearn's yVaults v3.
- ERC4626 property tests from A16Z, Trail of Bits' Crytic, and Runtime Verification
- OpenZeppelin's implementation with decimals offset (A Novel Defense Against ERC4626 Inflation Attacks)
- First deposit during deployment with dead shares, pioneered by the Morpho Optimizer
- Timelock for sensitive operations using OpenZeppelin's TimelockController
- Invariant tests for a list of system properties
| Date | Version | Auditor | Report |
|---|---|---|---|
| 2025-09-11 | v0.1.0 | Open Zeppelin | Report |
| 2025-07-26 | v0.0.1 | Obsidian Audits | Report |
For bug reports, please refer to our Bug Bounty Program
| Contract | Address |
|---|---|
| TimelockController (DEFAULT_ADMIN_ROLE) | 0x220d1165798AC86BD70D987aDfc9E5FF8A317363 |
| TimelockController (VAULT_MANAGER_ROLE) | 0xcDB5eC52Cc326711461f93909d767E31fCfF7A1e |
| Auth | 0xB5294A791c37DFdc2228FACEd7dCE8EFCEb14B84 |
| CashStrategyVault | 0x096A1e4176ca516Bced19B15903EaB4654f7ee7A |
| AaveStrategyVault | 0x30c37256cD4DbaC733D815ae520F94A9aDAff579 |
| ERC4626StrategyVault (Morpho/Steakhouse) | 0x0860b5C685a7985789251f54524c49d71D56d10D |
| ERC4626StrategyVault (Euler/Prime Gauntlet) | 0x2ae61A7463667503Ab530b17B387A448B0471bcC |
| ERC4626StrategyVault (Euler/Yield Gauntlet) | 0xd72d29287503ccDa5bd9131baA8D96df436dcdf0 |
| ERC4626StrategyVault (Morpho/Smokehouse) | 0x23de7fC5C9dc55B076558E6Be0cfA7755Bb5F38b |
| ERC4626StrategyVault (Morpho/MEV Capital) | 0xc266c2544B768D94b627d66060E2662533a1Dee3 |
| VeryLiquidVault (Core) | 0x3AdF08AFe804691cA6d76742367cc50A24a1F4A1 |
| VeryLiquidVault (Frontier) | 0x13dDa6fD149a4Da0f2012F16e70925586ee603b8 |
| Contract | Address |
|---|---|
| TimelockController (DEFAULT_ADMIN_ROLE) | 0x220d1165798AC86BD70D987aDfc9E5FF8A317363 |
| TimelockController (VAULT_MANAGER_ROLE) | 0xcDB5eC52Cc326711461f93909d767E31fCfF7A1e |
| Auth | 0xB5294A791c37DFdc2228FACEd7dCE8EFCEb14B84 |
| CashStrategyVault | 0xe822Cb00dd72a2278F623b82D0234b15241bcFD9 |
| AaveStrategyVault | 0x63954A96A4e77A96cf78C3A4959c45123cdA5de1 |
| ERC4626StrategyVault (Morpho/Spark) | 0x930D8350ff644114d9fc29D820228ACd0cC719ed |
| ERC4626StrategyVault (Morpho/Gauntlet Prime) | 0x40AEb7c4c392f90b37E0ff0caC005FA7804653Ec |
| ERC4626StrategyVault (Morpho/Moonwell Flagship) | 0xddED8eaB321803a3c2e836cAADD54339f4CDD5d1 |
| ERC4626StrategyVault (Morpho/Steakhouse) | 0x5a33c8517f4DDD3939a87fEAaaAaF570a542D2aD |
| VeryLiquidVault (Core) | 0xf4D43A8570Dad86595fc079c633927aa936264F4 |
- ERC-4626 Compliance: Standard vault interface for seamless DeFi integration
- Multi-Strategy Architecture: Support for multiple investment strategies with dynamic allocation
- Upgradeable Design: Built with OpenZeppelin's UUPS upgradeable contracts pattern
- ERC-7201: Namespaced Storage Layout to facilitate inheritance and upgradeability
- Role-Based Access Control: Granular permissions for different system operations
- Strategy Rebalancing: Manual fund movement between strategies by Strategist
- Deposit/Withdrawal Priority Logic: Configurable priority list for liquidity deposit/withdrawals
- Flexible Strategy Integration: Easily add or remove ERC4626-compatible strategies
- Pause Functionality: Emergency stop mechanisms for enhanced security
- Total Asset Caps: Maximum asset limits for each strategy and very liquid
- Performance Fees: Performance fee is minted as shares if the overall vault tokens have an appreciated price beyond the previous high water mark
- Supports allocation across:
- Cash
- Aave
- Morpho/Euler
- Liquidity is fungible: all users share average yield
- Default deposit destination is Cash for instant liquidity (as defined by the strategist)
- Strategist-defined deposit/withdrawal priority
- Allocation is manually managed by a Strategist
- Percentage allocations are defined off-chain, e.g., 10% Cash, 30% Aave, 30% Euler, 30% Morpho
- Strategist uses e.g.
rebalanceto move liquidity between strategies
VeryLiquidVault: Main vault contract that manages user deposits and strategy allocationAuth: Centralized role-based access control system with global pause functionality
CashStrategyVault: Simple cash-holding strategy (no yield generation)AaveStrategyVault: Aave lending protocol integration for yield generationERC4626StrategyVault: Generic wrapper for other ERC4626 vaults (e.g., Morpho). Only ERC-4626 vaults passing the integration checklist will be considered.
| Role | Timelock | Actions |
|---------------------|----------|---------------------------------------------------------------------------|
| DEFAULT_ADMIN_ROLE | 7d | upgrade, grantRole, revokeRole, setPerformanceFeePercent, setFeeRecipient |
| VAULT_MANAGER_ROLE | 1d | unpause, addStrategy, setTotalAssetsCap, setRebalanceMaxSlippagePercent |
| STRATEGIST_ROLE | 0 | rebalance, reorderStrategies |
| GUARDIAN_ROLE | 0 | cancel timelock proposals, pause, removeStrategy |- When
removeStrategyis performed, theVeryLiquidVaultattempts to withdraw all assets from the exiting strategy and re-deposit them into another strategy. If the withdrawal or deposit fails, the whole operation reverts. - The performance fee can stop being applied during a significant downturn event, which would cause the price per share to never surpass the high-water mark.
- Assets directly sent to the vaults may be lost, with the exception of the
CashStrategyVault, which accepts them as donations. - The vaults are not compatible with fee-on-transfer assets.
- The
ERC4626StrategyVaultcannot be used by vaults that take fees in assets on deposits or withdrawals. All integrated vaults must be strictly ERC-4626 compliant. - Read-only reentrancy is not fully mitigated because of how contracts are inherited from OpenZeppelin's
openzeppelin-contracts-upgradeablelibrary. Practically all ERC20 and ERC4626 view functions cannot be guarded with anonReentrantViewmodifier, since they are used internally in state-changing functions, which themselves arenonReentrant. If we appliednonReentrantViewto public view functions that are used by nonpayable functions, these would revert. SizeMetaVault'smax{Deposit,Withdraw,Mint,Redeem}functions may experience precision loss when aggregating the maximum values from underlying strategies.ERC4626StrategyVault'smax{Redeem,Mint}functions may experience precision loss when converting between the integratedvault's shares, assets, and strategy shares. In particular, this means a user'sbalanceOfmay not always be fullyredeemable, so users should always consult themaxlimits, as specified by ERC-4626.- The
reorderStrategiesfunction has quadtratic complexity due to duplicate detection logic, which is acceptable for the currentMAX_STRATEGIEScap. - The system assumes that integrated strategies are honest and non-malicious. A malicious or gas-griefing strategy could revert or consume excessive gas in
totalAssetsor other operations. - Onchain price-per-share calculations of integrated vaults (e.g.,
ERC4626StrategyVault.vault()used in many markets) may increase gas costs linearly with the number of underlying markets. This can makerebalance,totalAssets, and other operations expensive. - The vaults socialize losses on integrated protocols.
export ADMIN_MULTISIG=XXX
export VAULT_MANAGER_MULTISIG=XXX
export GUARDIANS=XXX
export STRATEGISTS=XXX
forge script script/TimelockControllerEnumerables.s.sol --rpc-url $RPC_URL --gas-limit 30000000 --sender $DEPLOYER_ADDRESS --account $DEPLOYER_ACCOUNT --verify -vvvvv [--slow]
export TIMELOCK_DEFAULT_ADMIN_ROLE=XXX
export TIMELOCK_VAULT_MANAGER_ROLE=XXX
export ADMIN=$DEPLOYER_ADDRESS
forge script script/Auth.s.sol --rpc-url $RPC_URL --gas-limit 30000000 --sender $DEPLOYER_ADDRESS --account $DEPLOYER_ACCOUNT --verify -vvvvv [--slow]
forge script script/ConfigureAuthRoles.s.sol --rpc-url $RPC_URL --gas-limit 30000000 --sender $DEPLOYER_ADDRESS --account $DEPLOYER_ACCOUNT --verify -vvvvv [--slow]export AUTH=XXX
forge script script/CashStrategyVault.s.sol --rpc-url $RPC_URL --gas-limit 30000000 --sender $DEPLOYER_ADDRESS --account $DEPLOYER_ACCOUNT --verify -vvvvv [--slow]
forge script script/AaveStrategyVault.s.sol --rpc-url $RPC_URL --gas-limit 30000000 --sender $DEPLOYER_ADDRESS --account $DEPLOYER_ACCOUNT --verify -vvvvv [--slow]
forge script script/ERC4626StrategyVault.s.sol --rpc-url $RPC_URL --gas-limit 30000000 --sender $DEPLOYER_ADDRESS --account $DEPLOYER_ACCOUNT --verify -vvvvv [--slow]
export IDENTIFIER=XXX
export STRATEGIES=XXX
forge script script/VeryLiquidVault.s.sol --rpc-url $RPC_URL --gas-limit 30000000 --sender $DEPLOYER_ADDRESS --account $DEPLOYER_ACCOUNT --verify -vvvvv [--slow]