Positions concepts

The unified position model — buckets, health factor, borrow limit, liquidation price, USD value, and why they are stored, not derived at read time.

Every protocol Orion supports reports positions in the same shape. A lending position in Blend and an LP share in Soroswap arrive in one normalized envelope, so you write your integration once.

Values are stored, not computed at read time

Health factor, borrow limit, liquidation price, and USD value are folded on the write side — computed as ledgers are indexed and written into the read model — not recalculated when you make a request. Two consequences follow:

  • Reads are cheap and consistent. The same request against the same last_indexed_ledger always returns the same numbers.
  • A value can be point-in-time correct. Because each figure was computed at a specific ledger, you can ask for a wallet’s state as of a past ledger and get the health factor that was true then — see As-of-ledger & staleness.

The position buckets

Under each protocol, positions are split into five buckets. Every bucket is a list of Position rows (empty when the wallet has nothing of that kind):

BucketMeaning
collateralSupplied assets that back borrowing. Each can carry its own liquidation_price.
supplySupplied assets earning yield but not enabled as collateral.
liabilitiesBorrowed assets — what the wallet owes.
lpLiquidity-pool shares (AMM protocols).
backstopFirst-loss capital deposited into a pool’s backstop.

The collateral-vs-supply split is deliberate: the same asset can be supplied with or without collateral enabled, and only collateral counts toward the borrow limit. Keep them distinct when you sum exposure.

A position row

{
  "asset_id": "CAS3J7GY...",
  "contract": "CCLBPEYS...",
  "share_amount": "1600.0000000",
  "asset_amount": "1620.0000000",
  "usd_value": "1620.00",
  "share_type": "bToken",
  "apr": "0.0221",
  "liquidation_price": null,
  "metadata": null
}
FieldMeaning
asset_idThe underlying asset’s contract. Resolve its symbol/decimals via enrichment.assets.
contractThe protocol contract holding the position (e.g. a Blend pool). Resolve via enrichment.contracts.
share_amountProtocol share units — bTokens, dTokens, LP tokens.
asset_amountThe underlying-asset amount those shares redeem to.
usd_valueUSD value of the position, or null when no price is available.
share_typeProtocol share vocabulary. Blend uses bToken (supply) and dToken (debt).
aprUncompounded rate for the position. Prefer apr; the older apy field carries the same value and is deprecated.
liquidation_pricePrice at which this collateral is liquidated, when the concept applies; otherwise null.

All amounts are strings to preserve on-chain precision — parse them as decimals.

Protocol and aggregate rollups

Each protocol entry carries pre-computed summary figures alongside its buckets:

{
  "protocol_id": "blend",
  "deposited_usd": "1620.00",
  "borrowed_usd": "137.45",
  "net_apy": "0.0413",
  "health_factor": "1.87",
  "estimates": {
    "borrow_cap_usd": "1053.00",
    "borrow_limit_pct": "0.13"
  },
  "positions": { "...": "the five buckets" }
}
FieldMeaning
deposited_usdGross USD supplied across every pool for this protocol — not net of borrows.
borrowed_usdGross USD borrowed.
health_factorCollateral-to-liability safety margin; null when the wallet has no borrows to measure against.
net_apyBlended yield across the protocol’s positions.
estimates.borrow_cap_usdRemaining USD the wallet can still borrow.
estimates.borrow_limit_pctCurrent borrow utilization, 01.

The top-level data object rolls these up further into total_value_usd, aggregate_net_apy, and aggregate_health_factor across all protocols.

Pricing and null values

A usd_value or health_factor can be null. A lending pool’s configured oracle can be a view-only aggregator that has never written a price to the ledger, so there is no on-chain price to value the position against. Orion returns null rather than a fabricated zero or a stale guess — check for it before doing math on usd_value.

When a price is available, enrichment.assets[asset_id].price_source tells you where it came from:

price_sourceMeaning
pool_oracleThe protocol’s own configured oracle.
dex_ratioDerived from an on-chain DEX pool ratio.
external_feedAn external price feed.

Per-protocol detail

The unified endpoint gives you everything in one call. For protocol-specific shapes — Blend pool-level health and per-asset supply/borrow APYs, Aquarius and Soroswap LP breakdowns — use the dedicated endpoints in Protocol coverage & registry.