Docs

Reading vault state

This page lists the exact view calls the frontend makes, so you can reproduce its reads in your own integration. All of these are mirrored in apps/frontend/src/hooks/vaultReads.ts and src/config/abis.ts.

Resolve addresses first

Before any read, resolve the immutable address graph from the vault (see Contracts & addresses):

FUND_MANAGER   = vault.FUND_MANAGER()
asset          = vault.asset()              // USDC
YIELD_POOL     = fundManager.YIELD_POOL()
YIELD_ASSET    = fundManager.YIELD_ASSET()  // USDCx
EXTERNAL_VAULT = fundManager.EXTERNAL_VAULT()
FEE_BPS        = fundManager.FEE_BPS()

Vault-level (protocol) reads

From StableYieldSyncVault (ERC-4626 surface):

CallReturns
totalAssets()Reserve-inclusive NAV of the vault
totalSupply()Total shares outstanding
asset()Underlying asset address (USDC)
convertToAssets(shares)Shares → assets at current NAV
previewRedeem(shares)Assets returned for redeeming shares now (spot, no TWAP)
maxDeposit(receiver)Binary gate: uint256.max or 0 (paused)
maxWithdraw(owner) / maxRedeem(owner)NAV- and liquidity-capped; read 0 under external pause
DEPOSIT_FEE()Flat deposit fee in asset atoms (immutable)

From the FundManager:

CallReturns
totalManagedAssets()Reserve-inclusive NAV
stableYieldRate()Promised rate, basis points
guaranteedFlowDuration()Forward-solvency horizon (seconds)
FEE_BPS()Protocol fee, basis points

Per-user position reads

CallReturns
vault.balanceOf(user)Shares owned
YIELD_POOL.getUnits(user)Nominal principal in USDC atoms (granted units)
vault.previewRedeem(shares)Position value at today's NAV (floats with external performance)
vault.maxRedeem(user)Shares redeemable right now (gated by Morpho liquidity / pause)
vault.maxWithdraw(user)Same, denominated in assets

Stream reads (the live yield)

From the GDA pool (ISuperfluidPool) and forwarder:

CallReturns
getTotalAmountReceivedByMember(user)Streamed-so-far, USDCx (18-dec). Monotonic; identical connected or not. Use this for "earned" displays.
getMemberFlowRate(user)Current per-second stream rate (int96, 18-dec) = flowRatePerUnit × userUnits
getTotalUnits() / getTotalFlowRate()Pool-wide units / flow
getClaimableNow(user)Reads 0 once the member is connected (accrual claimed at connect)
GDAv1Forwarder.isMemberConnected(pool, user)Whether the member's stream counts in their wallet balance

Decimals gotcha: the vault/asset are USDC (6-dec) but the stream is USDCx (18-dec). SCALING_FACTOR = 10^12 bridges them. Don't mix the two when displaying numbers.

Deriving the displayed rate

The app shows a linearized streaming rate, not the compounding APY. In src/components/vault/lib.ts the displayed APR is:

displayedRate = ln(1 + MORPHO_APY) × (1 − feeFraction)

i.e. continuous-compounding linearization of the underlying APY, net of fee.

Pause / availability checks

  • maxDeposit(...) == 0 → deposits gated.
  • maxRedeem(user) == 0 while the user holds shares → external pause or no liquidity; the stream still pays from the reserve.
  • The frontend uses these gates rather than calling the external vault's max* views (which are hardcoded to 0 and should be ignored).

Next

  • Integration guide — the write flows (classic and gasless) that act on this state.