Skip to main content
Source: instructions/account_manager/exec.rs, interface.rs.
A margin account is a PDA, so it can’t sign for itself from outside. Every interaction with an external protocol goes through this one instruction. The core program knows nothing about the target. The rules live in the validator.

Flow

Accounts

remaining_accounts, in order:
  1. The external instruction’s accounts (call_account_count of them). None is a signer: Vanna signs as the margin.
  2. The allowed-token groups, venue groups and debt groups (see Architecture).
  3. The oracle segment, including the price accounts of every holding and every token the call will receive.
  4. The validator segment, only when the validator needs accounts. For Phoenix it is [vanna_validator, market_book, exchange].

The permit

review_call receives a CallContext { mode, target_program, data, call_account_count, margin, authority, venue } and returns: The core then enforces the permit:
  • Every token in tokens_in and tokens_out must be an allowed token.
  • Each spent vault may drop by at most its cap. A receiving vault must not shrink.
  • The margin may appear only where the permit says. The core program, the authority’s wallet and the margin’s other token accounts may not appear anywhere in the call.
  • A vault left with a delegate or close authority is refused.
  • If the call opens a venue, the venue’s collateral_enabled must be on, and the margin must have room under max_venues_per_margin.

Health

After the call, every holding is revalued. The account must be debt-free or above HF 1.10. A collateral whose price fails a check counts as zero. A debt that is fresh and within confidence but off its TWAP counts at the higher of price and TWAP rather than blocking. There is no minimum output check in the core. Slippage protection is the external program’s own bound (for example Jupiter’s or Titan’s minimum out).

Client notes

  • The receiving margin vault must exist before the call. The margin account can’t pay rent, so the client creates the ATA idempotently from the wallet in the same transaction.
  • Large calls (Phoenix, the basis vaults) need a v0 transaction with an address lookup table and a raised compute-unit limit.
  • The app’s builder is marginExecuteIx in lib/solana/exec.ts.

Validator rules by venue

See Validator Program, and Swaps, Phoenix Perps and Yield Vaults for each integration.