Developers

Everything you need to interact with the Reflex program directly, without the frontend.

Program ID

7mSqZcYPUGm99M6sGpNRHjorbB1NPF3ThyTpEjhkKzKF

Mainnet, Anchor framework. Supports both SPL Token and Token-2022 mints.

IDL

The full IDL is in the GitHub repoarrow-up-right. You can also fetch it on-chain:

import { Program } from "@coral-xyz/anchor";
const idl = await Program.fetchIdl("7mSqZcYPUGm99M6sGpNRHjorbB1NPF3ThyTpEjhkKzKF", provider);

PDA Seeds

All accounts are derived from these seeds:

Account
Seeds
Description

Config

["config"]

Global program config (one per program)

Pool

["pool", token_mint]

Pool state for a specific token

Token Vault

["token_vault", pool]

Holds staked tokens

SOL Vault

["sol_vault", pool]

Holds SOL rewards

Stake Lot

["lot", pool, user, lot_seed]

Individual stake position

Deriving PDAs in TypeScript

Instructions

1

Initialize Pool (permissionless)

Creates a staking pool for any token mint. Anyone can call this.

Args:

  • creator_wallet (Pubkey) — the wallet that can also call fund_rewards for this pool

  • tier_multipliers (Option<[u64; 6]>) — custom multipliers or null for defaults

Accounts:

  • authority — signer, writable (pays rent)

  • config — PDA ["config"]

  • token_mint — the token mint (SPL Token or Token-2022)

  • pool — PDA ["pool", token_mint], writable

  • token_vault — PDA ["token_vault", pool], writable

  • sol_vault — PDA ["sol_vault", pool], writable

  • token_program — SPL Token or Token-2022 program

  • system_program

Blocked: Tokens with an active freeze authority or dangerous Token-2022 extensions.

2

Stake

Stakes tokens into a pool. Creates a new StakeLot PDA.

Args:

  • amount (u64) — tokens to stake, in smallest unit (raw amount with decimals)

  • tier (StakingTier enum) — lock tier

  • lot_seed (u64) — unique seed for this lot (e.g. Date.now())

Accounts:

  • user — signer, writable

  • pool — PDA ["pool", token_mint], writable

  • stake_lot — PDA ["lot", pool, user, lot_seed], writable

  • user_token_account — user's ATA, writable

  • token_vault — PDA ["token_vault", pool], writable

  • token_mint — the token mint

  • token_program — SPL Token or Token-2022

  • system_program

Tier enum values:

Variant
Index
Lock
Multiplier

Flexible

0

None

1.00x

Hours24

1

1 day

1.15x

Hours72

2

3 days

1.25x

Week1

3

7 days

1.40x

Month1

4

30 days

1.70x

Permanent

5

Forever

2.00x

3

Claim

Claims pending SOL rewards from a stake lot. Does not affect staked tokens.

Args: None

Accounts:

  • user — signer, writable

  • pool — PDA, writable

  • stake_lot — PDA, writable

  • sol_vault — PDA ["sol_vault", pool], writable

  • system_program

4

Unstake

Unstakes tokens after lock period expires. Automatically claims pending rewards. Closes the StakeLot account (rent returned to user). Permanent tier lots cannot be unstaked.

Args: None

Accounts:

  • user — signer, writable

  • pool — PDA, writable

  • stake_lot — PDA, writable

  • user_token_account — writable

  • token_vault — PDA, writable

  • token_mint

  • sol_vault — PDA, writable

  • token_program — SPL Token or Token-2022

  • system_program

5

Sync Rewards (permissionless)

Detects SOL that has been sent to the pool's SOL vault and distributes it to stakers by updating the per-share accumulator. Anyone can call this.

Args: None

Accounts:

  • payer — signer (pays tx fee only)

  • pool — PDA, writable

  • sol_vault — PDA ["sol_vault", pool]

This is the key instruction for the crank bot. It compares the actual SOL vault balance against what the pool expects, and treats any excess as new rewards. 100% goes to stakers.

6

Fund Rewards

Deposits SOL directly into a pool's reward vault. Updates acc_sol_per_share so all stakers' pending rewards increase. Can be called by the global authority or the pool's creator wallet.

Args:

  • amount (u64) — lamports to deposit

Accounts:

  • funder — signer, writable

  • config — PDA ["config"]

  • pool — PDA, writable

  • sol_vault — PDA, writable

  • system_program

Reading Pool State

Fetch any pool account to see total staked, total shares, reward accumulator, etc:

Reading Stake Lots

Find all stake lots for a user across all pools:

Calculating Pending Rewards

Error Codes

Code
Name
Meaning

6000

InvalidTier

Bad tier value

6001

UnstakeTooEarly

Lock period hasn't expired

6002

UnstakeNotAllowed

Permanent tier, can't unstake

6003

MathOverflow

Arithmetic overflow

6004

Unauthorized

Not authorized for this action

6005

InvalidAmount

Amount must be > 0

6006

LotNotActive

Lot already unstaked

6007

InvalidTokenProgram

Must use SPL Token or Token-2022

6008

TokenMintMismatch

Wrong token mint

6009

InvalidMultipliers

Multipliers out of range

6010

InsufficientFunds

Not enough SOL in vault

6011

NoRewardsToClaim

Nothing to claim

6014

UnsupportedTokenExtension

Blocked Token-2022 extension

6015

ZeroShares

Amount too small for any shares

6017

ClaimTooEarly

Must wait 60s after staking

6018

NoStakers

Can't fund empty pool

Events

The program emits events you can subscribe to or parse from transaction logs:

  • Staked — pool, user, lot, amount, shares, tier, unlock_at, timestamp

  • Claimed — pool, user, lot, amount, timestamp

  • Unstaked — pool, user, lot, amount, shares_removed, rewards_claimed, timestamp

  • RewardsFunded — pool, funder, amount, distributed_amount, new_acc_sol_per_share, total_shares, timestamp

  • RewardsSynced — pool, syncer, new_rewards, new_acc_sol_per_share, total_shares, timestamp

  • PoolInitialized — pool, token_mint, creator_wallet, tier_multipliers, timestamp