Morpho Vaults
One immutable meta-adapter that reports an account's underlying-asset balance in any Morpho ERC-4626 vault (MetaMorpho V1 and V2).
Last updated
One immutable meta-adapter that reports an account's underlying-asset balance in any Morpho ERC-4626 vault (MetaMorpho V1 and V2).
One immutable meta-adapter that reports an account's underlying-asset balance in any Morpho ERC-4626 vault (MetaMorpho V1 and V2). Which vaults it queries is a governed instance set on the NAV Calculator; the adapter holds no per-vault state.
Type: Meta-adapter
protocolSubId: keccak256("morpho-vaults")
Instance key: the vault address, widened to bytes32
One position per vault the account holds shares in.
Vault supply
Supplied
false
Vault shares converted to the underlying
A vault returns an empty result (rather than reverting) when its asset is unregistered, excluded by assetFilter, or the converted balance is zero — so one bad vault never zeroes out the rest of the set. Rewards (Merkl / Universal Rewards Distributor) are not included.
The shares are valued with previewRedeem, which nets out any ERC-4626 vault exit fee (per EIP-4626 §4.3) that convertToAssets ignores. It reflects the vault's current totalAssets / totalSupply (interest accrued across its underlying Morpho markets), denominated in vault.asset(). The two agree for fee-less vaults (none currently charge an exit fee).
If previewRedeem cannot be read the leg reports 0; there is no convertToAssets fallback. Because §4.3 requires convertToAssets to ignore the redemption fee that previewRedeem must include, convertToAssets ≥ previewRedeem by construction — so falling back could only ever report more than a redemption would pay. Reporting nothing under-reports, which is the permitted direction. If instead previewRedeem runs out of the gas its frame was given, the read fails closed with RedeemValueGasExhausted(vault, stipend, consumed) rather than reporting 0, since a starved read is not evidence of an empty position — see a starved read is not an empty read.
positionId: abi.encode(address vault) — the vault address
positionKind: Supplied
There is no labels field on the position. The adapter implements positionLabels(positionId), which returns ["Vault", "<ERC4626 name()>"] from the vault's on-chain name — surfaced only by the verbose reads (getAccountPositionsVerbose / getAccountNavVerbose); the full breadcrumb is [protocolName, ...labels].
navCalculator_
NAV Calculator contract (asset registry + instance set)
Meta-adapter. Register once and seed its vaults with addMetaBalanceAdapter(adapter, instances), then adjust with addMetaInstances(adapter, instances) / removeMetaInstances(adapter, instances) (MANAGER-gated). Each instance coordinate is a vault address widened to bytes32 (decoded via _toAddress, which reverts on a non-address coordinate). Adding a new vault is a config call — no new deploy.
Last updated
amount = vault.previewRedeem(vault.balanceOf(account)) // 0 if unreadable; no convertToAssets fallbackconstructor(address navCalculator_)