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

# Farm / Staking 指令

> CreateFarm、Deposit、Withdraw、Harvest、AddReward / SetRewards / RestartRewards、WithdrawReward — farm v3、v5 與 v6 的完整指令介面。

<Info>
  **本頁內容由 AI 自動翻譯，所有內容以英文版本為準。**

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

<Info>
  Farm 指令因版本而異。v6 上的 `Deposit` 無法在 v5 farm 上呼叫，反之亦然。SDK 會透過讀取 farm 的程式擁有者來進行分派；如需鏈上 CPI，你必須事先選擇正確的程式 ID。
</Info>

## 指令清單

| 用途                | v3                  | v5                       | v6               |
| ----------------- | ------------------- | ------------------------ | ---------------- |
| 建立 farm           | `CreateFarm`        | `CreateFarm`             | `CreateFarm`     |
| 新增使用者帳本（可能隱含）     | `CreateUserLedger`  | `CreateAssociatedLedger` | 隱含於 `Deposit`    |
| 質押                | `Deposit`           | `Deposit`                | `Deposit`        |
| 取消質押              | `Withdraw`          | `Withdraw`               | `Withdraw`       |
| 僅領取獎勵             | N/A（使用 `Deposit 0`） | N/A（使用 `Deposit 0`）      | `Harvest`        |
| 建立後新增獎勵流          | N/A                 | `AddReward`              | `AddReward`      |
| 編輯現有獎勵流           | N/A                 | `SetRewards`             | `SetRewards`     |
| 在 end\_time 後重啟獎勵 | N/A                 | `RestartRewards`         | `RestartRewards` |
| 提取未領取的獎勵預算（管理）    | N/A                 | `WithdrawReward`         | `WithdrawReward` |

在 v3 和 v5 上，不改變質押而領取獎勵的標準方式是呼叫 `Deposit` 並設定 `amount = 0`。程式將其視為純粹的結算。v6 引入了明確的 `Harvest` 以提高清晰度。

SDK 將這些全部抽象化為 `raydium.farm.deposit({ ... })` 等呼叫。以下各節記錄了基礎帳戶清單，供需要手動構建指令的整合者使用（聚合器、監測工具、SDK 擴展）。

## `CreateFarm` (v6)

啟動新的 v6 farm。

**引數**

```
reward_info_count: u8               // 建立時的獎勵流數量 (1..=5)
reward_infos: [
  {
    open_time:            u64,
    end_time:             u64,
    emission_per_second_x64: u128,   // Q64.64
    mint:                 Pubkey,    // 獎勵 mint
    token_program:        Pubkey,    // SPL 或 Token-2022
  }
]
```

**帳戶**（簡化版，`reward_info_count = 1`）

| #  | 名稱                         | W | S | 備註                         |
| -- | -------------------------- | - | - | -------------------------- |
| 1  | `creator`                  | W | S | 支付租金，擁有 farm。              |
| 2  | `farm_state`               | W |   | 新的 `FarmState` 帳戶。         |
| 3  | `farm_authority`           |   |   | PDA `[farm_id]`。           |
| 4  | `staking_mint`             |   |   |                            |
| 5  | `staking_vault`            | W |   | 建立為授權簽署者的 ATA 或 PDA 保險庫。   |
| 6  | `staking_token_program`    |   |   |                            |
| 7  | `reward_mint`              |   |   |                            |
| 8  | `reward_vault`             | W |   | 將接收初始預算。                   |
| 9  | `reward_token_program`     |   |   |                            |
| 10 | `reward_sender_ata`        | W |   | 建立者在獎勵 mint 上的 ATA；由此指令消耗。 |
| 11 | `system_program`           |   |   |                            |
| 12 | `token_program`            |   |   |                            |
| 13 | `associated_token_program` |   |   |                            |
| 14 | `rent`                     |   |   |                            |

**前置條件**

* `open_time > now`，`end_time > open_time`。
* `creator` ATA 至少持有 `emission_per_second_x64 × (end_time − open_time) / 2^64` 的獎勵 mint。
* `staking_mint` 沒有凍結授權，或凍結授權已禁用。

**後置條件**

* `FarmState` 初始化完成，`total_staked = 0`。
* 獎勵保險庫資金充足，包含完整流預算。
* 建立者的獎勵 ATA 消耗相應金額。

## `Deposit` (v6)

質押質押 mint 的 `amount`。

**引數**

```
amount: u64
```

**帳戶**

| #        | 名稱                         | W | S |
| -------- | -------------------------- | - | - |
| 1        | `user`                     | W | S |
| 2        | `user_ledger`              | W |   |
| 3        | `farm_state`               | W |   |
| 4        | `farm_authority`           |   |   |
| 5        | `staking_vault`            | W |   |
| 6        | `user_staking_ata`         | W |   |
| 7..(7+n) | `reward_vault_{i}`         | W |   |
| ...      | `user_reward_ata_{i}`      | W |   |
| last−2   | `system_program`           |   |   |
| last−1   | `token_program`            |   |   |
| last     | `associated_token_program` |   |   |

如果 `user_ledger` 不存在，SDK 會前置一個 `CreateAccount` 風格的指令；v6 程式也可以透過系統程式帳戶惰性建立它。剩餘帳戶模式：針對每個有效的獎勵，附加 `(reward_vault, user_reward_ata)`，以便結算可以支付。

**效果**

1. 使用惰性更新公式為每個有效獎勵流重新整理 `reward_per_share_x64[i]`。
2. 計算 `pending_i = user_ledger.deposited × reward_per_share_x64[i] / 2^64 − user_ledger.reward_debts[i]`。
3. 從 `reward_vault_{i}` 轉移 `pending_i` 至 `user_reward_ata_{i}`。
4. 從 `user_staking_ata` 轉移 `amount` 質押 mint 至 `staking_vault`。
5. 更新 `user_ledger.deposited += amount` 並重新快照 `reward_debts[i]`。
6. 更新 `farm_state.total_staked += amount`。

**前置條件**

* `amount > 0` 才能進行真實質押（v6 禁止 `amount = 0` — 僅領取時使用 `Harvest`）。
* `user_staking_ata` 至少持有 `amount`。
* 每個有效獎勵保險庫至少持有欠此使用者的待領金額。

## `Withdraw` (v6)

取消質押 `amount`。

**引數**

```
amount: u64
```

**帳戶** — 與 `Deposit` 相同。

**效果** — 執行與 `Deposit` 相同的結算，然後將質押 mint 移回使用者：`staking_vault → user_staking_ata`。`total_staked` 和 `user_ledger.deposited` 都會減少。

**前置條件**

* `amount ≤ user_ledger.deposited`。
* Farm 未暫停。

## `Harvest` (v6)

領取待領獎勵而不改變質押。

**引數** — 無。

**帳戶** — 與 `Deposit` 相同，質押端無動作。

**效果** — 重新整理 `reward_per_share_x64[i]`，支付 `pending_i`，重新快照 `reward_debts[i]`。`total_staked` 或 `deposited` 無變化。

## `AddReward` (v5/v6)

為有可用插槽的現有 farm 新增新獎勵流。

**引數**

```
reward_info: {
  open_time:            u64,
  end_time:             u64,
  emission_per_second_x64: u128,
  mint:                 Pubkey,
  token_program:        Pubkey,
}
```

**前置條件**

* 存在可用插槽（v6 上 `reward_info_count < 5`，v5 上 `< 2`）。
* `open_time ≥ now`（可能在未來），或 `open_time < now` 僅在程式版本允許時才可——v6 允許，v5 不允許。

**後置條件**

* 新流在索引 `reward_info_count` 處初始化，`reward_info_count++`。
* 獎勵保險庫由呼叫者的 ATA 記入完整流預算。

**常見錯誤** — 如果 mint 與現有插槽衝突，則為 `RewardAlreadyExists`。

## `SetRewards` (v5/v6)

延長或補充現有獎勵流。無法變更 mint；無法縮短 `end_time`；執行後無法降低 `emission_per_second_x64`。

**引數**

```
reward_index:         u8
new_open_time:        u64,
new_end_time:         u64,
new_emission_per_second_x64: u128,
```

**前置條件**

* 流仍在執行中（`reward_state == 1`）。
* `new_end_time ≥ 當前 end_time`。
* 所需的額外預算 `(new_emission × new_duration − already_emissioned)` 存在於寄件者的 ATA 中，並由指令轉移至獎勵保險庫。

在 v5 上，等效呼叫為 `SetRewards`，引數集較小（執行中的流無每秒變更）。

## `RestartRewards` (v5/v6)

在流的 `end_time` 已過後重啟流。概念上與已有插槽的 mint 的 `AddReward` 相同。

**引數** — 與該索引的 `AddReward` 相同的形狀。

**前置條件**

* `reward_state == 2`（已結束）。
* 呼叫者是插槽的 `reward_sender`（v6）或 farm `owner`（v5）。

## `WithdrawReward` (v5/v6)

在流已結束且所有質押者都有機會領取的情況下，對未領取獎勵保險庫餘額進行管理掃除。

**引數**

```
reward_index: u8
```

**前置條件**

* 流已結束（`reward_state == 2`）。
* `reward_total_emissioned == reward_claimed + vault_balance`（無待結算）。

**效果** — 將餘額轉移至 `reward_sender_ata`。程式不會阻止在質押者仍有待領索賠的情況下進行提取；預期管理員首先代表落後的質押者進行領取（或讓他們自行領取）。如果你提前掃除，使用者將失去對未領獎勵的存取權。**不要提前呼叫此指令。**

## v5 變異

* `Deposit` / `Withdraw` 的形狀與 v6 相同，但使用最多 2 個獎勵插槽，`reward_per_share` 為 `u128`（具有不同基數的定點）。
* `CreateAssociatedLedger` 是第一次 `Deposit` 前的必需單獨呼叫；v6 將其合併。
* `AddReward` 可用，`Harvest` 不可用（使用 `Deposit 0`）。

## v3 變異

* 單一獎勵流。無 `AddReward`，無第二個插槽。
* `Deposit 0` 是唯一的領取方式。
* `CreateUserLedger` 必須在第一次 `Deposit` 前呼叫。

## 狀態變化矩陣

| 指令               | `total_staked` | `user.deposited` | `reward_per_share` | 獎勵保險庫    |
| ---------------- | -------------- | ---------------- | ------------------ | -------- |
| `CreateFarm`     | 0              | —                | 0                  | 由建立者資金充足 |
| `Deposit(n)`     | +n             | +n               | 重新整理               | −待領（已支付） |
| `Withdraw(n)`    | −n             | −n               | 重新整理               | −待領      |
| `Harvest`        | —              | —                | 重新整理               | −待領      |
| `AddReward`      | —              | —                | —                  | +新預算     |
| `SetRewards`     | —              | —                | —                  | +差異預算    |
| `RestartRewards` | —              | —                | —                  | +預算      |
| `WithdrawReward` | —              | —                | —                  | −餘額      |

## 接下來前往

* [`products/farm-staking/code-demos`](/zh-Hant/products/farm-staking/code-demos) — TypeScript 範例。
* [`products/farm-staking/accounts`](/zh-Hant/products/farm-staking/accounts) — `FarmState` / `UserLedger` / `UserStake` 配置。
* [`reference/error-codes`](/zh-Hant/reference/error-codes) — farm 錯誤列舉。

資源：

* [Raydium SDK v2 `Farm` 模組](https://github.com/raydium-io/raydium-sdk-V2)
* Raydium farm 程式原始碼（v3 / v5 / v6）
