Skip to content

solanabr/solana-vault-standard

Repository files navigation

Solana Vault Standard (SVS)

solana-vault is a collection of tokenized vault programs and TypeScript SDK/CLI for building and maintaining yield-bearing vaults on Solana. The SDK provides deposit/withdraw operations, share accounting, preview functions, and modular extensions for fees, caps, access control, timelocks, and multi-asset portfolios.

The interface started off following the ERC-4626 specification adapted for Solana's account model. With time, more ERC's and features were also covered such as Centrifuge's ERC-7540, alongside novel onchain enforcements and implementations such as Tranched RWA vaults, streaming vault yield, vaults-of-vaults, and more.

SVS Variants

Version Name Balance Model Privacy Sync Status
SVS-1 Public Vault (Live) Live balance None No sync needed ✅ Devnet
SVS-2 Public Vault (Stored) Stored balance None Requires sync() ✅ Devnet
SVS-3 Private Vault (Live) Live balance Encrypted No sync needed ✅ Devnet
SVS-4 Private Vault (Stored) Stored balance Encrypted Requires sync() ✅ Devnet
SVS-5 Streaming Yield Vault Interpolated balance None distribute_yield() + checkpoint() ✅ Devnet
SVS-6 Streaming Private Vault Interpolated balance Encrypted distribute_yield() + checkpoint() ✅ Devnet
SVS-7 SOL Vault Live balance None Native SOL wrapping ✅ Devnet
SVS-8 Multi-Asset Basket Oracle-weighted None Weight rebalancing ✅ Devnet
SVS-9 Allocator Vault Stored balance None CPI to child vaults ✅ Devnet
SVS-10 Async Vault (ERC-7540) Stored balance None Request→Fulfill→Claim ✅ Devnet
SVS-11 Credit Markets Vault Oracle NAV KYC + Freeze Async (request→approve→claim) ✅ Devnet
SVS-12 Tranched Vault Stored balance None Manager-driven ✅ Devnet

Balance Model Comparison

Live Balance (SVS-1, SVS-3):

  • Uses asset_vault.amount directly for all calculations
  • External donations/yield immediately reflected in share price
  • No sync timing attack vulnerability
  • No sync() function needed

Stored Balance (SVS-2, SVS-4):

  • Uses vault.total_assets stored in account
  • Requires sync() call to recognize external donations
  • Authority controls when yield is recognized
  • May be preferred for yield strategies that require controlled distribution

Streaming Balance (SVS-5):

  • Uses base_assets + accrued_stream_yield computed at current timestamp
  • Yield distributed linearly over configurable duration via distribute_yield(amount, duration)
  • checkpoint() materializes accrued yield into base_assets (permissionless)
  • Eliminates MEV from front-running discrete sync/yield operations
  • Suited for payroll vaults, vesting schedules, DCA strategies

Async (SVS-10):

  • Request→Fulfill→Claim lifecycle for deposits and redemptions
  • Operator fulfills requests using vault price or oracle NAV
  • Supports illiquid assets, RWA, and cross-chain strategies
  • ERC-7540 equivalent with synchronous cancellation (ERC-7887)

Privacy Model

Public (SVS-1, SVS-2):

  • Token-2022 shares mint (no extensions)
  • All balances visible on-chain
  • Simple, auditable, production-ready

Private (SVS-3, SVS-4):

  • Token-2022 with Confidential Transfers extension
  • Share balances encrypted with ElGamal
  • Only owner can decrypt their balance
  • Requires Rust proof backend for ZK proof generation

Program IDs

Program Devnet Localnet
SVS-1 CzZyssz2PdLccWpbVi6a3wFKMmMqdf28U2RapNNRJSPX Same as devnet
SVS-2 7vnZM4aCsRapH9ft7Bo5ibTXNH2dvoxkj96c7JonLhoe Same as devnet
SVS-3 CC4xQGxmwKusLW3ToqUzRAFjh7cL2iKsgfkz6qJSasYs Same as devnet
SVS-4 EqRNvMTwczQjUhQL8wwrxJGALgz5VWsYne3d67e6ruCv Same as devnet
SVS-5 HCp23XHzV4HJHXwLWwQj8aSTU1yjyzj8FCNLe6NybwXt Same as devnet
SVS-6 oaT6wgNiwCqd7EGvB6Wb5ZFYUJXckk6LEhB7MWqXbyC Same as devnet
SVS-7 CR2ccVacmbQ2DaXvR66W7gnmH7KuDCqbVW5VwnTczQUC Same as devnet
SVS-8 HnZ9N8Y1v6jMhwDqo4Y76GfqjRArdinadgK67yLVFZbe Same as devnet
SVS-9 AaADS3DCGkjhDEDbGkygbG9bNaziR9TPK2X7SMBYedws Same as devnet
SVS-10 4G5d6KutMpUaDPTVcv7FJBpPTGZej8rx3GyGnfiRdD6M Same as devnet
SVS-11 CMeQ5Lx7AvjuW3DrzNvEkPZSdqKZjjhaTrAmgqBvPKHD Same as devnet
SVS-12 EPwH58e5V1UXYkkD8JZ4bq7Wr2iRiC9fLj1S6BRRz2R Same as devnet
Mock Oracle Heezh11y1FJPvrUjKetGsDJTFFNdHqXPz9bFsUiEJxdh Same as devnet
Mock SAS GTTMWDHTZibyEpqNRr33RnBhgms262U6qHaGrjoHqEXg Same as devnet

Installation

# Core SDK (SVS-1/SVS-2)
npm install @stbr/solana-vault

# Privacy SDK (SVS-3/SVS-4)
npm install @stbr/svs-privacy-sdk

# Backend (for private vault proof generation)
cd proofs-backend && cargo run

Quick Start

import { SolanaVault, ManagedVault, StreamingVault, AsyncVault } from "@stbr/solana-vault";
import { BN } from "@coral-xyz/anchor";

// SVS-1: Load live-balance vault
const vault = await SolanaVault.load(program, assetMint, 1);

// SVS-2: Load stored-balance vault (adds sync())
const managed = await ManagedVault.load(program, assetMint, 1);

// Preview deposit
const expectedShares = await vault.previewDeposit(new BN(1_000_000));

// Deposit with slippage protection
await vault.deposit(user, {
  assets: new BN(1_000_000),
  minSharesOut: expectedShares.mul(new BN(95)).div(new BN(100)),
});

// Redeem shares
const expectedAssets = await vault.previewRedeem(shares);
await vault.redeem(user, {
  shares,
  minAssetsOut: expectedAssets.mul(new BN(95)).div(new BN(100)),
});

// SVS-2 only: sync stored balance
await managed.sync(authority);

// SVS-5: Load streaming yield vault
const streaming = await StreamingVault.load(program, assetMint, 1);

// Distribute yield over 1 hour
await streaming.distributeYield(authority, new BN(1_000_000), new BN(3600));

// Permissionless checkpoint
await streaming.checkpoint();

// SVS-10: Async vault (request→fulfill→claim)
const asyncVault = await AsyncVault.load(program, assetMint, 1);
await asyncVault.requestDeposit(user, { assets: new BN(1_000_000) });
await asyncVault.fulfillDeposit(operator, { owner: user.publicKey });
await asyncVault.claimDeposit(user, { owner: user.publicKey });

Features

Feature Description
Inflation Attack Protection Virtual offset mechanism prevents donation attacks
Vault-Favoring Rounding All operations round to protect vault solvency
Slippage Protection Min/max parameters prevent sandwich attacks
Multi-Vault Support Multiple vaults per asset via vault_id
Emergency Controls Pause/unpause and authority transfer
CPI-Composable Views Preview functions callable from other programs

On-Chain Modules (SVS-1)

SVS-1 includes optional on-chain modules for enforcing vault policies at the program level. Build with --features modules to enable.

Module Description
svs-fees Entry/exit fees (max 10%), collected later via admin instruction
svs-caps Global and per-user deposit caps with bypass prevention
svs-locks Time-locked shares before redemption (max 1 year)
svs-access Whitelist/blacklist with merkle proof verification

Module PDAs are passed via remaining_accounts. If not passed, checks are skipped (backward compatible).

# Build SVS-1 with modules
anchor build -p svs-1 -- --features modules

SDK Extensions

The TypeScript SDK includes modular extensions for common vault patterns:

Module Description
fees Management, performance, and entry/exit fee calculation
cap Global and per-user deposit caps
emergency Emergency withdrawal with configurable penalty
access-control Whitelist/blacklist with merkle proof verification
multi-asset Portfolio allocation across multiple vaults
timelock Governance proposal lifecycle management
strategy CPI templates for deploying assets to external protocols

CLI

The SDK includes a CLI for vault management:

# Install globally
npm install -g @stbr/solana-vault

# Initialize config
solana-vault config init

# Add vault alias
solana-vault config add-vault my-vault <ADDRESS> --variant svs-1 --asset-mint <MINT>

# Common operations
solana-vault info my-vault                    # View vault state
solana-vault balance my-vault                 # Check your balance
solana-vault deposit my-vault -a 1000000      # Deposit assets
solana-vault withdraw my-vault -a 500000      # Withdraw assets
solana-vault dashboard my-vault               # Live monitoring

# Admin (authority only)
solana-vault pause my-vault                   # Emergency pause
solana-vault sync my-vault                    # Sync balance (SVS-2/4)

# Async vault (SVS-10)
solana-vault async request-deposit my-vault -a 1000000
solana-vault async fulfill-deposit my-vault --owner <PUBKEY>
solana-vault async claim-deposit my-vault --owner <PUBKEY>
solana-vault async request-redeem my-vault -s 500000
solana-vault async set-operator my-vault --operator <PUBKEY>

Global flags: --dry-run, --yes, --output json, --keypair <path>, --url <rpc>

Core Operations

Operation User Action Rounding Favors
deposit Pay exact assets → receive shares Floor Vault
mint Receive exact shares → pay assets Ceiling Vault
withdraw Receive exact assets → burn shares Ceiling Vault
redeem Burn exact shares → receive assets Floor Vault

Architecture

+--------------------------------------------------------------------+
|                    Solana Vault Standard                           |
+--------------------------------------------------------------------+
|                                                                    |
|   PUBLIC VAULTS                     PRIVATE VAULTS                 |
|   +------------------+              +------------------+           |
|   |                  |              |                  |           |
|   | SVS-1            | Live         | SVS-3            | Live      |
|   | (No sync needed) | Balance      | (No sync needed) | Balance   |
|   |                  |              |                  |           |
|   +------------------+              +------------------+           |
|   |                  |              |                  |           |
|   | SVS-2            | Stored       | SVS-4            | Stored    |
|   | (sync() for      | Balance      | (sync() for      | Balance   |
|   |  yield accrual)  |              |  yield accrual)  |           |
|   +------------------+              +--------+---------+           |
|   |                  |                                             |
|   | SVS-5            | Streaming                                   |
|   | (distribute_yield| Balance                                     |
|   |  + checkpoint)   |                                             |
|   +------------------+                                             |
|            |                                 |                     |
|            v                                 v                     |
|   +------------------+              +------------------+           |
|   |  SPL Token       |              |  Token-2022      |           |
|   |  (public u64)    |              |  + CT Extension  |           |
|   +------------------+              |  (encrypted)     |           |
|                                     +--------+---------+           |
|                                              |                     |
|                                              v                     |
|                                     +------------------+           |
|                                     |  Proofs Backend  |           |
|                                     |  (Rust/Axum)     |           |
|                                     +--------+---------+           |
|                                              |                     |
|                                              v                     |
|                                     +------------------+           |
|                                     |  ZK ElGamal      |           |
|                                     |  Proof Program   |           |
|                                     +------------------+           |
|                                                                    |
|   ASYNC VAULTS                                                     |
|   +------------------+                                             |
|   |                  |                                             |
|   | SVS-10           | Stored                                     |
|   | (Request→Fulfill | Balance                                    |
|   |  →Claim)         | + Oracle                                   |
|   |                  |                                             |
|   +------------------+                                             |
+--------------------------------------------------------------------+

PDA Derivation

Vault PDA

Seeds: ["vault", asset_mint, vault_id (u64 LE)]

SVS-5 note: StreamVault uses seed "stream_vault" instead of "vault".

const [vault] = PublicKey.findProgramAddressSync(
  [Buffer.from("vault"), assetMint.toBuffer(), vaultId.toArrayLike(Buffer, "le", 8)],
  programId
);

Shares Mint PDA

Seeds: ["shares", vault_pubkey]

const [sharesMint] = PublicKey.findProgramAddressSync(
  [Buffer.from("shares"), vault.toBuffer()],
  programId
);

Instructions

Core Operations (All Programs)

Instruction Description
initialize Create new vault
deposit Deposit assets, receive shares
mint Mint exact shares, pay assets
withdraw Withdraw exact assets, burn shares
redeem Burn shares, receive assets

Admin Operations

Instruction SVS-1 SVS-2 SVS-3 SVS-4 SVS-5 Description
pause Emergency pause vault
unpause Resume operations
transfer_authority Transfer admin rights
sync Sync total_assets with balance
distribute_yield Start streaming yield distribution
checkpoint Materialize accrued yield (permissionless)

View Functions (All Programs)

Instruction Description
preview_deposit Preview shares for asset deposit
preview_mint Preview assets needed for share mint
preview_withdraw Preview shares burned for asset withdrawal
preview_redeem Preview assets received for share redemption
convert_to_shares Convert asset amount to shares
convert_to_assets Convert share amount to assets
total_assets Get total vault assets
max_deposit Get maximum deposit amount
max_mint Get maximum mint amount
max_withdraw Get maximum withdraw amount
max_redeem Get maximum redeem amount

SVS-3/SVS-4 view difference: max_withdraw returns the vault's total assets (not user-specific) and max_redeem returns u64::MAX, because encrypted share balances can't be read on-chain. SVS-1/SVS-2 return user-specific values based on owner_shares_account.amount.

SVS-5 view addition: get_stream_info returns current stream parameters (base_assets, stream_amount, stream_start, stream_end). All view functions use effective_total_assets(now) for share price computation.

Private Vault Only (SVS-3, SVS-4)

Instruction Description
configure_account Enable confidential mode on user account
apply_pending Move pending balance to available

Error Codes

Code Name Description
6000 ZeroAmount Amount must be > 0
6001 SlippageExceeded Slippage tolerance exceeded
6002 VaultPaused Vault is paused
6003 InvalidAssetDecimals Asset decimals > 9
6004 MathOverflow Arithmetic overflow
6005 DivisionByZero Division by zero
6006 InsufficientShares Not enough shares
6007 InsufficientAssets Not enough assets
6008 Unauthorized Not vault authority
6009 DepositTooSmall Below minimum deposit
6010 AccountNotConfigured Account not configured for confidential transfers
6011 PendingBalanceNotApplied Pending balance not applied
6012 InvalidProof Invalid ZK proof data
6013 ConfidentialTransferNotInitialized CT extension not initialized
6014 InvalidCiphertext Invalid ciphertext format

Events

Event Description
VaultInitialized New vault created
Deposit Assets deposited
Withdraw Assets withdrawn
VaultSynced Total assets synced (SVS-2, SVS-4 only)
YieldStreamStarted Yield stream started (SVS-5 only)
Checkpoint Yield materialized into base_assets (SVS-5 only)
VaultStatusChanged Pause/unpause
AuthorityTransferred Authority changed

Security

Key Features:

  • Virtual offset inflation attack protection
  • Vault-favoring rounding strategy
  • Slippage protection on all operations
  • Emergency pause mechanism
  • Checked arithmetic throughout
  • PDA bumps stored (not recalculated)
  • SVS-1/SVS-3 use live balance (no sync timing attack)

Audit Status: 10 internal audit rounds completed (v1–v10), all findings resolved. No external audit yet.

Testing

# Build all programs
anchor build

# Run all tests (200+ tests, requires proof backend for SVS-3/SVS-4)
anchor test

# Run with modules feature (includes 16 module tests)
anchor build -p svs-1 -- --features modules && anchor test --skip-build

# Run SDK tests (460 tests)
cd sdk/core && npm test

# Run SVS-1 tests only
anchor test -- --grep "svs-1"

# Run specific test file
anchor test -- --grep "yield"

# Backend tests (19 tests)
cd proofs-backend && cargo test

# Start proof backend (required for SVS-3/SVS-4 CT tests)
cd proofs-backend && cargo run

Project Structure

solana-vault-standard/
├── programs/
│   ├── svs-1/                    # Public vault, live balance
│   ├── svs-2/                    # Public vault, stored balance
│   ├── svs-3/                    # Private vault, live balance (beta)
│   ├── svs-4/                    # Private vault, stored balance (beta)
│   ├── svs-5/                    # Streaming yield vault
│   ├── svs-6/                    # Streaming private vault
│   ├── svs-7/                    # SOL vault (native SOL wrapping)
│   ├── svs-8/                    # Multi-asset basket vault
│   ├── svs-9/                    # Allocator vault (CPI to child vaults)
│   ├── svs-10/                   # Async vault (ERC-7540)
│   ├── svs-11/                   # Credit markets vault (async, oracle NAV, KYC)
│   ├── svs-12/                   # Tranched vault, waterfall yield/loss
│   ├── mock-oracle/              # Mock oracle for testing
│   └── mock-sas/                 # Mock SAS for testing
├── modules/
│   ├── svs-math/                 # Shared math (mul_div, rounding, conversion)
│   ├── svs-fees/                 # Entry/exit fee calculation
│   ├── svs-caps/                 # Global/per-user deposit caps
│   ├── svs-locks/                # Time-locked shares
│   ├── svs-access/               # Whitelist/blacklist + merkle proofs
│   ├── svs-module-hooks/          # Module hook integration
│   ├── svs-rewards/              # Secondary reward distribution
│   └── svs-oracle/               # Oracle price validation
├── sdk/
│   ├── core/                     # @stbr/solana-vault
│   └── privacy/                  # @stbr/svs-privacy-sdk
├── proofs-backend/               # Rust proof generation backend
│   ├── src/
│   ├── Cargo.toml
│   ├── Dockerfile
│   └── README.md
├── tests/
│   ├── svs-{1..12}.ts           # Per-program integration tests
│   ├── svs-11-sdk.ts            # SVS-11 SDK tests
│   ├── svs-12-sdk.ts            # SVS-12 SDK tests
│   ├── svs-9-e2e.ts             # SVS-9 end-to-end tests
│   ├── modules.ts               # Module integration tests
│   ├── helpers/
│   │   └── proof-client.ts      # ZK proof backend client helpers
│   ├── admin-extended.ts        # Admin function tests
│   ├── decimals.ts              # Multi-decimal tests
│   ├── edge-cases.ts            # Edge case tests
│   ├── full-lifecycle.ts        # Full lifecycle tests
│   ├── invariants.ts            # Invariant tests
│   ├── multi-user.ts            # Multi-user tests
│   └── yield-sync.ts            # Yield/live balance tests
└── docs/
    ├── ARCHITECTURE.md          # Technical architecture
    ├── CLI.md                   # CLI reference
    ├── CONSTANTS.md             # Constants reference
    ├── DEPLOYMENT.md            # Deployment guide
    ├── ERC-4626-REFERENCE.md    # Original ERC-4626 spec
    ├── ERRORS.md                # Error codes
    ├── EVENTS.md                # Event definitions
    ├── MODULES.md               # Module system
    ├── PATTERNS.md              # Design patterns
    ├── PRIVACY.md               # Privacy model & proof backend
    ├── SDK.md                   # SDK usage guide
    ├── SECURITY.md              # Attack vectors & mitigations
    ├── TESTING.md               # Test guide & coverage
    └── SVS-{1..12}.md           # Per-program specifications

AI Development

This project uses solana-claude for Claude Code integration — skills, rules, agents, and MCP servers for Solana development.

Resources

License

Apache 2.0

Disclaimer

This software is provided "as is" without warranty. Use at your own risk. 10 internal audit rounds completed but no external audit. Private vaults (SVS-3, SVS-4) require the Rust proofs backend for full functionality.

About

Solana tokenized vault standard built on Anchor. Programs, SDK, CLI + native extensions to help you across the whole lifecycle of many different types of onchain vaults.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Contributors

Languages