Skip to main content
The ExponentStrategyVault account is the central state account for each vault. It tracks depositor balances, strategy positions, AUM, roles, and vault configuration. Program ID: HycecAnELpjL1pMp435nEKWkcr7aNZ2QGQGXpzK1VEdV PDA Seeds: ["vault", seed_id]

ExponentStrategyVault

#[account]
pub struct ExponentStrategyVault {
    /// Address to address lookup table (ALT)
    pub address_lookup_table: Pubkey,

    /// Squads settings account (policies, signers, configuration)
    /// Derived as: ["smart_account", "settings", seed]
    pub squads_settings: Pubkey,

    /// Squads smart account (holds funds, signs CPIs as vault)
    /// Derived as: ["smart_account", settings, "smart_account", account_index]
    pub squads_vault: Pubkey,

    /// Token entries defining accepted deposit tokens
    pub token_entries: Vec<TokenEntry>,

    /// Underlying mint used to validate all price references
    pub underlying_mint: Pubkey,

    /// SPL mint for this vault's LP tokens
    pub mint_lp: Pubkey,

    /// LP token escrow (holds staked LP tokens)
    pub token_lp_escrow: Pubkey,

    /// Fee to the treasury in LP basis points
    pub fee_treasury_lp_bps: u16,

    /// Fee treasury account
    pub fee_treasury: Pubkey,

    /// The vault PDA's own address (for self-reference in CPIs)
    pub self_address: Pubkey,

    /// PDA bump seed
    pub signer_bump: [u8; 1],

    /// Bitfield of vault status flags
    pub status_flags: u8,

    /// AUM and LP financial state
    pub financials: VaultFinancials,

    /// Strategy positions for AUM calculation
    pub strategy_positions: Vec<StrategyPosition>,

    /// Maximum LP token supply allowed
    pub max_lp_supply: u64,

    /// 8-byte seed used to derive the vault PDA
    pub seed_id: [u8; 8],

    /// Role membership lists (manager, curator, allocator, sentinel)
    pub roles: VaultRoles,

    /// Governance voting configuration for proposal rejection
    pub proposal_vote_config: ProposalVoteConfig,

    /// Reserve configuration (share BPS, lock time)
    pub reserves_config: VaultConfig,
}

VaultFinancials

pub struct VaultFinancials {
    /// Total LP token supply
    pub lp_balance: u64,

    /// Tokens sitting in vault escrows (not deployed)
    pub aum_in_base: u64,

    /// Tokens deployed in strategy positions (Kamino, etc.)
    pub aum_in_base_in_positions: u64,

    /// LP tokens in reserve escrow
    pub lp_in_reserves: u64,
}
Total AUM is computed as:
total_aum = aum_in_base + aum_in_base_in_positions

VaultRoles

pub struct VaultRoles {
    /// Full control: manage policies, roles, vault settings
    pub manager: Vec<Pubkey>,

    /// Configure token entries and validation rules via policies
    pub curator: Vec<Pubkey>,

    /// Execute strategy interactions (Kamino deposits/withdrawals)
    pub allocator: Vec<Pubkey>,

    /// Emergency control: pause/freeze the vault. Typically maintained by Exponent
    pub sentinel: Vec<Pubkey>,
}
RoleResponsibilities
ManagerFull control — initialize the vault, manage all other roles, update strategy positions
CuratorAdd or propose new policies, configure token entries — define which assets the vault accepts and how they are priced
AllocatorExecute onchain interactions on behalf of the vault within the bounds of approved policies
SentinelSafety operations — can pause or freeze vault operations if conditions require it. Typically maintained by Exponent

Status Flags

The status_flags field is a bitfield. Each bit blocks a specific class of vault operation:
/// Block queue_withdrawal
pub const FLAG_WITHDRAWALS_BLOCKED: u8 = 1 << 0;  // 0x01

/// Block strategy execution (manager invoke with policy)
pub const FLAG_MANAGER_INVOKE_BLOCKED: u8 = 1 << 1;  // 0x02

/// Block user force deallocate
pub const FLAG_USER_INVOKE_BLOCKED: u8 = 1 << 2;  // 0x04
The sentinel role (typically maintained by Exponent) can set or clear these flags at any time.

StrategyPosition

Strategy positions are tracked for AUM calculation. Each variant represents a different deployment type:
pub enum StrategyPosition {
    /// Position in an Exponent orderbook (PT/YT offers)
    Orderbook(OrderbookEntry),
    /// Position in one or more token accounts (generic)
    TokenAccount(TokenAccountEntry),
    /// Position in a lending obligation (Kamino, etc.)
    Obligation(ObligationType),
}
For Kamino integrations, positions are stored as StrategyPosition::Obligation(ObligationType::KaminoObligation(...)).

ProposalVoteConfig

Governs the rejection-based voting system for vault policies. Proposals are approved by default after the timelock expires unless enough LP holders vote to reject.
FieldDefaultDescription
min_voting_period_seconds3,600 (1h)Minimum time proposals must be open for voting
max_voting_period_seconds604,800 (7d)Maximum voting duration
default_voting_period_seconds172,800 (48h)Default voting window
default_timelock_seconds86,400 (24h)Delay after voting ends before execution
rejection_threshold_bps330,000 (33%)Fraction of LP supply needed to reject a proposal
next_proposal_id0Auto-incrementing counter for proposal IDs
voting_enabledtrueWhether the voting mechanism is active

PDA Derivation

import { ExponentVaultsPDA } from "@exponent-labs/exponent-vaults-pda";

const pda = new ExponentVaultsPDA();

// All PDA methods return [PublicKey, bump] tuples
const [vault] = pda.vault({ seedId });
const [mintLp] = pda.mintLp({ vault });
const [tokenLpEscrow] = pda.tokenLpEscrow({ vault });
const [tokenEscrow] = pda.tokenEntryEscrow({ vault, mint });