Skip to main content

Yield Routing

The yield router is the component that decides which DeFi protocol receives backed capital, deposits it, tracks the resulting receipt token, and redeems it for principal plus yield at resolution. This page documents the routing logic, the deposit and withdraw flows, receipt-token management, and the two staking edge cases that need special handling: the Jito cooldown and the Marinade instant-unstake path.

Devnet beta

The router runs against Solana devnet. Where an SDK is unavailable or a program is not yet deployed on devnet, the router returns a clear error and skips that token — it never fabricates a receipt. Devnet yield is 0 for stubbed routes.

Routing by token type

Capital is routed to the correct protocol based on the token type of the backing asset. The router selects a primary protocol per token and falls back where applicable.

TokenPrimary routeReceipt token
SOLKamino LendkSOL (kToken)
SOL (staking)Jito stake pooljitoSOL
SOL (staking)MarinademSOL
USDCKamino / SavekToken / cToken
JUP, PYTHJupiter Lend (Fluid)Fluid receipt
BONK, RAY, WIF, MET, KMNOMeteora DLMMDLMM LP position
SKRGuardian stakingStaking receipt

Per-protocol mechanism and SDK details are in DeFi Integrations.

Deposit flow

  1. Capital is committed to the vault with its token type and amount.
  2. The router selects the protocol for that token type.
  3. The router calls the protocol's deposit() via the protocol SDK.
  4. The protocol returns a receipt token.
  5. The router stores the receipt in the position record (the protocol-specific receipt field).

Receipt-token management

Each protocol returns a distinct receipt that MAGMA persists so the position can later be unwound. The router matches the receipt type to the correct withdrawal SDK at resolution.

ProtocolReceipt fieldStored value
Kaminokamino_receiptkToken receipt address
Jitojito_receiptjitoSOL amount
Marinademarinade_receiptmSOL amount
SaveSave receiptcToken receipt
Jupiter LendJupiter receiptFluid receipt
MeteoraMeteora LP receiptDLMM LP position

A pending_yield field tracks yield that has not yet been realized — used for the Jito cooldown case below.

Withdraw flow (resolution)

At resolution, routeWithdrawal() calls the correct withdraw method for each receipt type, returns principal + yield to the vault, and the vault distributes to backers according to their multipliers.

Jito unstaking cooldown

Jito liquid staking imposes a 1–2 epoch cooldown (~2–4 days) on unstaking. Because a delayed unstake would block payouts, the router handles resolution-during-cooldown as follows:

  • Principal is returned immediately from vault reserves.
  • Yield is paid when the unstaking completes, after the cooldown ends.
  • The outstanding amount is tracked in pending_yield.
  • The portfolio UI shows "Yield pending — unstaking in progress" until the cooldown resolves.

Marinade instant unstake

Marinade offers both a delayed and an immediate unstake path. For narrative resolution, the router always uses the immediate unstake path:

  • Immediate unstake: 0.3% fee, settles instantly — used for all resolutions.
  • Delayed unstake: never used for resolution — it would block payouts.

This keeps Marinade resolutions free of the cooldown complexity that Jito requires.

Collateral routing logic

Only lending positions count toward borrow collateral; liquid-staking and LP positions do not (yet).

The shared borrow aggregator sums lending-position USD value and multiplies by the tier's LTV cap to compute borrow capacity. See Borrowing for the LTV table and health-factor rules.

APY monitoring

A background worker fetches APYs and caches them in Redis with a 30-minute TTL:

ProtocolAPY source
Kamino, Save, Jupiter, MeteoraProtocol APY endpoints
JitoJito APY endpoint (~8–9%)
Marinadehttps://api.marinade.finance/msol/apy/1y (~7–8%)

APYs are served to clients via GET /v1/defi/apys.

Failure handling

  • If an SDK is unavailable or a program is not deployed on devnet, the router returns a clear error and skips that token — it does not return a fake receipt.
  • Receipt type and withdrawal SDK must always match; a mismatched withdrawal is rejected.
  • The Guardian deposit fee is always 0% — hardcoded and never altered.