> ## 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.

# 农场/质押账户

> FarmState、UserStake/Ledger、奖励金库及权限 PDA — 农场 v3、v5 和 v6 的布局与 PDA 种子。

<Info>
  **本页内容由 AI 自动翻译，所有内容以英文版本为准。**

  [查看英文版 →](/products/farm-staking/accounts)
</Info>

<Info>
  **三个程序，三个数据结构。** 农场 v3、v5 和 v6 是独立的程序，各有自己的状态布局。本页并行文档化它们各自的结构。实际上大多数新集成都针对 v6；对于大多数集成方来说，v3 和 v5 是只读的（质押早已发生，这些池已处于风险管理阶段）。
</Info>

## 账户清单（每个农场，所有版本）

| 账户                                   | 所有者            | 用途                                       |
| ------------------------------------ | -------------- | ---------------------------------------- |
| `FarmState`                          | 农场程序（v3/v5/v6） | 根状态：质押 mint、总质押量、奖励流。                    |
| `farm_authority`                     | 农场程序           | 拥有质押金库和奖励金库的 PDA。                        |
| `staking_vault`                      | SPL 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 是当前版本，其账户结构最具通用性。

```rust theme={null}
// 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_mint`、`staking_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_x64`** — `UserLedger` 用来计算债务的计数器。

## `FarmState` 布局 — v5

```rust theme={null}
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_second` 是 `u64`。这使可表达的最小速率限制在每秒 1 单位，对于 9 位小数 mint 的低发放流来说过粗糙。v6 用 Q64.64 速率解决了这个问题。
* **没有 `reward_sender`**。在 v5 上，owner 是隐含的发送方；只有 `owner` 能够充值。

## `FarmState` 布局 — v3

```rust theme={null}
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：

```ts theme={null}
// 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 源代码进行验证。）

```rust theme={null}
// 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]
```

每次 `Deposit`、`Withdraw` 或 `Harvest` 之后，债务被重置为当前的 `deposited × reward_per_share_x64[i] / 2^64`。

## 权限 PDA

```ts theme={null}
// 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`。

## 后续阅读

* [`products/farm-staking/instructions`](/zh/products/farm-staking/instructions) — 各版本指令参考。
* [`products/farm-staking/code-demos`](/zh/products/farm-staking/code-demos) — 通过 SDK 进行质押、收获和创建农场。
* [`reference/program-addresses`](/zh/reference/program-addresses) — 所有三个程序 ID。

资源：

* [Raydium SDK v2 `Farm` 模块](https://github.com/raydium-io/raydium-sdk-V2)
* 农场 v6 程序源代码目前未作为独立仓库发布；IDL 打包在 [`raydium-io/raydium-sdk-V2`](https://github.com/raydium-io/raydium-sdk-V2) 中的 `src/raydium/farm/` 下。
