Skip to main content
Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
Cette page s’accompagne de products/clmm/accounts (ce que sont les comptes) et products/clmm/math (ce que sont les mathématiques). Elle fait autorité pour les arguments et l’ordre des comptes ; les dispositions d’octets spécifiques proviennent de l’IDL.

Inventaire des instructions

La plupart des instructions réservées à l’admin (CreateAmmConfig, UpdateAmmConfig, UpdatePoolStatus, CreateSupportMintAssociated, CreateOperationAccount, UpdateOperationAccount, CloseProtocolPosition) sont contrôlées par la clé admin codée en dur du programme. CreatePermissionPda / ClosePermissionPda acceptent soit la clé admin soit une clé permission_pda_admin dédiée. Les instructions d’admin de flux de récompenses (TransferRewardOwner, CollectRemainingRewards) sont contrôlées par le financeur de récompenses, pas par l’admin du programme. Le suffixe V2 signifie « supporte Token-2022 sur les coffres / NFT, nécessite l’emplacement d’extension bitmap ». Le SDK choisit V2 par défaut pour les nouveaux pools.

CreatePool

Arguments
Comptes (abrégés) Préconditions
  • token_mint_0 < token_mint_1 par ordre d’octets.
  • amm_config.disable_create_pool == false.
  • Les mints ne sont pas rejetés par la liste blanche d’extension Token-2022.
Postconditions
  • pool_state.sqrt_price_x64 = sqrt_price_x64, tick_current = floor(log_{1.0001}(price)).
  • pool_state.liquidity = 0 (pas de positions encore).
  • pool_state.fee_on = FromInput (défaut hérité).
  • pool_state.dynamic_fee_info est mis à zéro (frais dynamiques désactivés).

CreateCustomizablePool

Recommandé pour les nouveaux pools. Même effet que CreatePool plus le mode de collecte des frais par pool et un opt-in optionnel pour les frais dynamiques. Arguments
Comptes (abrégés) — identiques à CreatePool plus, lorsque enable_dynamic_fee = true : Préconditions — identiques à CreatePool. Si enable_dynamic_fee = false, dynamic_fee_config est ignoré. Postconditions
  • pool_state.fee_on défini à la variante CollectFeeOn choisie.
  • Si les frais dynamiques ont été activés : pool_state.dynamic_fee_info est initialisé à partir du DynamicFeeConfig fourni (cinq paramètres d’étalonnage copiés ; champs d’état mis à zéro).
  • Sinon : pool_state.dynamic_fee_info est mis à zéro (= frais dynamiques inactifs à jamais pour ce pool).
fee_on et le bit d’activation des frais dynamiques sont définis uniquement à la création du pool. Il n’y a pas de mise à niveau sur place — les pools créés via le CreatePool hérité ne peuvent pas rétroactivement obtenir des frais dynamiques ou des frais unilatéraux. Les nouveaux déploiements doivent utiliser cette instruction par défaut.

CreatePermissionedPool

À la fois CreatePool et CreateCustomizablePool dérivent le PDA du pool de ["pool", amm_config, token_mint_0, token_mint_1], donc il y a exactement une adresse de pool canonique par triplet (config, mint0, mint1) — un second init aux mêmes graines échoue. CreatePermissionedPool lève cette restriction en pliant un seed_index: u16 fourni par le client dans les graines du PDA du pool, permettant plusieurs pools pour la même paire et palier de frais — chacun à sa propre adresse. Parce qu’une adresse de pool arbitraire est une capacité privilégiée, le payeur doit détenir un PDA Permission qui l’autorise. Tout le reste du pool est identique à CreateCustomizablePool : il prend les mêmes CreateCustomizableParams et supporte les frais unilatéraux et l’opt-in pour les frais dynamiques. Arguments
Comptes (abrégés) — identiques à CreateCustomizablePool plus, au début : Le PDA pool_state est dérivé de ["pool", amm_config, token_mint_0, token_mint_1, seed_index.to_le_bytes()]. Préconditions
  • seed_index != 0. Un seed_index de 0 est réservé aux pools hérités et est rejeté ici ; la composante de graine [0, 0] est ce qui fait qu’une adresse de pool hérité s’effondre à la forme classique à quatre graines.
  • Le PDA permission pour payer existe (créé par un admin via CreatePermissionPda).
  • Mêmes règles de mint / liste blanche que CreatePool.
Postconditions
  • Un nouveau pool_state existe à l’adresse dérivée de seed_index, avec pool_state.seed_index = seed_index.
  • Tout autre post-état correspond à CreateCustomizablePool (mode de frais, frais dynamiques optionnels).
Cette instruction ne pas élargir l’accès général à la création de pools — la création sans permission continue via CreatePool / CreateCustomizablePool, qui restent un-pool-par-paire. CreatePermissionedPool existe pour le cas spécifique où un opérateur sur liste blanche a besoin de plusieurs pools pour la même paire (par exemple, prix initiaux différents ou cohortes de lancement) et détient un PDA Permission accordé par l’admin.

OpenPositionV2 / OpenPositionWithToken22Nft

Créer une nouvelle position à l’intérieur d’un pool existant. Arguments
Comptes (abrégés) Mathématiques — voir products/clmm/math. Donné base_flag, le programme résout soit liquidity soit (amount_0_max, amount_1_max) en L réel et les montants de jetons réels consommés. Préconditions
  • tick_lower < tick_upper, tous deux multiples de pool.tick_spacing, dans [MIN_TICK, MAX_TICK].
  • Les tick arrays requis passés et initialisés (ou créés ici via CPI InitTickArray dans la transaction).
  • L’utilisateur a au moins amount_0_max et amount_1_max dans les ATAs source.
Postconditions
  • personal_position existe, liquidity défini, fee_growth_inside_last capturé.
  • Les entrées du tick-array à tick_lower et tick_upper mises à jour (liquidity_gross += L, liquidity_net ± L, instantanés de croissance des frais maintenus).
  • pool_state.liquidity += L si la position est en plage (tick_lower ≤ tick_current < tick_upper).
  • Le mint NFT de la position enregistre pool_state comme autorité de gel. L’autorité de mint est supprimée après que le seul NFT soit frappé. L’enregistrement de l’autorité de gel ne change pas l’état du compte de jeton NFT.
  • Le compte de jeton NFT reste dégelé sauf si l’instruction est OpenPositionV2 ou OpenPositionWithToken22Nft et que l’autorité de gel de l’un des mints de coffre correspond à la liste des émetteurs restreints de CLMM. Seul ce chemin V2 correspondant gèle le compte. OpenPosition V1 ne gèle pas.
Erreurs courantesInvalidTickIndex, NotApproved, ZeroAmountSpecified, TransactionTooLarge (si trop de tick arrays).
Le gel de position n’ajoute pas de comptes d’instruction déclarés ou d’arguments. Les clients peuvent ouvrir ces positions avec les dispositions V2 existantes. Le comportement est sélectionné on-chain à partir de vault_0_mint et vault_1_mint.

IncreaseLiquidityV2

Ajouter de la liquidité à une position déjà ouverte. Arguments
Comptes — comme OpenPosition moins le mint NFT (la position existe déjà ; le NFT est passé comme l’ATA du propriétaire détenant 1 jeton). Effet
  • Transfère amount_0_actual / amount_1_actual de l’utilisateur → coffres.
  • Incrémente personal_position.liquidity et pool_state.liquidity (si en plage), et le liquidity_gross / liquidity_net du tick d’extrémité en conséquence.
  • Collecte les frais et récompenses dus depuis le dernier toucher et les crédite à tokens_fees_owed_{0,1} / reward_amount_owed. Ceux-ci ne sont payés que sur DecreaseLiquidity ou CollectReward, pas sur l’augmentation.

DecreaseLiquidityV2

Retirer de la liquidité d’une position. Arguments
Comptes — même forme que IncreaseLiquidity. Effet
  • Calcule (amount_0, amount_1) pour le L retiré donné le sqrt_price_x64 actuel.
  • Règle les frais/récompenses accumulés depuis le dernier toucher, comme IncreaseLiquidity.
  • Transfère amount_0 + fees_owed_0 et amount_1 + fees_owed_1 hors des coffres vers l’utilisateur.
  • Décrémente les compteurs de liquidité ; si le nouveau personal_position.liquidity == 0, la position est éligible pour ClosePosition.
Slippageamount_0_min et amount_1_min sont les minimums que l’utilisateur accepte nets des frais de transfert Token-2022 du côté de la sortie.

ClosePosition

Brûler le NFT de position et fermer PersonalPositionState. Comptes déclarés Comptes restants
  • NFT dégelé : aucun requis ; un compte de pool supplémentaire est inoffensif car le gestionnaire ne le lit pas.
  • NFT gelé : ajouter personal_position.pool_id comme premier compte restant. Le programme le charge comme PoolState et utilise ses graines PDA pour signer le dégel.
Préconditions
  • personal_position.liquidity == 0.
  • tokens_fees_owed_{0,1} == 0.
  • Tous les compteurs de récompenses reward_amount_owed == 0.
(C’est-à-dire, collecter tout et diminuer à zéro d’abord.) Effet
  • Si le compte de jeton NFT est gelé, vérifie que le premier compte restant égale personal_position.pool_id, puis le dégèle avec le PDA du pool.
  • Brûle le NFT.
  • Ferme le compte de jeton NFT et personal_position, remboursant le loyer à nft_owner. Si le NFT de position utilise Token-2022, il ferme également le mint NFT ; les mints Token SPL classiques ne peuvent pas être fermés et restent avec l’approvisionnement zéro.
Le dégel, la combustion et la fermeture sont atomiques. Le NFT ne peut pas devenir transférable entre ces étapes. Rupture client conditionnelle — la disposition IDL déclarée est inchangée, donc les clients hérités continuent à fermer les positions existantes et dégelées. Un constructeur hérité qui omet le compte de pool restant échoue avec AccountLack lors de la fermeture d’une position gelée. Passer le pool pour chaque fermeture est la stratégie compatible la plus simple.

SwapV2

Parcourir la courbe de liquidité ; entrée exacte ou sortie exacte selon is_base_input. Arguments
Comptes (abrégés) Les appelants passent une liste classée de tick arrays couvrant la marche de swap attendue ; le programme en utilise autant qu’il en a besoin. Le SDK calcule cette liste via PoolUtils.computeAmountOutFormat ou le point de terminaison de devis de l’API. Préconditions
  • pool_state.status permet le swap.
  • now >= open_time.
  • sqrt_price_limit_x64 est du bon côté de sqrt_price_x64 pour la direction.
Erreurs courantesExceededSlippage, SqrtPriceLimitOverflow, TickArrayNotFound, LiquidityInsufficient. Ce que SwapV2 fait en interne que les appelants doivent savoir (version post-2025) :
  1. Surcharge de frais dynamiques — si pool.dynamic_fee_info est non-zéro, le programme met à jour l’accumulateur de volatilité en utilisant la distance de tick parcourue depuis le dernier swap (avec les règles de filtre/décroissance de products/clmm/fees) et ajoute un dynamic_fee_component en plus de AmmConfig.trade_fee_rate. Le frais total est plafonné à 10% (MAX_FEE_RATE_NUMERATOR / 1_000_000).
  2. Appariement des ordres limites — lorsque la marche de prix traverse un tick qui détient des ordres limites ouverts, le programme remplit d’abord la liquidité d’ordre limite disponible à ce tick (FIFO par order_phase), puis procède le long de la courbe de liquidité LP. Les montants remplis mettent à jour tick.unfilled_ratio_x64 et tick.part_filled_orders_remaining pour le règlement ultérieur ; les ordres eux-mêmes restent non dépensés jusqu’à ce que leur propriétaire appelle SettleLimitOrder.
  3. Routage des frais unilatéraux — lorsque pool.fee_on = Token0Only ou Token1Only, l’étape de swap calcule toujours le même échange entrée-sortie ; le frais est ensuite acheminé vers le côté configuré. Pour les directions où le côté de frais configuré est la sortie, le frais est déduit de la sortie du swap (l’utilisateur reçoit out − fee) ; pour les directions où il est l’entrée, le comportement correspond à FromInput. Voir is_fee_on_input(zero_for_one) et is_fee_on_token0(zero_for_one) sur PoolState.
Swap (V1) implémente les mêmes frais dynamiques, routage des frais unilatéraux et appariement des ordres limites que SwapV2 ; la seule fonctionnalité qu’il manque est le support Token-2022 — les deux coffres doivent être du Token SPL classique. Les pools avec n’importe quel mint Token-2022 doivent être échangés via SwapV2. L’agrégateur et le SDK préfèrent déjà V2 pour chaque jambe CLMM, donc les appelants n’ont pas à se brancher sur le type de mint.

OpenLimitOrder

Placer un ordre de vente à un tick spécifique. L’ordre reste dans une cohorte FIFO par tick et se remplit à mesure que le prix traverse. Arguments
Comptes (abrégés)
Changement de liste de comptes (version 2026-07). OpenLimitOrder prend maintenant aussi les comptes du côté de la sortieoutput_token_account, output_vault et output_vault_mint — en plus du côté d’entrée. Ils sont utilisés uniquement pour la validation : le programme rejette l’ordre si le compte de jeton d’entrée ou de sortie du propriétaire est gelé. Cela garantit qu’un remplissage peut réellement être réglé à l’ATA de sortie du propriétaire, ce qui importe pour les mints Token-2022 avec liste blanche / gelés par défaut (par exemple, jetons autorisés) où un compte peut ne pas encore être dégelé. Les clients construits contre la liste de comptes unilatérale plus ancienne doivent ajouter les trois comptes de sortie.
Préconditions
  • Ni input_token_account ni output_token_account n’est gelé (sinon NotApproved).
  • pool_state.status permet à la fois le swap (bit 4) et les opérations d’ordre limite (bit 5) (sinon NotApproved).
  • tick_index % pool.tick_spacing == 0 et dans [MIN_TICK, MAX_TICK].
  • tick_index est du bon côté de pool.tick_current pour la direction choisie (vendre token0 → le tick doit être au-dessus du courant, et vice versa). Vendre à un tick déjà traversé serait immédiatement appariée et est rejeté.
Postconditions
  • limit_order existe, capturant tick.order_phase et tick.unfilled_ratio_x64 au moment de l’ouverture.
  • tick.orders_amount += amount (dans la cohorte actuelle).
  • limit_order_nonce.order_nonce += 1.
  • OpenLimitOrderEvent émis.
Erreurs courantesNotApproved (compte de jeton d’entrée ou de sortie gelé, ou le pool a le swap / ordre limite désactivé), InvalidLimitOrderAmount (zéro ou en dessous du minimum du pool), InvalidTickIndex (hors de [MIN_TICK, MAX_TICK], ou du mauvais côté de tick_current pour la direction choisie), TickAndSpacingNotMatch (tick_index % pool.tick_spacing != 0), OrderPhaseSaturated.

IncreaseLimitOrder

Ajouter à un ordre ouvert existant. Uniquement appelable par le owner de l’ordre. Arguments
Comptes — comme OpenLimitOrder moins le compte nonce ; le PDA limit_order est passé directement. Préconditions
  • limit_order.owner == signer.
  • L’ordre est toujours dans la même cohorte (tick.order_phase == limit_order.order_phase). Si la cohorte a déjà commencé à se remplir, l’ordre est partiellement réglé — l’appelant doit d’abord appeler DecreaseLimitOrder ou SettleLimitOrder pour avancer.
Effet
  • Transfère amount de l’ATA du propriétaire à input_vault.
  • limit_order.total_amount += amount ; tick.orders_amount += amount.

DecreaseLimitOrder

Réduire ou annuler complètement un ordre ouvert. Paie le reste non rempli au propriétaire, plus tout résultat déjà réglé par les remplissages partiels passés. Arguments
Comptes — côtés d’entrée et de sortie du jeton : Effet
  • Recalcule le montant rempli de l’ordre à partir du unfilled_ratio_x64 de la cohorte depuis l’ouverture.
  • Envoie la sortie remplie à output_token_account.
  • Envoie amount de l’entrée non remplie de retour à input_token_account.
  • Met à jour limit_order en conséquence. Si le nouveau reste non rempli est zéro, le programme ferme le compte et rembourse le loyer à owner.

SettleLimitOrder

Pousser les jetons de sortie remplis vers le propriétaire sans modifier le reste non rempli de l’ordre. Utile lorsque les gardiens auto_withdraw veulent verser progressivement les remplissages partiels de longue durée. Appelant — soit le owner de l’ordre, soit le limit_order_admin du programme (un portefeuille chaud opérationnel hors chaîne qui exécute une boucle de gardien automatisée). Le gardien n’a aucune autre autorité — il ne peut pas déplacer les fonds de l’utilisateur en dehors de pousser la sortie remplie à l’ATA owner. Comptes Effet
  • Calcule la sortie cumulative due en utilisant (limit_order.unfilled_ratio_x64, tick.unfilled_ratio_x64).
  • Transfère le delta à output_token_account.
  • Met à jour limit_order.settled_output.
  • Ne ferme pas l’ordre ; il est toujours ouvert contre toute entrée restante.

CloseLimitOrder

Fermer un compte d’ordre entièrement consommé. Le loyer est toujours retourné à limit_order.owner quel que soit le signataire. Appelant — soit owner soit limit_order_admin. Préconditions
  • L’ordre a un reste non rempli zéro (soit amount == total_amount a été rempli et réglé, soit le propriétaire a précédemment réduit l’ordre à zéro et a oublié de fermer).
Effet
  • Ferme limit_order ; le loyer est envoyé à limit_order.owner.

CreateDynamicFeeConfig (admin)

Créer un ensemble de paramètres réutilisable sous un index u16. Arguments
Comptes Erreurs courantesInvalidDynamicFeeConfigParams si decay_period <= filter_period ou tout champ à valeur zéro est hors limites.

UpdateDynamicFeeConfig (admin)

Modifier un DynamicFeeConfig existant. Les pools qui ont déjà capturé la configuration à la création ne sont pas rétroactivement mis à jour ; seuls les pools nouvellement créés qui référencent cette configuration reprendront les nouvelles valeurs. Arguments — mêmes cinq champs d’étalonnage que CreateDynamicFeeConfig (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) ; index est fixé à la création et n’est pas re-passé ici.

CollectProtocolFee / CollectFundFee

Forme identique à CollectProtocolFee / CollectFundFee du CPMM. Le signataire doit correspondre à AmmConfig.owner / AmmConfig.fund_owner. Balayer les frais de protocole/fonds accumulés des coffres du pool vers un destinataire, mettre à zéro les champs correspondants PoolState.protocol_fees_* / fund_fees_*.

InitializeReward

Ajouter un nouveau flux de récompenses à un pool. Jusqu’à 3 flux peuvent être actifs à la fois. Arguments
Comptes Préconditions
  • Moins de 3 flux actuellement actifs sur le pool.
  • Le financeur dépose total_emission = emissions_per_second × (end_time − open_time) de jeton de récompense dans le coffre dans le cadre de cette instruction.
  • Mint de récompense sur liste blanche par operation_state.

SetRewardParams

Étendre, alimenter ou modifier le taux d’émission sur un flux de récompenses existant. Généralement appelé par un créateur de pool ou le multisig Raydium. Les contraintes vivent on-chain : vous pouvez généralement étendre end_time ou augmenter les émissions, pas les réduire rétroactivement. Vérifiez la liste des propriétaires de operation_state.

UpdateRewardInfos

Pur comptage — règle reward_growth_global_x64 à l’heure actuelle en multipliant emissions_per_second × Δt / liquidity. Appelé en interne par chaque instruction touchant la liquidité. Exposé en tant qu’instruction autonome car les acteurs externes (UIs, cranks) veulent parfois le déclencher.

CollectReward

Le propriétaire de la position réclame les jetons de récompense dus. Comptes Effet
  • Règle la croissance des récompenses (même motif que les frais).
  • Transfère le montant dû à l’ATA du destinataire, met à zéro reward_amount_owed[i].

Matrice de changement d’état

Où aller ensuite

Sources :