System Overview
The Multiliquid Program is built on a modular, account-based architecture that enables atomic swaps between multiple permissioned Real World Asset (RWA) tokens and multiple stablecoins on Solana. The system is designed for institutional-grade operations with comprehensive access controls, transparent fee structures, and flexible pricing mechanisms.Design Principles
- Account-Based State: All state stored in Program-Derived Address (PDA) accounts
- Anchor Framework: Type-safe program development with automatic serialization
- Atomicity: All operations either fully succeed or fully revert within a transaction
- Transparency: All state changes emit comprehensive events via Anchor’s event system
- Extensibility: New assets can be integrated without program upgrades
Core Account System
The swap program’s primary account types work together to enable secure, atomic swaps between configured assets.How the Accounts Work Together
At the heart of the system, GlobalConfig acts as the central configuration holding program-wide settings including the admin, fee wallet, and protocol fees. When an admin registers a new token, an AssetConfig account is created to store the token’s NAV pricing sources and configuration. When a trading pair is created, a Pair account links two configured assets with settings specific to each capital provider, while LpStableConfig tracks the capital provider’s stablecoin-specific pause state. Token custody is managed through capital provider vault token accounts owned by a capital provider’s VaultAuthority PDA, with protocol fees collected in fee vault token accounts owned by the global ProgramAuthority PDA. This separation of concerns ensures each account focuses on its specialized responsibility while maintaining atomic execution.1. GlobalConfig Account
PDA Seeds:["global_config"]
The central configuration account managing program-wide settings.
Core Responsibilities
- Admin Management: Track current admin and pending admin transfer
- Fee Configuration: Store protocol fee percentage
- Global Pause: Control program-wide pause state
- Fee Wallet: Destination for claimed protocol fees
View GlobalConfig Reference
Program-wide settings and their effects on integrations
2. AssetConfig Account
PDA Seeds:["asset", mint_address]
Per-token configuration storing NAV pricing sources and asset-level controls.
Asset Types
Core Responsibilities
- NAV Pricing: Store and manage up to 5 pricing sources per asset
- Price Validation: Enforce maximum price divergence between sources
- Asset Pause: Independent pause control per asset
- Usage Tracking: Track how many pairs reference this asset
View AssetConfig Reference
Per-token NAV sources, classification, and pause state
3. Pair Account
PDA Seeds:["pair", liquidity_provider, quote_mint, base_mint]
Trading pair state linking two configured assets with configuration specific to each capital provider.
Core Responsibilities
- Fee Configuration: Store redemption and discount fees for each capital provider
- Pair Identity: Link specific quote and base tokens
- Capital Provider Ownership: Track the capital provider controlling this pair
- Pair Pause: Independent pause control per pair
View Pair Instructions
Complete instruction details for pair management
4. LpStableConfig Account
PDA Seeds:["lp_stable_config", stable_mint, liquidity_provider]
Configuration per capital provider and stablecoin for controlling multiple pairs at once.
Core Responsibilities
- Batch Pause Control: Pause all pairs for a specific capital provider/stablecoin combination
- Capital Provider Identification: Link configuration to specific capital provider
- Stablecoin Association: Scope configuration to specific stablecoin
5. Vault Accounts
VaultAuthority PDA Seeds:["vault_authority", liquidity_provider]
Capital Provider Vault Token Account: Associated token account for (mint_address, vault_authority)
ProgramAuthority PDA Seeds: ["program_authority"]
Fee Vault Token Account: Associated token account for (mint_address, program_authority)
Token accounts for custody and fee collection.
For permissioned mints, both the listed Capital Provider address and its listed Vault Authority (PDA) must be separately whitelisted (allowlisted) by the token issuer. Whitelisting the capital provider does not whitelist its PDA. The capital provider’s token account and PDA-owned vault ATA must also be thawed before liquidity or swap transfers can succeed.
Vault (Liquidity Custody)
- Holds liquidity for a specific capital provider/token combination
- Owned by the capital provider’s
vault_authorityPDA, not by the global program authority - Derived as the associated token account for the token mint and
vault_authority - Shared across multiple pairs using the same capital provider and token
- Tracked by
UserVaultInfoaccount for usage counting
Fee Vault (Protocol Fees)
- Created per asset when asset config is initialized
- Owned by the global
program_authorityPDA - Protocol fees accumulate in the configured fee-token vault
- Claimed via
claim_feesinstruction to fee wallet
6. UserVaultInfo Account
PDA Seeds:["user_vault_info", mint_address, liquidity_provider]
Tracks vault usage across pairs.
7. Vault and Program Authorities
VaultAuthority
PDA Seeds:["vault_authority", liquidity_provider]
The vault authority is a capital provider’s signer PDA used to own and authorize outbound transfers from capital provider liquidity vaults. Every vault for the same capital provider is an associated token account owned by this PDA.
ProgramAuthority
PDA Seeds:["program_authority"]
The program authority is a global signer PDA used for protocol fee vaults. It authorizes outbound transfers from fee vaults during claim_fees. It does not own capital provider liquidity vaults.
The capital provider’s protocol-fee token account is owned by a separate PDA derived from ["lp_fee_vault_authority", liquidity_provider]. Swaps debit this account to fund the global fee vault.
8. LpProtocolFeeConfig Account
PDA Seeds:["lp_protocol_fee_config", liquidity_provider]
This optional account stores the capital provider’s protocol-fee overrides and treasury_enabled flag. Without it, swaps use the global fee settings and Treasury routing is disabled. The admin sets fee overrides; the capital provider controls Treasury routing.
Treasury Accounts
The Treasury program maintains separate accounts under its own program ID:
For swap-integrated Treasury routing, the position owner is the capital provider’s swap vault-authority PDA. The capital provider opts in through
set_lp_treasury_enabled; eligible stablecoin inputs can be deposited into Treasury, and stablecoin output shortfalls can be redeemed from it. The Pair Management page describes the routing and withdrawal behavior.
Operational Flow
Swap Execution Flow
NAV Pricing System
The program supports four types of NAV (Net Asset Value) pricing sources:NavData Types
Price Aggregation
When multiple NAV sources are configured:- All prices are normalized to 9 decimal places
- Price divergence is validated against
price_difference_bpsas(max_nav - min_nav) / max_nav - If divergence exceeds threshold, the function returns 0 (blocking swaps)
- Average price is returned if all sources agree within tolerance
View Price Source Details
Complete documentation on NAV pricing configuration
Fee Structure
Protocol Fees
Configured inGlobalConfig.protocol_fees_bps, unless a capital provider protocol-fee configuration overrides the global defaults:
- Range: 0-9900 basis points (0% - 99%)
- Applied to all swaps regardless of direction
- Paid from the capital provider fee-token ATA into the configured global fee vault
- Claimed to
fee_walletviaclaim_feesinstruction
Capital Provider Fees
Configured per pair by the capital provider:Fee Calculation Order
Quote → Base (QuoteToBase):- Calculate the pair fee and protocol spread charge from the quote input
- Deduct both from the input amount
- Apply the NAV exchange rate to the post-fee amount
- Apply the NAV exchange rate
- Apply the pair fee and protocol spread charge to the quote equivalent
- Transfer the resulting quote output to the user
Permission Model
The program implements a comprehensive permission model:Admin Role
Controlled by:GlobalConfig.admin
Permissions:
- Initialize and update global configuration
- Set and confirm new admin (two-step transfer)
- Initialize asset configurations
- Update asset configurations
- Configure capital provider protocol-fee overrides
- Set pause state for assets and capital provider configs
Capital Provider Role
Identified by: Pair and vault ownership Permissions:- Initialize pairs and update pair configuration (fees, pause state)
- Close pairs they own
- Add and remove liquidity from their vaults
- Set pause state for their capital provider stable configs
User Role (Permissionless)
Anyone can:- Execute swaps on active pairs
- Claim protocol fees (sent to fee_wallet)
Permission Hierarchy
Event System
The program emits events for all significant state changes using Anchor’s event system:Swap Events
Administrative Events
Events are emitted for configuration changes, pair updates, liquidity operations, and pause state changes.Extensibility
The program’s modular architecture enables straightforward extension:Adding a New Pair
- Capital Provider Action: Call
init_pairspecifying the two mints in canonical byte order - Vaults Created: Automatic vault creation if needed
- Capital Provider Configuration: The capital provider calls
update_pairto adjust fees or pause state as needed - Add Liquidity: The capital provider adds tokens to vaults
- Enable Trading: Pair is ready for swaps
Next: Security & Access Control
Review the comprehensive security measures, access controls, and pause mechanisms