Skip to main content

Overview

Pair accounts link RWA tokens to stablecoins, enabling trading between them. Each pair is owned by a specific Liquidity Provider (LP) who controls its configuration, fees, and liquidity.

Account Structures

Pair Account

PDA Seeds: ["pair", liquidity_provider, stable_mint, asset_mint]

LpStableConfig Account

PDA Seeds: ["lp_stable_config", stable_mint, liquidity_provider]

UserVaultInfo Account

PDA Seeds: ["user_vault_info", mint_address, liquidity_provider]

VaultAuthority PDA

PDA Seeds: ["vault_authority", liquidity_provider]
For permissioned mints (tokens), the issuer must separately whitelist (allowlist) both the liquidity_provider address and the derived vault_authority PDA. The LP address owns the source token account; the PDA owns the destination vault ATA. Approval of one address does not apply to the other.The corresponding LP-owned token account and PDA-owned vault ATA must also be thawed before a transfer can succeed. Creating the pair or vault ATA does not perform issuer whitelisting or thawing.
The vault_authority PDA is LP-specific and owns that LP’s vault token accounts. The vault token accounts themselves are associated token accounts for (mint, vault_authority), so they are keyed by LP and mint without using the global program authority.

Pair Instructions

init_pair

Create a new trading pair. The LP signs and pays for all account creation; the configured global-config admin is referenced as a non-signing account and checked by has_one.

Parameters

Required Accounts

Behavior

  • Creates Pair PDA account, paid for by the LP
  • Validates that asset_config_stable.asset_type == Stable and asset_config_rwa.asset_type == Rwa
  • Creates or updates LpStableConfig for LP/stablecoin
  • Creates vault ATAs owned by the LP’s vault_authority PDA if they don’t exist
  • Creates UserVaultInfo accounts to track vault usage
  • Increments used_in_pairs_count on both asset configs
  • Initializes redemption_fee_bps and discount_rate_bps from the instruction arguments
  • Requires program to be unpaused
  • Pair pause state defaults to unpaused unless the LP later pauses it with update_pair

Access Control

Access: LP (signs as liquidity_provider). The admin account must be provided and is verified against global_config.admin via has_one, but admin does not sign.
Swaps still require every pause gate to be open: global config, both asset configs, the LP stable config, and the pair itself.

Example


update_pair

Update pair configuration (fees and pause state).

Parameters

Required Accounts

Behavior

  • Updates fee configuration
  • Updates pause state
  • Requires program to be unpaused
  • Validates both fee values are <= 9900

Access Control

Access: LP (pair owner) only

Example


close_pair

Permanently close a trading pair. The LP signs and receives the reclaimed rent for the pair account and any closed vault accounts; the configured global-config admin is referenced as a non-signing account and checked by has_one.

Required Accounts

Behavior

  • Closes Pair account
  • Requires program to be unpaused
  • Decrements used_in_pairs_count on both asset configs
  • Returns remaining vault tokens to the LP’s recipient token accounts
  • Closes vault ATAs if no longer used by other pairs
  • Closes the corresponding UserVaultInfo PDAs when their used count reaches 0
  • Returns reclaimed rent (Pair PDA, closed vault ATAs, and closed UserVaultInfo PDAs) to the LP
Closing a pair reclaims rent and clears the pair’s configuration (fees, pause state). The LP can re-initialize a pair for the same (stable, asset) combination later via init_pair, but it will start with fresh configuration — prior fee settings are not restored.

Access Control

Access: LP (pair owner). The admin account must be provided and is verified against global_config.admin via has_one, but admin does not sign.

set_paused_for_lp_stable_config

Set pause state for all pairs of an LP/stablecoin combination.

Parameters

Required Accounts

Behavior

  • Updates pause state on LpStableConfig
  • Affects ALL pairs using this LP/stablecoin combination
  • Requires program to be unpaused

Access Control

Access: Admin OR LP (config owner)

Liquidity Instructions

add_liquidity

Deposit tokens into a vault.

Parameters

Required Accounts

Behavior

  • Transfers tokens from LP’s account to vault
  • Vault is the mint’s ATA owned by the LP’s vault_authority PDA
  • Requires program to be unpaused
  • Amount must be greater than 0

Access Control

Access: LP (vault owner) only

Example


remove_liquidity

Withdraw tokens from a vault.

Parameters

Required Accounts

Same as add_liquidity.

Behavior

  • Transfers tokens from vault to LP’s account
  • Vault is the mint’s ATA owned by the LP’s vault_authority PDA
  • Requires program to be unpaused
  • Amount must be greater than 0
  • Vault must have sufficient balance

Access Control

Access: LP (vault owner) only

Vault Architecture

Shared Vault Model

Vaults are shared across pairs for the same LP/token combination. Each LP has a vault_authority PDA, and each vault is the associated token account for (mint, vault_authority):

UserVaultInfo Tracking

The UserVaultInfo account tracks how many pairs use each vault:
  • Incremented when pair is created
  • Decremented when pair is closed
  • Vault closed only when used reaches 0
This ensures vaults aren’t closed while still in use by other pairs.

Error Codes


Next: Price Sources

Learn about NAV pricing sources and oracle integration