Skip to main content
Field names below are the exact wire names. Numeric scales are not encoded in the names: see Events for the scale of every field.

HubAssetKey

The market coordinate used by controller flows, pool storage, keeper config, views, events, and strategy inputs. The same token under two hubs is two independent markets.

Account model

There is no single Account struct on the wire. Account state is split across three controller records plus the position-NFT contract: Ownership is not stored on the controller. The account_id is the position NFT’s token_id; the controller calls owner_of(account_id) on every authority check. Transferring the token transfers the whole position. AccountAttributes is the view projection of AccountMeta: { spoke_id: u32, mode: PositionMode }. Accounts bind to a spoke id >= 1, and the binding never changes.

PositionMode

#[repr(u32)], so it is a plain u32 on the wire. Fixed at account creation and enforced on every later multiply or flash_position call against that account (#25 AccountModeMismatch).

AccountPositionRaw

DebtPositionRaw

SpokeConfig

SpokeAssetConfig

The three halt flags are independent. Seizure is deliberately not gated by paused, because seizure is pro-rata across an account’s whole collateral set — pausing one collateral would otherwise halt liquidation of every account holding it. SpokeAssetArgs is the write-side input shape. It uses different field names for the same values: can_collateral, can_borrow, ltv, threshold, bonus, plus hub_id, asset, spoke_id, the three flags, liquidation_fees, supply_cap, and borrow_cap.

SpokeUsageRaw

MarketParamsRaw

Lives in pool Params(HubAssetKey) storage. Rate and utilization fields are RAY-scaled. There are no _ray / _bps suffixes on the wire, and no supply/borrow cap fields — caps are per-spoke, not per-market. InterestRateModel is the same set minus asset_id and asset_decimals; it is what upgrade_liquidity_pool_params takes.

Liquidation types

SeizeMode

Credit(0) creates the receiving account for you. It is owned by the liquidator and bound to the liquidated account’s spoke. A non-zero id must already satisfy all five of these:
  • it exists;
  • it is not the liquidated account itself (#133);
  • the liquidator owns it, or is a delegate on it;
  • it sits in the liquidated account’s spoke;
  • it is in PositionMode::Normal.

LiquidationEstimate

Units follow the mode: asset units for Transfer, RAY-scaled supply shares for Credit. PaymentTuple is { asset: Address, amount: i128 }.

MarketIndexView

Returned by get_market_indexes_detailed.
error_code is not in a released build yet. It exists only on an unmerged branch. A contract deployed from main today returns MarketIndexView and PriceStatus without this field, so a decoder that expects it will fail.Until it lands, treat a price as unusable whenever valid is false.Do not try to infer why from stale or deviation. A resolution error zeroes both, so false there does not mean those checks passed.
Once it ships, error_code becomes the only field that tells you why a price failed, for exactly that reason.

Oracle types

Oracle configuration is stored on the price aggregator, keyed by PriceKey:

AssetOracle

PriceSource

FeedSource { provider: ProviderRef, decimals: u32, max_stale_seconds: u64 }, where ProviderRef is Reflector(ReflectorFeedRef), RedStone(MultiFeedRef), or Xoxno(MultiFeedRef). Reflector references carry an OracleReadMode of Spot or Twap(records); RedStone and Xoxno references carry a FeedNature of Market or Fundamental. See Oracles for how these compose.