跳转到主要内容

Documentation Index

Fetch the complete documentation index at: https://docs.raydium.io/llms.txt

Use this file to discover all available pages before exploring further.

本页内容由 AI 自动翻译,所有内容以英文版本为准。查看英文版 →
三个程序,三个数据结构。 农场 v3、v5 和 v6 是独立的程序,各有自己的状态布局。本页并行文档化它们各自的结构。实际上大多数新集成都针对 v6;对于大多数集成方来说,v3 和 v5 是只读的(质押早已发生,这些池已处于风险管理阶段)。

账户清单(每个农场,所有版本)

账户所有者用途
FarmState农场程序(v3/v5/v6)根状态:质押 mint、总质押量、奖励流。
farm_authority农场程序拥有质押金库和奖励金库的 PDA。
staking_vaultSPL Token持有质押的 LP(或其他质押 mint)。
reward_vault_{i}SPL Token持有奖励流 i 的未分发预算。每个流一个。
UserStake(v3/v5)/ UserLedger(v6)农场程序每个 (farm, user) 的账本:质押金额 + 每个流的单位奖励快照。
SDK 通过 raydium.farm.getFarmById 返回完整集合。对于任意第三方农场,API 端点 GET https://api-v3.raydium.io/main/farms/info?ids=<FARM_ID> 也会返回它们。

FarmState 布局 — v6

v6 是当前版本,其账户结构最具通用性。
// programs/farm_v6/src/state/farm.rs (abridged)
pub struct FarmState {
    pub state: u64,                // bitfield: 0 = live, 1 = paused, ...
    pub nonce: u64,                 // bump for farm_authority
    pub creator: Pubkey,            // original creator (can add rewards / transfer admin)
    pub staking_mint: Pubkey,
    pub staking_vault: Pubkey,
    pub staking_token_program: Pubkey, // SPL Token or Token-2022
    pub lp_mint_decimals: u8,
    pub reward_period_len: u64,     // minimum duration between SetRewards edits
    pub reward_period_min: u64,
    pub total_staked: u64,
    pub reward_info_count: u8,
    pub _reserved: [u8; ...],
    pub reward_infos: [RewardInfo; 5], // up to 5 reward streams
}

pub struct RewardInfo {
    pub reward_state: u8,           // 0 = unused, 1 = running, 2 = ended
    pub open_time: u64,             // start_time
    pub end_time: u64,
    pub last_update_time: u64,
    pub emission_per_second_x64: u128, // Q64.64 fixed-point rate
    pub reward_total_emissioned: u64,   // sum of emissions so far
    pub reward_claimed: u64,            // sum paid out to stakers
    pub reward_vault: Pubkey,
    pub reward_mint: Pubkey,
    pub reward_sender: Pubkey,          // who deposited the budget; can top up
    pub reward_token_program: Pubkey,   // SPL or Token-2022
    pub reward_per_share_x64: u128,     // Q64.64 counter
}
集成方相关的字段:
  • staking_mintstaking_vault — 被质押的资产及其位置。
  • total_staked — 当前总量。计算 APR 必需:reward_per_second × 86400 / total_staked
  • reward_infos[i].emission_per_second_x64 — Q64.64 格式的速率。除以 2^64 得真实的每秒代币数。
  • reward_infos[i].open_time / end_time — 用于 UI 显示”还剩 X 天”。
  • reward_infos[i].reward_per_share_x64UserLedger 用来计算债务的计数器。

FarmState 布局 — v5

pub struct FarmStateV5 {
    pub state: u64,
    pub nonce: u64,
    pub lp_vault: Pubkey,            // aka staking_vault
    pub reward_vaults: [Pubkey; 2],
    pub owner: Pubkey,
    pub reward_mints: [Pubkey; 2],
    pub reward_total_emissioned: [u64; 2],
    pub reward_claimed: [u64; 2],
    pub reward_per_second: [u64; 2],  // integer, not fixed-point
    pub reward_open_time: [u64; 2],
    pub reward_end_time: [u64; 2],
    pub reward_per_share: [u128; 2],  // Q56.8 or similar; check program source
    pub total_staked: u64,
    pub last_slot: u64,               // v5 updates per-slot on mainnet
    pub _reserved: [u8; 256],
}
与 v6 的区别:
  • 按区块而非按秒。 v5 的更新循环按区块而非挂钟时间运行。SDK 会将其规范化为”每秒”用于 UI,但链上单位是区块。
  • 整数发放速率。 reward_per_secondu64。这使可表达的最小速率限制在每秒 1 单位,对于 9 位小数 mint 的低发放流来说过粗糙。v6 用 Q64.64 速率解决了这个问题。
  • 没有 reward_sender。在 v5 上,owner 是隐含的发送方;只有 owner 能够充值。

FarmState 布局 — v3

pub struct FarmStateV3 {
    pub state: u64,
    pub nonce: u64,
    pub lp_vault: Pubkey,
    pub reward_vault: Pubkey,          // single reward
    pub owner: Pubkey,
    pub reward_mint: Pubkey,
    pub reward_total_emissioned: u64,
    pub reward_claimed: u64,
    pub reward_per_slot: u64,
    pub reward_per_share: u128,
    pub total_staked: u64,
    pub last_slot: u64,
    pub _reserved: [u8; 256],
}
单一奖励。基于区块。最古老的程序版本,为预先于 v5 的 RAY-USDC 和 SOL-USDC 农场保留。

UserLedger(v6)/ UserStake(v5/v3)

每个用户的状态,每个 (farm, user) 对应一个账户。Seeded PDA:
// v6
const [ledgerPda] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer(), user.toBuffer(), Buffer.from("user_stake_info_v2")],
  FARM_V6_PROGRAM_ID,
);

// v5
const [stakePda] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer(), user.toBuffer(), Buffer.from("user_stake_info")],
  FARM_V5_PROGRAM_ID,
);

// v3
const [stakePda] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer(), user.toBuffer(), Buffer.from("staker_info")],
  FARM_V3_PROGRAM_ID,
);
(种子字符串是 SDK 实际使用的值;程序版本过去有所变化。对于任何安全关键的内容,请根据 v6 源代码进行验证。)
// v6
pub struct UserLedger {
    pub version: u64,
    pub farm_id: Pubkey,
    pub owner: Pubkey,
    pub deposited: u64,                          // current stake
    pub reward_debts: [u128; 5],                 // snapshot of reward_per_share_x64 × deposited
}
每个流的债务是概述中描述的会计偏移量:
pending_for_stream_i = deposited × reward_per_share_x64[i] / 2^64  − reward_debts[i]
每次 DepositWithdrawHarvest 之后,债务被重置为当前的 deposited × reward_per_share_x64[i] / 2^64

权限 PDA

// v6
const [farmAuthorityV6] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer()],
  FARM_V6_PROGRAM_ID,
);

// v5
const [farmAuthorityV5] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer()],
  FARM_V5_PROGRAM_ID,
);

// v3
const [farmAuthorityV3] = PublicKey.findProgramAddressSync(
  [farmId.toBuffer()],
  FARM_V3_PROGRAM_ID,
);
所有三个版本都通过单一种子为每个农场派生农场权限。这个 PDA 是质押金库和每个奖励金库上的权限。它对农场进行的每笔转账都进行签名。

金库

质押和奖励金库是标准的 SPL Token 账户,其 owner 是农场权限 PDA。地址存储在 FarmState 上 — 不要重新派生;从状态中读取。质押 mint 上的冻结权限对于 v5/v6 必须被禁用(程序会检查)。 Token-2022 说明:
  • v3:仅 SPL Token。
  • v5:仅 SPL Token。
  • v6:在质押和奖励 mint 上都支持 Token-2022,由 staking_token_program / reward_token_program 字段限制。Token-2022 奖励 mint 上的转账费在发放时收取(金库 → 用户)。

观察和 APR

农场不在链上存储 APR。计算方法:
annualized_rewards_value_usd = reward_per_second × 86400 × 365 × reward_usd_price
tvl_usd                     = total_staked / 10^decimals × staking_mint_usd_price
apr                         = annualized_rewards_value_usd / tvl_usd
消费者通常通过 LP 所属的池(通过 api-v3.raydium.io/pools/info/ids)来获取 staking_mint_usd_price,并从任何价格预言机获取 reward_usd_price

后续阅读

资源: