Vault of Vaults
One of the simplest, but most powerful implementations of MORE Vaults is to build and manage portfolios of other vaults. This is achieved by adding or removing vault contracts and rebalancing between them.
The MORE Vault Core ships with two generic facets, ERC-4626 and ERC-7540 for interacting with ERC‑4626‑compatible vaults within MORE Vaults and, for vaults that require asynchronous deposit and withdrawal/redemption flows, a separate facet aligned with EIP‑7540. In addition, to accommodate custom asynchronous scenarios that fall outside these standards, the ERC‑4626 facet includes a controlled function for executing whitelisted custom actions.
These two contracts enable out-of-the-box interoperability with not just any MORE Vault, but nearly every DeFi vault on any EVM chain.
Specifically, the system supports:
Explicit implementation of key non‑view ERC‑4626 functions.
Execution of custom asynchronous actions via whitelisted selectors and parameter masks.
Asset accounting in terms of the underlying MORE Vault via oracles.
Facets and Functions
ERC-4626
The facet implements and verifies (via a Whitelist Registry) the following ERC‑4626 functions:
function deposit(uint256 assets, address receiver);
function mint(uint256 shares, address receiver);
function withdraw(uint256 assets, address receiver, address owner);
function redeem(uint256 shares, address receiver, address owner);
It also exposes a controlled entrypoint for custom asynchronous scenarios that are outside the ERC‑4626 standard:
function executeAsyncAction(
address vault,
bytes4 selector,
bytes calldata data
);
executeAsyncAction
— selector and parameter verification
executeAsyncAction
— selector and parameter verificationFor each whitelisted (vault, selector)
pair, the Whitelist Registry stores a parameter mask. The mask defines, per argument position, whether the argument is taken from user‑supplied calldata or is overridden with the MORE Vault address:
Mask bit = 1 → take the argument from calldata.
Mask bit = 0 → substitute the argument with the MORE Vault address.
This defaulting covers typical parameters such as receiver
or owner
to prevent tokens from being sent outside of the vault. If a target function’s inputs deviate from this expected pattern, the call path applies selector‑specific modifications (for example, argument re‑ordering or a dedicated adapter) before forwarding.
executeAsyncAction
— request‑type detection and accounting cache
executeAsyncAction
— request‑type detection and accounting cacheBefore and after the low‑level call, the facet inspects balance deltas of the vault’s asset and share tokens to infer the action type and to update the accounting cache:
If the asset balance decreased and no shares were minted, the action is treated as a deposit request with lock. The deposited assets are cached for accounting.
If the share balance decreased and no assets were transferred out, the action is treated as a redeem request with lock. The locked shares are cached for accounting.
Cancellation handling: if a subsequent action indicates a request cancellation (for example, balances revert to pre‑request levels or an allowed
cancel
/undo
path is executed), any previously cached amounts are uncached accordingly.If no lock is observed (balances do not indicate a lock), the facet makes no caching changes.
ERC-7540
Logic related to asynchronous requests per EIP‑7540 is implemented in a separate facet, which provides the following request methods:
function requestDeposit(uint256 assets, address receiver);
function requestRedeem(uint256 shares, address receiver);
Clarifications per the EIP‑7540 spec:
The standard does not include
requestWithdraw
orrequestMint
; it definesrequestDeposit
andrequestRedeem
only.Claims are performed via the existing ERC‑4626 methods with adjusted semantics in async mode: deposits are claimed by calling
deposit
/mint
, and redemptions are claimed by callingwithdraw
/redeem
.The base EIP‑7540 does not standardize a cancel flow (no default
cancelRequest
). If cancellation is needed, it must be implemented vault‑specifically or via a separate standard; when used, it is handled through the allowlisted selector mechanism described above.
Whitelist Registry (for executeAsyncAction
)
executeAsyncAction
)For executeAsyncAction
, the system verifies that the passed selector is allowed for the given vault. In addition, the registry stores a per‑selector parameter mask that governs argument sourcing and defaulting:
Mask bit = 1 → take the argument from the call data.
Mask bit = 0 → substitute the argument with the MORE Vault address.
This mechanism ensures that sensitive parameters such as receiver
/owner
are constrained to the MORE Vault unless explicitly permitted.
Asset Accounting and Conversion
Asset accounting against an ERC‑4626 position uses the vault’s convertToAssets()
method. The result is converted to the underlying MORE Vault value via price oracles. For asynchronous paths initiated via executeAsyncAction
or EIP‑7540 requests, any cached amounts (pending deposits or locked shares) are included in accounting until claims or cancellations release them.
Advantages
Clear separation of ERC‑4626 and EIP‑7540 logic enhances modularity.
executeAsyncAction
provides controlled flexibility for integrating non‑standard asynchronous scenarios while enforcing selector and parameter verification.
Portfolio Composition via Generic Connectors
Through the Vaults Registry, MORE DAO maintains a list of approved protocols and whitelisted vaults. This list can expand as new protocols and/or vaults are proposed by Vault Owners, Curators, or the Community.
Initial supported protocols/vaults will likely include:
Morpho
Euler
Term Finance
Hyperliquid
Gearbox
Origami
Lombard
Midas
Yearn
Ether.fi
Veda
Concrete
Beefy
Blueberry
Liminal
IPOR
Gain
Enzyme
Upshift
Last updated