Farm-Anweisungen sind versionsspezifisch. Ein Deposit auf v6 ist auf einer v5-Farm nicht aufrufbar und umgekehrt. Das SDK führt einen Dispatch durch, indem es den Programmbesitzer der Farm liest; für On-Chain-CPI müssen Sie die richtige Programm-ID im Voraus wählen.
Anweisungsübersicht
| Zweck | v3 | v5 | v6 |
|---|
| Farm erstellen | CreateFarm | CreateFarm | CreateFarm |
| Benutzer-Ledger hinzufügen (kann implizit sein) | CreateUserLedger | CreateAssociatedLedger | Implizit in Deposit |
| Stake | Deposit | Deposit | Deposit |
| Unstake | Withdraw | Withdraw | Withdraw |
| Nur Belohnungen einfordern | N/A (verwenden Sie Deposit 0) | N/A (verwenden Sie Deposit 0) | Harvest |
| Belohnungsstrom nach Erstellung hinzufügen | N/A | AddReward | AddReward |
| Bestehenden Belohnungsstrom bearbeiten | N/A | SetRewards | SetRewards |
| Belohnung nach end_time neu starten | N/A | RestartRewards | RestartRewards |
| Nicht beanspruchtes Belohnungsbudget abheben (Admin) | N/A | WithdrawReward | WithdrawReward |
Bei v3 und v5 ist die kanonische Methode, Belohnungen ohne Änderung der Einsätze einzufordern, das Aufrufen von Deposit mit amount = 0. Das Programm behandelt dies als reine Abrechnung. v6 führte ein explizites Harvest zur Verdeutlichung ein.
Das SDK abstrahiert alle diese hinter raydium.farm.deposit({ ... }) usw. Die folgenden Abschnitte dokumentieren die zugrunde liegenden Kontolisten für Integrierer, die Anweisungen manuell erstellen müssen (Aggregatoren, Monitoring-Tools, SDK-Erweiterungen).
CreateFarm (v6)
Starten Sie eine neue v6-Farm.
Argumente
reward_info_count: u8 // Anzahl der Belohnungsströme bei der Erstellung (1..=5)
reward_infos: [
{
open_time: u64,
end_time: u64,
emission_per_second_x64: u128, // Q64.64
mint: Pubkey, // Belohnungs-Mint
token_program: Pubkey, // SPL oder Token-2022
}
]
Konten (gekürzt, für reward_info_count = 1)
| # | Name | W | S | Notizen |
|---|
| 1 | creator | W | S | Zahlt Miete, besitzt die Farm. |
| 2 | farm_state | W | | Neues FarmState-Konto. |
| 3 | farm_authority | | | PDA [farm_id]. |
| 4 | staking_mint | | | |
| 5 | staking_vault | W | | Erstellt als ATA der Autorität oder ein PDA-Vault. |
| 6 | staking_token_program | | | |
| 7 | reward_mint | | | |
| 8 | reward_vault | W | | Erhält das Anfangsbudget. |
| 9 | reward_token_program | | | |
| 10 | reward_sender_ata | W | | ATA des Erstellers auf der Belohnungs-Mint; wird durch diese Anweisung geleert. |
| 11 | system_program | | | |
| 12 | token_program | | | |
| 13 | associated_token_program | | | |
| 14 | rent | | | |
Vorbedingungen
open_time > now, end_time > open_time.
- Creator-ATAs halten mindestens
emission_per_second_x64 × (end_time − open_time) / 2^64 der Belohnungs-Mint.
staking_mint hat keine Gefrierautorität oder die Gefrierautorität ist deaktiviert.
Nachbedingungen
FarmState initialisiert, total_staked = 0.
- Belohnungsvaults mit dem vollständigen Stream-Budget finanziert.
- Die Belohnungs-ATA des Erstellers wird um diesen Betrag geleert.
Deposit (v6)
Setzen Sie amount der Staking-Mint.
Argumente
Konten
| # | Name | 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 | | |
Falls das user_ledger nicht vorhanden ist, stellt das SDK eine CreateAccount-ähnliche Anweisung voran; das v6-Programm kann es auch faul erstellen, wenn es das Systemprogrammkonto erhält. Remaining-Accounts-Muster: Fügen Sie für jeden aktiven Belohnungsstrom (reward_vault, user_reward_ata) an, damit die Abrechnung auszahlen kann.
Effekt
- Aktualisieren Sie
reward_per_share_x64[i] für jeden aktiven Belohnungsstrom mit der Lazy-Update-Formel.
- Berechnen Sie
pending_i = user_ledger.deposited × reward_per_share_x64[i] / 2^64 − user_ledger.reward_debts[i].
- Übertragen Sie
pending_i von reward_vault_{i} zu user_reward_ata_{i}.
- Übertragen Sie
amount Staking-Mint von user_staking_ata zu staking_vault.
- Aktualisieren Sie
user_ledger.deposited += amount und erstellen Sie einen neuen Snapshot von reward_debts[i].
- Aktualisieren Sie
farm_state.total_staked += amount.
Vorbedingungen
amount > 0 für einen echten Stake (v6 verbietet amount = 0 — verwenden Sie Harvest nur für Anspruchsforderungen).
user_staking_ata hält mindestens amount.
- Jeder aktive Belohnungsvault hält mindestens das Ausstehende, das diesem Benutzer geschuldet wird.
Withdraw (v6)
Unstake amount.
Argumente
Konten — identisch mit Deposit.
Effekt — gleiche Abrechnung wie Deposit, dann Staking-Mint zurück zum Benutzer: staking_vault → user_staking_ata. Sowohl total_staked als auch user_ledger.deposited nehmen ab.
Vorbedingungen
amount ≤ user_ledger.deposited.
- Farm ist nicht pausiert.
Harvest (v6)
Fordern Sie ausstehende Belohnungen an, ohne den Stake zu ändern.
Argumente — keine.
Konten — wie Deposit, keine Bewegung auf der Staking-Seite.
Effekt — aktualisieren Sie reward_per_share_x64[i], zahlen Sie pending_i aus, erstellen Sie einen neuen Snapshot von reward_debts[i]. Keine Änderung an total_staked oder deposited.
AddReward (v5/v6)
Fügen Sie einen neuen Belohnungsstrom zu einer bestehenden Farm hinzu, die einen ungenutzten Slot hat.
Argumente
reward_info: {
open_time: u64,
end_time: u64,
emission_per_second_x64: u128,
mint: Pubkey,
token_program: Pubkey,
}
Vorbedingungen
- Ein freier Slot existiert (
reward_info_count < 5 auf v6, < 2 auf v5).
open_time ≥ now (kann in der Zukunft liegen) oder open_time < now ist nur zulässig, wenn die Programmversion dies erlaubt — v6 tut es, v5 nicht.
Nachbedingungen
- Der neue Strom wird bei Index
reward_info_count initialisiert, reward_info_count++.
- Der Belohnungsvault wird mit dem vollständigen Stream-Budget aus der ATA des Aufrufers gutgeschrieben.
Häufiger Fehler — RewardAlreadyExists, wenn die Mint mit einem bestehenden Slot kollidiert.
SetRewards (v5/v6)
Erweitern oder auffüllen Sie einen bestehenden Belohnungsstrom. Kann die Mint nicht ändern; kann end_time nicht verkürzen; kann emission_per_second_x64 nicht senken, während der Betrieb läuft.
Argumente
reward_index: u8
new_open_time: u64,
new_end_time: u64,
new_emission_per_second_x64: u128,
Vorbedingungen
- Der Strom läuft noch (
reward_state == 1).
new_end_time ≥ current end_time.
- Das erforderliche zusätzliche Budget
(new_emission × new_duration − already_emissioned) ist in der ATA des Absenders vorhanden und wird durch die Anweisung in den Belohnungsvault übertragen.
Auf v5 ist der entsprechende Aufruf SetRewards mit einem kleineren Argumentsatz (keine Pro-Sekunden-Änderungen in aktiven Streams).
RestartRewards (v5/v6)
Starten Sie einen Stream neu, nachdem end_time vergangen ist. Konzeptionell dasselbe wie AddReward für eine Mint, die bereits einen Slot hat.
Argumente — identische Form wie AddReward bei diesem Index.
Vorbedingungen
reward_state == 2 (beendet).
- Aufrufer ist
reward_sender des Slots (v6) oder Farm-owner (v5).
WithdrawReward (v5/v6)
Admin-Entfernung nicht beanspruchter Belohnungsvault-Restbeträge nach Beendigung eines Streams und nachdem alle Staker die Möglichkeit hatten zu harvesten.
Argumente
Vorbedingungen
- Stream ist beendet (
reward_state == 2).
reward_total_emissioned == reward_claimed + vault_balance (es ist nichts mehr geschuldet).
Effekt — verschiebt den Rest zu reward_sender_ata. Das Programm verhindert nicht das Abheben, während Staker noch ausstehende Ansprüche haben; vom Admin wird erwartet, dass er zuerst im Auftrag von nachzügigen Stakern harvested (oder lässt sie harvesten). Wenn Sie frühzeitig abheben, verlieren Benutzer den Zugriff auf ihre nicht beanspruchten Belohnungen. Rufen Sie dies nicht frühzeitig auf.
v5-Variationen
Deposit / Withdraw haben die gleiche Form wie v6, aber verwenden bis zu 2 Belohnungsslots und reward_per_share ist u128 (Festkomma mit einer anderen Radix).
CreateAssociatedLedger ist ein erforderlicher separater Aufruf vor dem ersten Deposit; v6 hat das zusammengeführt.
AddReward ist verfügbar, Harvest ist nicht (verwenden Sie Deposit 0).
v3-Variationen
- Einzelner Belohnungsstrom. Kein
AddReward, kein zweiter Slot.
Deposit 0 ist die einzige Möglichkeit, Ansprüche geltend zu machen.
CreateUserLedger muss vor dem ersten Deposit aufgerufen werden.
Zustandsänderungsmatrix
| Anweisung | total_staked | user.deposited | reward_per_share | Belohnungsvaults |
|---|
CreateFarm | 0 | — | 0 | vom Ersteller finanziert |
Deposit(n) | +n | +n | aktualisiert | −pending (ausbezahlt) |
Withdraw(n) | −n | −n | aktualisiert | −pending |
Harvest | — | — | aktualisiert | −pending |
AddReward | — | — | — | +neues Budget |
SetRewards | — | — | — | +Delta-Budget |
RestartRewards | — | — | — | +Budget |
WithdrawReward | — | — | — | −Restbetrag |
Nächste Schritte
Quellen: