Skip to content

Oracle Transparency

The ORACLE tab on each expanded carry strategy explains, for that exact vault, (1) how the execution platform's oracle works, (2) how it is wired for the specific tokens involved, and (3) what that means for the strategy's liquidation risk. The goal is that a credit analyst can see why a temporary market depeg does or does not threaten the position.

The unifying fact

Across all three venues, collateral is priced by its on-chain redemption / exchange rate against a correlated base asset, never by the wrapper's secondary-market price. That is precisely why a transient stETH / sUSDe / weETH market depeg does not liquidate these loops. The protocols differ only in how they wrap that idea.

Per-platform mechanism

  • Fluid — each vault has its own oracle contract returning two figures: an operate rate (used when opening or adjusting a loan) and a liquidation rate (checked for liquidation). Governance can set the liquidation rate more conservatively, building a buffer directly into the oracle. Fluid oracles read protocol exchange rates, not spot DEX prices.
  • Aave v3 — Chainlink CAPO adapters (Correlated-Asset Price Oracle / PriceCapAdapter): price = on-chain redemption rate × Chainlink base/USD, with a maximum upward growth cap on the redemption rate (anti-manipulation; downside fully tracked). wstETH uses the Lido rate, weETH the EtherFi rate, sUSDe the ERC-4626 redemption rate.
  • SparkLend — a Sky-governed Aave fork: ETH is priced by an aggregate of three feeds (Chronicle, Chainlink, RedStone); each LST is priced by an exchange-rate adapter reading the staking protocol's own rate (e.g. the Lido rate for wstETH, the Rocket Pool rate for rETH).

Curated vs live split

src/lib/data/oracles.ts holds only the editorial layers (platform mechanism, per-collateral explanation, risk notes). The drift-prone facts are read live from chain when the tab opens:

  • FluidVaultResolver.getVaultEntireData(vault) → the vault's configs.oracle address plus the operate / liquidation prices.
  • Aave / SparkAaveOracle.getSourceOfAsset(asset) → the price-source adapter, its on-chain description() string, and getAssetPrice(asset).

Because the address, description, and rate are read live, a protocol rotating an oracle cannot make the curated copy silently lie.

Serving

The tab fetches GET /api/carry-oracle?key=<strategyKey> on open (lazy), cached 30 minutes in the RPC layer, so the carries page itself pays nothing for these reads. See API Reference.

Drift guard

scripts/resolve-oracles.ts re-derives every strategy's oracle from chain and prints address + description() + live rate, exiting non-zero if any source resolves to null. Because the Fluid decode is a positional heuristic over the resolver payload, it also asserts each Fluid vault's de-scaled operate rate sits in a plausible band ([0.1, 20]) so a wrong-but-non-null decode (e.g. if Fluid reorders the struct) surfaces in the audit rather than on the page.

Risk framing per collateral

Each collateral type carries a short "protects against / residual risk / TradFi analogy" note, for example:

  • wstETH — protects against a transient stETH/ETH market depeg; residual risk is Lido protocol/redemption integrity (mass slashing) and rate-contract risk. Analog: marking a held-to-maturity bond at amortized cost rather than a stressed secondary quote.
  • sUSDe — protects against a transient sUSDe/USDe market discount; residual risk is a break in USDe's peg itself (Ethena's basis trade failing, custody failure). Analog: an unregistered money-market fund valued at stated NAV.
  • syrupUSDC / syrupUSDT — residual risk is credit losses in Maple's loan book and gated (non-instant) redemptions. Analog: a private-credit fund marked at reported NAV.

Private documentation. creddit.xyz