Các lệnh farm là tuỳ theo phiên bản. Một Deposit trên v6 không thể gọi được trên farm v5 và ngược lại. SDK phân phối bằng cách đọc chủ sở hữu chương trình của farm; đối với CPI trên chuỗi, bạn phải chọn ID chương trình phù hợp từ đầu.
Danh mục lệnh
| Mục đích | v3 | v5 | v6 |
|---|
| Tạo một farm | CreateFarm | CreateFarm | CreateFarm |
| Thêm sổ cái người dùng (có thể ngầm định) | CreateUserLedger | CreateAssociatedLedger | Ngầm định trong Deposit |
| Stake | Deposit | Deposit | Deposit |
| Unstake | Withdraw | Withdraw | Withdraw |
| Chỉ nhận phần thưởng | N/A (sử dụng Deposit 0) | N/A (sử dụng Deposit 0) | Harvest |
| Thêm luồng phần thưởng sau khi tạo | N/A | AddReward | AddReward |
| Chỉnh sửa luồng phần thưởng hiện có | N/A | SetRewards | SetRewards |
| Khởi động lại phần thưởng sau end_time | N/A | RestartRewards | RestartRewards |
| Rút ngân sách phần thưởng chưa nhận (admin) | N/A | WithdrawReward | WithdrawReward |
Trên v3 và v5, cách chuẩn để nhận phần thưởng mà không thay đổi stake là gọi Deposit với amount = 0. Chương trình coi đây là một quyết toán thuần túy. v6 đã giới thiệu Harvest rõ ràng để làm rõ ý định.
SDK trừu tượng hóa tất cả những điều này đằng sau raydium.farm.deposit({ ... }) v.v. Các phần dưới đây ghi chép danh sách tài khoản cơ bản cho những người tích hợp cần xây dựng lệnh thủ công (aggregators, công cụ theo dõi, mở rộng SDK).
CreateFarm (v6)
Khởi động một farm v6 mới.
Đối số
reward_info_count: u8 // số lượng luồng phần thưởng khi tạo (1..=5)
reward_infos: [
{
open_time: u64,
end_time: u64,
emission_per_second_x64: u128, // Q64.64
mint: Pubkey, // phần thưởng mint
token_program: Pubkey, // SPL hoặc Token-2022
}
]
Tài khoản (tóm tắt, cho reward_info_count = 1)
| # | Tên | W | S | Ghi chú |
|---|
| 1 | creator | W | S | Trả tiền thuê, sở hữu farm. |
| 2 | farm_state | W | | Tài khoản FarmState mới. |
| 3 | farm_authority | | | PDA [farm_id]. |
| 4 | staking_mint | | | |
| 5 | staking_vault | W | | Được tạo dưới dạng ATA của authority hoặc vault PDA. |
| 6 | staking_token_program | | | |
| 7 | reward_mint | | | |
| 8 | reward_vault | W | | Sẽ nhận ngân sách ban đầu. |
| 9 | reward_token_program | | | |
| 10 | reward_sender_ata | W | | ATA của creator trên phần thưởng mint; bị xóa bởi lệnh này. |
| 11 | system_program | | | |
| 12 | token_program | | | |
| 13 | associated_token_program | | | |
| 14 | rent | | | |
Điều kiện tiên quyết
open_time > now, end_time > open_time.
- ATA của
creator chứa ít nhất emission_per_second_x64 × (end_time − open_time) / 2^64 của phần thưởng mint.
staking_mint không có freeze authority hoặc freeze authority bị vô hiệu hóa.
Điều kiện sau
FarmState được khởi tạo, total_staked = 0.
- Vault phần thưởng được tài trợ với toàn bộ ngân sách luồng.
- ATA phần thưởng của creator bị xóa theo số tiền đó.
Deposit (v6)
Stake amount của staking mint.
Đối số
Tài khoản
| # | Tên | 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 | | |
Nếu user_ledger không tồn tại, SDK sẽ thêm một ix kiểu CreateAccount; chương trình v6 cũng có thể tạo nó một cách lười biếng với tài khoản system program. Mẫu tài khoản còn lại: với mỗi phần thưởng hiện hoạt, hãy thêm (reward_vault, user_reward_ata) để có thể thực hiện quyết toán.
Hiệu ứng
- Làm mới
reward_per_share_x64[i] cho mỗi luồng phần thưởng hiện hoạt bằng công thức cập nhật lười biếng.
- Tính toán
pending_i = user_ledger.deposited × reward_per_share_x64[i] / 2^64 − user_ledger.reward_debts[i].
- Chuyển
pending_i từ reward_vault_{i} đến user_reward_ata_{i}.
- Chuyển
amount staking mint từ user_staking_ata đến staking_vault.
- Cập nhật
user_ledger.deposited += amount và chụp lại reward_debts[i].
- Cập nhật
farm_state.total_staked += amount.
Điều kiện tiên quyết
amount > 0 cho một stake thực sự (v6 không cho phép amount = 0 — sử dụng Harvest cho chỉ nhận).
user_staking_ata chứa ít nhất amount.
- Mỗi vault phần thưởng hiện hoạt chứa ít nhất số tiền còn lại phải trả cho người dùng này.
Withdraw (v6)
Unstake amount.
Đối số
Tài khoản — giống hệt với Deposit.
Hiệu ứng — quyết toán tương tự như Deposit, sau đó chuyển staking mint quay lại cho người dùng: staking_vault → user_staking_ata. Cả total_staked và user_ledger.deposited đều giảm.
Điều kiện tiên quyết
amount ≤ user_ledger.deposited.
- Farm không bị tạm dừng.
Harvest (v6)
Nhận phần thưởng đang chờ xử lý mà không thay đổi stake.
Đối số — không có.
Tài khoản — giống như Deposit, không có chuyển động phía staking.
Hiệu ứng — làm mới reward_per_share_x64[i], trả pending_i, chụp lại reward_debts[i]. Không có thay đổi đối với total_staked hoặc deposited.
AddReward (v5/v6)
Thêm luồng phần thưởng mới vào farm hiện có có khe trống.
Đối số
reward_info: {
open_time: u64,
end_time: u64,
emission_per_second_x64: u128,
mint: Pubkey,
token_program: Pubkey,
}
Điều kiện tiên quyết
- Khe trống tồn tại (
reward_info_count < 5 trên v6, < 2 trên v5).
open_time ≥ now (có thể ở tương lai) hoặc open_time < now được phép chỉ khi phiên bản chương trình cho phép — v6 có, v5 thì không.
Điều kiện sau
- Luồng mới được khởi tạo tại chỉ mục
reward_info_count, reward_info_count++.
- Vault phần thưởng được tín dụng với toàn bộ ngân sách luồng từ ATA của người gọi.
Lỗi phổ biến — RewardAlreadyExists nếu mint va chạm với khe hiện có.
SetRewards (v5/v6)
Mở rộng hoặc bổ sung luồng phần thưởng hiện có. Không thể thay đổi mint; không thể rút ngắn end_time; không thể giảm emission_per_second_x64 khi đang chạy.
Đối số
reward_index: u8
new_open_time: u64,
new_end_time: u64,
new_emission_per_second_x64: u128,
Điều kiện tiên quyết
- Luồng vẫn đang chạy (
reward_state == 1).
new_end_time ≥ current end_time.
- Ngân sách bổ sung cần thiết
(new_emission × new_duration − already_emissioned) có trong ATA của người gửi và được chuyển đến vault phần thưởng bởi lệnh.
Trên v5, lệnh tương đương là SetRewards với bộ đối số nhỏ hơn (không có thay đổi per-second trên các luồng hiện hoạt).
RestartRewards (v5/v6)
Khởi động lại luồng sau khi end_time của nó đã trôi qua. Về mặt khái niệm giống như AddReward cho một mint đã có khe.
Đối số — hình dạng giống hệt với AddReward tại chỉ mục đó.
Điều kiện tiên quyết
reward_state == 2 (đã kết thúc).
- Người gọi là
reward_sender của khe (v6) hoặc owner của farm (v5).
WithdrawReward (v5/v6)
Quét hành chính của số dư vault phần thưởng chưa nhận sau khi luồng đã kết thúc và tất cả những người stake đã có cơ hội để harvest.
Đối số
Điều kiện tiên quyết
- Luồng đã kết thúc (
reward_state == 2).
reward_total_emissioned == reward_claimed + vault_balance (không có gì đang nợ).
Hiệu ứng — chuyển phần còn lại đến reward_sender_ata. Chương trình không ngăn chặn việc rút tiền trong khi những người stake vẫn còn các khoản thanh toán đang chờ xử lý; admin được kỳ vọng sẽ harvest thay mặt những người stake chậm trễ trước (hoặc để cho họ harvest). Nếu bạn quét sớm, người dùng sẽ mất quyền truy cập vào phần thưởng chưa nhận của họ. Đừng gọi cái này sớm.
Biến thể v5
Deposit / Withdraw có hình dạng giống v6 nhưng sử dụng tối đa 2 khe phần thưởng và reward_per_share là u128 (điểm cố định với cơ số khác).
CreateAssociatedLedger là lệnh gọi riêng biệt cần thiết trước Deposit đầu tiên; v6 đã hợp nhất nó.
AddReward có sẵn, Harvest thì không (sử dụng Deposit 0).
Biến thể v3
- Luồng phần thưởng duy nhất. Không có
AddReward, không có khe thứ hai.
Deposit 0 là cách duy nhất để nhận.
CreateUserLedger phải được gọi trước Deposit đầu tiên.
Ma trận thay đổi trạng thái
| Lệnh | total_staked | user.deposited | reward_per_share | Vault phần thưởng |
|---|
CreateFarm | 0 | — | 0 | tài trợ bởi creator |
Deposit(n) | +n | +n | làm mới | −pending (trả) |
Withdraw(n) | −n | −n | làm mới | −pending |
Harvest | — | — | làm mới | −pending |
AddReward | — | — | — | +ngân sách mới |
SetRewards | — | — | — | +ngân sách delta |
RestartRewards | — | — | — | +ngân sách |
WithdrawReward | — | — | — | −phần còn lại |
Bước tiếp theo
Nguồn: