For the complete documentation index, see llms.txt. This page is also available as Markdown.

Deposit

Send USDC to the ksUSD vault and get ksUSD back at the current share price. How many tokens you get depends on that price, so a deposit made later buys fewer tokens, each worth more.

New here? Read What is ksUSD? first.


The instruction

deposit(usdc_amount: u64)

One transaction does all three steps, or none of them:

  • Moves your USDC into the vault's USDC account

  • Mints ksUSD to you at the current share price

  • Updates the vault's record of what it holds

The accounts below use two Solana conventions. A PDA is an account the program controls directly, with no private key behind it. An ATA is the standard token account a wallet holds a given token in.

Account
Mutability
Purpose

vault

mut

Vault PDA (seeds: [b"vault"])

vault_usdc_account

mut

Vault's USDC ATA — receives the deposit

ksusd_mint

mut

ksUSD share mint — vault PDA is authority

user_usdc_account

mut

Depositor's USDC source ATA

user_ksusd_account

mut

Depositor's ksUSD destination ATA

user

signer

Depositor

phoenix_trader

—

Phoenix trader account — read to true up the venue's contribution to NAV before pricing. Pinned to vault.phoenix_trader

sol_oracle

—

Pyth SOL/USD — values the perp leg for that same correction. Pinned to vault.sol_oracle

token_program

—

SPL token program

phoenix_trader and sol_oracle are required on every deposit, not only in Normal mode. While the vault is Parked they are read and ignored; in Normal mode the deposit re-books the venue's real equity into NAV first, so the shares you mint are priced against the position as it actually stands.


Share-price math

In plain terms, one division:

Deposit $100 while a share is worth $1.03 and you get 97.09 ksUSD. Deposit $100 while it's worth $1.00 and you get 100. Either way you own $100 of the vault the moment the transaction lands; the price only decides how many tokens that is.

The same thing in the integers the program actually stores:

share_price_1e9 is dollars scaled by 1e9, so 1_030_000_000 reads as $1.03. Multiplying by 1e9 before dividing by it cancels the scale out, which is why usdc_amount and shares_to_mint are both plain 6-decimal amounts. The division truncates, so any fraction of a base unit is left in the vault rather than minted, so it can never round in the depositor's favour at other holders' expense.

deposit calls accrue_perf_fees before it prices your mint. That advances the high-water mark to the current price first, so you're never charged a performance fee on gains the vault made before you arrived.

The first deposit into an empty vault mints shares 1:1 at $1.00, since the starting share_price_1e9 is 1_000_000_000. Every deposit after that mints fewer shares, because the share price has drifted up with the carry earned so far. Full derivation and a worked example in NAV & share pricing.


Capacity

The vault ships with a $500k deposit cap. That isn't a demand estimate. It is roughly the largest short Phoenix's book can absorb, and it re-sizes as the venue grows.

It's a hard cap rather than a soft target because the vault only earns while its dollars are in the hedge. Whatever it can't short sits in USDC lending instead. A cap set above what the venue can hold doesn't add yield; it dilutes the part that does, until ksUSD is a Kamino deposit wearing a wrapper, carrying all of the operational risk for none of the carry.

So the cap tracks the venue:

The volume limb is a quarter of a day's flow because exit is harder than entry: that is about what a clean unwind can take. On Phoenix's numbers measured 16 September 2026 the open-interest limb binds, by roughly 2.2×: $4.73M of OI gives $709k, against $1.59M from volume. In early August it was the other way round, so the rule takes whichever is tighter.

The word median matters. A few spike days can sit inside any 30-day window and pull the mean above the median, and sizing off the mean would imply a short the venue couldn't absorb on an ordinary day.

The ramp

Phase
Cap
Opens when Phoenix has

Launch (private beta)

$500k

roughly today's book

Next tier

$1M

roughly twice today's open interest

Public

$5M → $25M

a far deeper book

Tiers open against the live book, not on a date. There is no second Solana perp venue deep enough to split the short across, so the ramp follows Phoenix.

Reading the cap live

deposit_cap_usdc is a u64 on the Vault account. 0 pauses deposits outright, u64::MAX means uncapped, anything else is a hard ceiling.

Admins move the cap with update_params. Recompute it against the live book first, rather than trusting a constant, since both inputs move week to week.


Guardrails

A deposit can be blocked by any of three things:

  • The vault is paused. The admin can pause it with set_pause in an emergency.

  • The deposit cap is hit. A deposit reverts with DepositCapExceeded if cached_nav_usdc + usdc_amount > deposit_cap_usdc. See Capacity above.

  • The amount is zero. usdc_amount must be greater than 0.


TypeScript example


Events

DepositEvent is emitted on success:


Last updated