Skip to main content
delta-vault holds user deposits, maintains a delta-neutral hedge via kimia-perp, and distributes accrued funding to vault share holders.

Accounts

Vault

["vault", perps_market].
FieldTypeNotes
authorityPubkeyAdmin
perps_marketPubkeykimia-perp::Market this vault hedges on
perps_market_indexu16
perps_user_accountPubkeyVault’s user account inside kimia-perp
share_mintPubkeySPL mint for vault shares
usdc_vaultPubkeyUSDC token account (vault PDA authority)
wsol_vaultPubkeywSOL token account (spot leg)
spot_poolPubkeykimia-perp::SpotPool the vault swaps against
navu64Net asset value, USDC 6-decimal
total_sharesu64
insurance_fundu64
insurance_skim_bpsu16configurable per vault (e.g. 3000 = 30%)
rebalance_threshold_bpsu16triggers rebalance()
stateVaultStateActive, Paused, Closed
last_realized_pnl_snapshoti64used by claim_funding
last_wsol_balanceu64for rebalance diffs
share_price() = nav × ONE / total_shares (9-decimal fixed point).

Instructions

InstructionWhoPurpose
initialize_vaultadminCreate Vault PDA, share mint, USDC vault
admin_seed_insuranceadminBootstrap the insurance fund
init_perps_user_accountadminOne-time CPI to create vault’s perp user
admin_setup_spot_legadminConfigure wSOL vault + spot pool
deposituserMint shares; optionally open hedge
withdrawuserBurn shares; optionally close hedge
rebalanceanyoneClose delta gap if > rebalance_threshold_bps
claim_fundinganyoneCPI settle_funding, route yield to NAV + insurance
admin_resync_navadminEmergency NAV reconciliation
admin_unwind_vaultadminForce close all positions (requires Paused)
admin_simulate_fundingadmin (demo)Inject synthetic yield for testing
admin_force_pauseadmin (demo)Pause vault manually

Deposit flow

user USDC


vault.usdc_vault  ── mints shares = amount × total_shares / NAV ──► user

    │ if open_perp=true and size_amount>0:

    ├── spot_swap(half USDC → wSOL)                  [CPI → kimia-perp]
    ├── deposit_collateral(half USDC → perp)         [CPI → kimia-perp]
    └── place_order(direction=SHORT, size_amount,
                    is_market=true, max_slippage_bps) [CPI → kimia-perp]
Remaining accounts passed to deposit are orderbook counterparty accounts used by place_order.

claim_funding flow

pre_snapshot  = perps_user_account.realized_pnl
settle_funding(keeper=vault_pda)    [CPI → kimia-perp]
post_snapshot = perps_user_account.realized_pnl

delta = post_snapshot - pre_snapshot

if delta > 0:
    skim      = delta × insurance_skim_bps / 10_000
    to_nav    = delta - skim
    insurance_fund += skim
    nav       += to_nav
else:
    abs_delta = -delta
    drawn     = min(abs_delta, insurance_fund)
    insurance_fund -= drawn
    nav       -= abs_delta - drawn

    if insurance_fund == 0 and sustained 24h loss:
        state = Paused

Withdraw flow

shares = amount
if close_perp=true:
    place_order(direction=LONG buy-to-close, base_amount=share_ratio × position)
    spot_swap(wSOL → USDC proportionally)

burn shares → transfer USDC to user
nav -= amount_out

Errors

VaultNotActive, VaultNotPaused, MathOverflow, StaleOracle, PerpsUserAccountNotInit, NavCorrupted, InsufficientInsuranceFund, RebalanceGapTooSmall.

Delta-neutral concept

The math and motivation.

split-engine

Wrap vault shares into PT/YT.