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.
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.
| Token | Primary route | Receipt token |
|---|---|---|
| SOL | Kamino Lend | kSOL (kToken) |
| SOL (staking) | Jito stake pool | jitoSOL |
| SOL (staking) | Marinade | mSOL |
| USDC | Kamino / Save | kToken / cToken |
| JUP, PYTH | Jupiter Lend (Fluid) | Fluid receipt |
| BONK, RAY, WIF, MET, KMNO | Meteora DLMM | DLMM LP position |
| SKR | Guardian staking | Staking receipt |
Per-protocol mechanism and SDK details are in DeFi Integrations.
Deposit flow
- Capital is committed to the vault with its token type and amount.
- The router selects the protocol for that token type.
- The router calls the protocol's
deposit()via the protocol SDK. - The protocol returns a receipt token.
- 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.
| Protocol | Receipt field | Stored value |
|---|---|---|
| Kamino | kamino_receipt | kToken receipt address |
| Jito | jito_receipt | jitoSOL amount |
| Marinade | marinade_receipt | mSOL amount |
| Save | Save receipt | cToken receipt |
| Jupiter Lend | Jupiter receipt | Fluid receipt |
| Meteora | Meteora LP receipt | DLMM 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:
| Protocol | APY source |
|---|---|
| Kamino, Save, Jupiter, Meteora | Protocol APY endpoints |
| Jito | Jito APY endpoint (~8–9%) |
| Marinade | https://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.