Skip to main content
Raydium’s newer programs (CPMM, CLMM, Farm v6, LaunchLab) are written in Anchor — a Rust framework that builds on Solana’s native program model to provide account validation, error handling, and an IDL (interface description). AMM v4 and older farms predate Anchor. Understanding both paradigms helps you read the code, generate clients from the IDL, and debug unexpected errors.

Program deployment model

Every Solana program lives at a Pubkey. The program’s bytecode is stored in an executable account owned by the BPF Upgradable Loader (BPFLoaderUpgradeab1e11111111111111111111111). A program deployment comprises three accounts:
  1. Program account: small metadata account at the program’s ID. Owner: BPF Upgradable Loader.
  2. ProgramData account: holds the actual bytecode. Derived as [program_id, "programdata"].
  3. Buffer account (transient): holds new bytecode during an upgrade. Discarded after the upgrade.
The ProgramData account has an upgrade authority — a key that can replace the bytecode with a new version. Raydium’s upgrade authority is a multisig behind a 24-hour timelock; see security/admin-and-multisig.

Verifying a deployed program

To confirm what’s on-chain matches what’s in the audit-approved source:
Matching hashes prove you’re interacting with the source you think you are. Raydium publishes verified-build instructions in the release notes.

Anchor: a framework on top of Solana

Raw Solana programs are Rust functions with this signature:
Anchor wraps all the boilerplate and lets you write:
Anchor:
  • Auto-generates a deterministic 8-byte discriminator for each instruction and each account type.
  • Validates account constraints (owner, seeds, writable, signer, mint-matches, token-program-matches) before your code runs.
  • Generates an IDL — an interface description file that clients use to call the program.
  • Ships with a Rust, TypeScript, and Python client-side library.

The 8-byte discriminator

Every Anchor account and every Anchor instruction starts with an 8-byte discriminator — the first 8 bytes of SHA-256 of a fixed string:
When you call an Anchor instruction, the first 8 bytes of the instruction data are this discriminator; Anchor dispatches to the right handler by looking them up. When you read an Anchor account, the first 8 bytes tell you its type — crucial for tools like getProgramAccounts that enumerate all accounts of a type.

Errors

Anchor programs define errors via #[error_code]:
Anchor auto-assigns these numeric codes starting from 6000 (0x1770). Raydium’s full error-code table is in reference/error-codes.

The IDL

An Anchor IDL (Interface Description Language) file is a JSON description of a program: its instructions, accounts, types, errors, and events. It’s the equivalent of an Ethereum ABI. Raydium publishes IDLs for all Anchor programs. Fetch live from on-chain:
Or from the SDK source: src/raydium/*/idl/*.json.

IDL structure

Generating a client from the IDL

Anchor’s anchor CLI generates TypeScript and Rust types:
Third-party tools like Kinobi can generate Rust, Python, C, or Go clients from an IDL.

When the IDL is your friend

If you want to build a custom integration that doesn’t go through Raydium SDK:
  1. Fetch the IDL (live from on-chain or from SDK source).
  2. Look up the instruction you want (e.g., swap_base_input).
  3. Construct the instruction data: 8-byte discriminator + encoded args.
  4. Pass accounts in the order the IDL specifies.
See sdk-api/anchor-idl for worked examples.

Pre-Anchor programs: AMM v4 and Farm v3/v5

These programs predate Anchor. They use:
  • Manual instruction dispatch: a u8 tag in instruction_data with a match statement.
  • Manual account validation: if accounts[0].owner != &expected_program { ... }.
  • Borsh-serialized instruction args: no discriminator, just instruction_data[1..].
  • Layout via #[repr(C, packed)]: C-struct binary layout.
Raydium SDK v2 ships TypeScript layouts for the non-Anchor AMM v4 instructions so clients can encode/decode without Anchor:
The integration pattern is the same — you just don’t get Anchor’s IDL-driven auto-generation.

Program upgrade mechanics

Only the ProgramData’s upgrade_authority can upgrade. Steps:
  1. Compile the new bytecode.
  2. Write it to a buffer account (solana program write-buffer).
  3. Submit an upgrade instruction: BpfLoaderUpgradeable::Upgrade { buffer, program, authority }.
  4. The runtime atomically replaces the program’s bytecode with the buffer’s contents.
Raydium gates this behind a 24-hour timelock implemented in the Squads multisig’s settings. An upgrade transaction must wait 24 hours after multisig approval before execution. This protects against rushed / coerced upgrades. See security/admin-and-multisig.

Making a program immutable

An upgrade authority can be set to None, at which point the program becomes permanently immutable. Raydium hasn’t done this for any product — the team retains the ability to push security fixes. Trade-off: users must trust the multisig + timelock process.

Programs and rent

Deploying a program consumes rent-exempt lamports:
  • A 50 KB program: ~0.35 SOL in rent.
  • A 200 KB program: ~1.4 SOL in rent.
Closing a program (via solana program close) returns the lamports. Raydium programs remain active and aren’t scheduled for closure.

Debugging Anchor programs

Log output

Anchor’s msg! macro writes to the transaction’s log. Simulate a transaction to see logs:
Logs include:
  • Program invocation (Program CPMMoo8... invoke [1]).
  • msg! calls from program code.
  • Compute unit consumption (consumed 137842 of 400000 compute units).
  • Program success or error.

Error codes

If an Anchor program throws, the log shows:
0x1770 = 6000 decimal = the first Anchor error (e.g., SlippageExceeded). Cross-reference with the IDL’s errors array. See reference/error-codes for Raydium’s full error table.

Account layout mismatches

If you pass the wrong account in the wrong slot, Anchor’s account-validation macros return errors like:
Error numbers below 6000 are Anchor’s built-in errors (see Anchor’s ErrorCode enum); errors ≥6000 are the program’s custom codes.

Pointers

Sources: