FungibleVault.
Read Supply and
Withdraw for controller transaction semantics.
The DeFindex strategy provides a
concrete adapter using one account per vault.
Track the lending balance
Supply positions are stored onaccount_id as scaled shares keyed by
HubAssetKey. They are not transferable supply tokens. The strategy contract
holds the account’s position NFT, which determines account ownership.
Underlying balances derive from RAY-normalized shares and the supply index.
Use controller views to perform this conversion and include accrued interest:
These views do not read oracle prices. Interest is reflected in the index, so
reporting lending yield requires no harvest or index-maintenance update. See
Interest and revenue.
Balance reads round half-up, while full withdrawal pays a floor-valued balance.
The payout can be one native unit below the displayed balance. Supply mints
shares with floor rounding; partial withdrawal burns shares with ceiling
rounding. Use returned payouts and reread balances after mutations.
Authorize supply
Pull the deposit tokens into the strategy and measure its receipt before calling this helper. Authenticate the depositor in the surrounding entrypoint. Use the measured amount, then persist the returned account id before issuing vault shares.account_id = 0 opens an account on the selected spoke_id.
This complete helper uses the repository’s controller-interface and common
crates. It supplies tokens already held by the invoking strategy contract:
get_collateral_amount(account_id, hub_asset) for the accrued underlying
balance. For withdrawal, call the controller with the strategy as caller and
the eligible recipient as to. The pool pays that recipient directly, so the
strategy needs no token-transfer authorization for the payout. Controller
amount = 0 closes the selected position; an excessive request clamps to full
withdrawal. The returned vector reports the actual amounts paid.
Size and simulate vault actions
The controller exposes nomax_withdraw or max_supply view. Read the relevant
state and simulate the proposed transaction:
Withdrawals also face the market utilization limit. Supply caps (
#311),
position limits (#109), cash shortages (#112), or utilization limits (#127)
can reject an action. While debt remains, withdrawal must pass LTV coverage,
health factor, and the configured USD collateral floor. Each collateral position
with fewer than three decimals must also retain at least two base units after
floor conversion. Simulation reflects one ledger state. Cash, interest, prices,
and cap usage can change before execution.
Handle account lifecycle
A full withdrawal of the final position from a debt-free account removes the account and burns its NFT. Clear the stored id and useaccount_id = 0 for the
next supply. A stale id raises #24 AccountNotFound. Missing-account balance
views return zero, position maps are empty, and health factor is i128::MAX.
Global protocol pause blocks supply but permits withdrawal, repayment,
renew_account, and recapitalization. A paused spoke listing also blocks its
ordinary withdrawals and repayments; a frozen listing permits those exits.
Debt-free supply and withdrawal do not need oracle valuation. Repayment and
native balance reads are also oracle-free. With debt, withdrawal needs valid
prices, and supply can need them for a less favorable liquidation-parameter
refresh. Account strategies fetch prices before funding or callbacks.
Account keys renew when read or written: a remaining lifetime below 30 days is
extended to 120 days. Touch dormant positions periodically with
renew_account(caller, account_id), including during pause. Archived entries
require RestoreFootprint before use. The vault must also maintain its own
mapping and share-accounting storage.

