Vault Account Structure
Every vault has these core properties:Vault Token
Each vault mints its own vault token:- Mint address is a PDA:
["mint", vault_id_u64]wherevault_idis a sequential counter from the global config. - Vault account address is derived from the mint:
["basket", mint_pubkey]. - Vault token holders have proportional ownership of all underlying tokens.
- All vault tokens have 6 decimal places (
MINT_DECIMALS = 6). This means 1,000,000 raw units = 1.0 vault tokens. - Vault token price = Total vault value / Total vault token supply.
- The
start_priceparameter at creation sets the initial vault token price in human USD terms (e.g."1.0"= $1.00). The SDK encodes this to the program’s internal fraction format. This determines how many vault tokens are minted per dollar of deposits — a higher start price means fewer tokens per deposit.
Composition
Each token position (Asset) in the vault contains:
Vault composition supports both classic SPL mints and Token Extensions (
Token22) mints.loadVaultPrice(), each asset also gets:
price— current oracle pricevalue— computed USD value of the position
Vault Types
The vault type is set during creation and is exposed in
vault.formatted.vault_type.
Formatted Vault
After fetching a vault, theformatted property provides a human-readable representation:
Metadata URI
Themetadata_uri is a URL pointing to a JSON file that describes the vault and its token. This JSON populates the vault token’s on-chain metadata and is read by frontends to display vault information. The URI can be hosted anywhere (Arweave, IPFS, a static server, etc.) and must be at most 200 characters.
The JSON file should contain the following fields:
You can include any additional fields for your own integrations — for example, social links, website URLs, or strategy details:
editMetadataTx.
Creating a Vault
start_priceis denominated in USDC (6 decimals). A start price of"1.0"means 1 vault token = $1.00 initially.- Host platform fees are set at creation and cannot be changed later.
- If
host_platform_paramsis omitted, the creator becomes the host with zero host fees. - The vault automatically wraps WSOL for the required bounty bond + minimum automation bounty.
- After creation, the vault has no tokens. You must add tokens with
addOrEditTokenTxand set weights withupdateWeightsTx.
Adding Tokens
After creating a vault, add tokens with their oracle configurations. For Pyth oracles, you can find price feed IDs for all supported assets at Pyth Price Feed IDs.Setting Token Weights
Set target weights for all tokens. Weights are in basis points and must sum to 10,000:Fetching Vaults
Loading Prices
CallingfetchVault returns the vault without live prices. To get current prices and TVL:
Vault Settings
Each vault has independently configurable settings, each with its own modification delay and authority bitmask:Deposits Setting
Controls whether users can deposit into the vault. Whenenabled: false, no new deposits are accepted. This change is always immediate (no modification delay). Configured via editDepositsTx.
Force Rebalance Setting
Controls whether authorized managers can trigger rebalances that bypass the normal automation checks. When a manager with theforce_rebalance authority bit triggers a rebalance via rebalanceVaultTx:
- Automation does not need to be enabled.
- The schedule automation window is not checked.
- The cooldown period is not enforced.
- The deviation threshold is not required.
enabled: false, this override is disabled and all rebalances must go through normal automation conditions. This is a powerful privilege — use the authority bitmask to restrict which managers can force rebalances. Configured via editForceRebalanceTx.
Custom Rebalance Setting
Controls whether custom rebalances (typeVaultCustom) are allowed. This is a separate rebalance mode from the standard keeper-initiated rebalance. Configured via editCustomRebalanceTx.
LP Setting
Controls whether the vault operates in LP (liquidity provider) mode. Whenenabled: true, lp_threshold_bps sets the maximum deviation (in bps) from target weights before LP swaps are restricted. Configured via editLpTx.
High Watermark
Thehigh_watermark tracks the vault token’s all-time high price. It is used to compute performance fees — fees are only charged on profits above the high watermark, preventing double-charging on recovery from drawdowns. When the vault token price exceeds the current high watermark, the difference is the “profit” subject to the performance fee. The high watermark is updated on-chain when fees are processed.
Accessible via vault.formatted.high_watermark.
Active Counters
The vault tracks how many operations are currently in progress:
These counters are incremented when operations are created on-chain and decremented when they complete. Accessible via
vault.formatted.
Schedule & Cycles
Each vault has a configurable schedule that divides time into repeating cycles. Within each cycle, three operation windows control when specific activities are allowed:How Cycles Work
cycle_start_timeis a unix timestamp marking the first cycle’s start.cycle_durationis the length of each cycle in seconds (e.g., 86400 for daily, 604800 for weekly).- The current position within the cycle is:
(current_time - cycle_start_time) % cycle_duration. - Each window’s
startandendare offsets (in seconds) from the beginning of the cycle. - An operation is allowed when the current cycle position falls within its window.
cycle_duration is 0, there is no cycle constraint and all operations are always allowed.
Each schedule window must be at least 10 minutes wide (600 seconds). The
cycle_duration must also be at least 10 minutes unless it’s set to 0 (which disables all schedule restrictions). Setting shorter windows will cause a validation error.Example: Daily Cycle with Restricted Windows
Example: Always Open (Default)
Setting all windows to cover the full cycle duration means no restrictions:Use Cases
- Daily rebalance window: Set
automation_startandautomation_endto a narrow window (e.g., 2 hours) so automated rebalances only run during low-activity periods. - Weekly management cycle: Use a 7-day cycle with management limited to the first day, giving vault holders predictability about when settings may change.
- Deposit lockout during rebalancing: Restrict
deposits_endto close deposits before the automation window opens, preventing new deposits while the vault is rebalancing.
isRebalanceRequired() checks whether the current time falls within the automation window before proceeding.
Lookup Tables
Each vault uses 2 active Address Lookup Tables (ALTs) to store oracle account addresses needed for price updates. When tokens are added and the ALTs become full, userewriteLookupTablesTx to rebuild them.