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
Préconditions
token_mint_0 < token_mint_1par ordre d’octets.amm_config.disable_create_pool == false.- Les mints ne sont pas rejetés par la liste blanche d’extension Token-2022.
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_infoest 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
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_ondéfini à la varianteCollectFeeOnchoisie.- Si les frais dynamiques ont été activés :
pool_state.dynamic_fee_infoest initialisé à partir duDynamicFeeConfigfourni (cinq paramètres d’étalonnage copiés ; champs d’état mis à zéro). - Sinon :
pool_state.dynamic_fee_infoest 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
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. Unseed_indexde0est 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
permissionpourpayerexiste (créé par un admin viaCreatePermissionPda). - Mêmes règles de mint / liste blanche que
CreatePool.
- Un nouveau
pool_stateexiste à l’adresse dérivée deseed_index, avecpool_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
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 depool.tick_spacing, dans[MIN_TICK, MAX_TICK].- Les tick arrays requis passés et initialisés (ou créés ici via CPI
InitTickArraydans la transaction). - L’utilisateur a au moins
amount_0_maxetamount_1_maxdans les ATAs source.
personal_positionexiste,liquiditydéfini,fee_growth_inside_lastcapturé.- Les entrées du tick-array à
tick_lowerettick_uppermises à jour (liquidity_gross += L,liquidity_net ± L, instantanés de croissance des frais maintenus). pool_state.liquidity += Lsi la position est en plage (tick_lower ≤ tick_current < tick_upper).- Le mint NFT de la position enregistre
pool_statecomme 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
OpenPositionV2ouOpenPositionWithToken22Nftet 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.OpenPositionV1 ne gèle pas.
InvalidTickIndex, 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
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_actualde l’utilisateur → coffres. - Incrémente
personal_position.liquidityetpool_state.liquidity(si en plage), et leliquidity_gross/liquidity_netdu 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 surDecreaseLiquidityouCollectReward, pas sur l’augmentation.
DecreaseLiquidityV2
Retirer de la liquidité d’une position.
Arguments
IncreaseLiquidity.
Effet
- Calcule
(amount_0, amount_1)pour leLretiré donné lesqrt_price_x64actuel. - Règle les frais/récompenses accumulés depuis le dernier toucher, comme
IncreaseLiquidity. - Transfère
amount_0 + fees_owed_0etamount_1 + fees_owed_1hors des coffres vers l’utilisateur. - Décrémente les compteurs de liquidité ; si le nouveau
personal_position.liquidity == 0, la position est éligible pourClosePosition.
amount_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_idcomme premier compte restant. Le programme le charge commePoolStateet utilise ses graines PDA pour signer le dégel.
personal_position.liquidity == 0.tokens_fees_owed_{0,1} == 0.- Tous les compteurs de récompenses
reward_amount_owed == 0.
- 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.
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
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.statuspermet le swap.now >= open_time.sqrt_price_limit_x64est du bon côté desqrt_price_x64pour la direction.
ExceededSlippage, SqrtPriceLimitOverflow, TickArrayNotFound, LiquidityInsufficient.
Ce que SwapV2 fait en interne que les appelants doivent savoir (version post-2025) :
- Surcharge de frais dynamiques — si
pool.dynamic_fee_infoest 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 deproducts/clmm/fees) et ajoute undynamic_fee_componenten plus deAmmConfig.trade_fee_rate. Le frais total est plafonné à 10% (MAX_FEE_RATE_NUMERATOR / 1_000_000). - 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 à jourtick.unfilled_ratio_x64ettick.part_filled_orders_remainingpour le règlement ultérieur ; les ordres eux-mêmes restent non dépensés jusqu’à ce que leur propriétaire appelleSettleLimitOrder. - Routage des frais unilatéraux — lorsque
pool.fee_on = Token0OnlyouToken1Only, 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çoitout − fee) ; pour les directions où il est l’entrée, le comportement correspond àFromInput. Voiris_fee_on_input(zero_for_one)etis_fee_on_token0(zero_for_one)surPoolState.
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
Changement de liste de comptes (version 2026-07).
OpenLimitOrder prend maintenant aussi les comptes du côté de la sortie — output_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.- Ni
input_token_accountnioutput_token_accountn’est gelé (sinonNotApproved). pool_state.statuspermet à la fois le swap (bit 4) et les opérations d’ordre limite (bit 5) (sinonNotApproved).tick_index % pool.tick_spacing == 0et dans[MIN_TICK, MAX_TICK].tick_indexest du bon côté depool.tick_currentpour 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é.
limit_orderexiste, capturanttick.order_phaseettick.unfilled_ratio_x64au moment de l’ouverture.tick.orders_amount += amount(dans la cohorte actuelle).limit_order_nonce.order_nonce += 1.OpenLimitOrderEventémis.
NotApproved (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
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 appelerDecreaseLimitOrderouSettleLimitOrderpour avancer.
- Transfère
amountde 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
Effet
- Recalcule le montant rempli de l’ordre à partir du
unfilled_ratio_x64de la cohorte depuis l’ouverture. - Envoie la sortie remplie à
output_token_account. - Envoie
amountde l’entrée non remplie de retour àinput_token_account. - Met à jour
limit_orderen 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_amounta été rempli et réglé, soit le propriétaire a précédemment réduit l’ordre à zéro et a oublié de fermer).
- 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
Erreurs courantes —
InvalidDynamicFeeConfigParams 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
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
products/clmm/code-demos— exemples TypeScript exécutables.products/clmm/fees— détails sur l’accumulation des frais et récompenses.reference/error-codes— table d’erreur Anchor CLMM complète.
raydium-io/raydium-clmm—programs/amm/src/instructions- Raydium SDK v2 —
@raydium-io/raydium-sdk-v2

