Cette page est traduite automatiquement par IA. La version anglaise fait foi.Voir la version anglaise →
Cette page décrit la structure et le rôle de chaque compte. Les seeds sont canoniques et listés dans
reference/program-addresses. Un pool CLMM est plus lourd en comptes qu’un pool CPMM car la liquidité est stockée de manière clairsemée sur la plage de ticks ; comprendre cette clairsemé est l’essentiel de cette page.Inventaire des comptes
Un pool CLMM actif est décrit par les familles de comptes suivantes. Tous sont possédés par le programme CLMM sauf les deux mints et leurs vaults.PoolState
L’état actif du pool, lu à chaque swap et à chaque changement de position.
sqrt_price_x64ettick_currentsont l’état des prix du pool. Ils sont mis à jour ensemble à chaque swap.tick_currentest le plancher delog_{1.0001}(price).liquidityest la liquidité active — la somme des valeursLpour toutes les positions dont la plage contienttick_current. Elle change chaque fois qu’un swap traverse un tick et chaque fois qu’une position est ouverte/fermée/redimensionnée.fee_growth_global_{0,1}_x64sont les frais cumulatifs gagnés par unité de liquidité sur tout l’historique du pool. Les positions lisent ceci pour calculer ce qui leur est dû.tick_spacingest verrouillé surAmmConfigà l’initialisation et ne change jamais. Il détermine quels indices de tick sont autorisés à être des points d’extrémité de position.tick_array_bitmapest un bitmap inline couvrant la plage de ticks couramment utilisée autour du prix spot. Pour les pools dont les positions s’étendent loin, le suivi du débordement vit dans leTickArrayBitmapExtensionséparé.fee_onest fixé à la création du pool.0(FromInput) reproduit le comportement classique d’Uniswap-V3.1et2acheminent les frais de swap vers un seul côté du carnet — voirproducts/clmm/feespour les compromis.seed_indexest[0, 0]pour chaque pool créé viaCreatePool/CreateCustomizablePool(un pool canonique par paire). Une valeur non-zéro signifie que le pool a été créé viaCreateCustomizablePoolV2(nomméCreatePermissionedPoolavant 2026-10-22) et l’index fait partie des seeds PDA du pool, permettant à plusieurs pools de coexister pour le même(config, mint0, mint1). Pour re-dériver l’adresse d’un tel pool, vous devez connaître sonseed_index.dynamic_fee_infoporte l’état de volatilité pour la surcharge de frais dynamiques. Quand activé, chaque swap recalcule undynamic_fee_componenten plus deAmmConfig.trade_fee_rate. La structure est documentée sousDynamicFeeInfoci-dessous ; les pools sans frais dynamiques laissent la structure entière à zéro.
AmmConfig
CreateAmmConfig écrit le protocol_fee_owner::ID codé en dur du programme dans owner et le fund_fee_owner::ID dans fund_owner. Avant cela, il copiait la clé du signataire admin dans les deux. Les configs existantes conservent ce qu’elles ont été créées ou rotées, donc lisez les deux champs du compte. Les paramètres UpdateAmmConfig 3 / 4 les font toujours tourner. Les adresses sont dans reference/program-addresses.
Un ensemble typique de paliers de frais CLMM publiés (confirmez par rapport à GET https://api-v3.raydium.io/main/clmm-config) :
protocol_fee_rate et fund_fee_rate sont des fractions des frais commerciaux ; même convention que CPMM. Voir products/clmm/fees.
TickArrayState
CLMM ne stocke pas un enregistrement unique par tick. Cela représenterait des milliards de comptes. À la place, il regroupe TICK_ARRAY_SIZE ticks adjacents initialisés ou non (généralement 60 ou 88 selon la version du programme) dans un TickArrayState créé de manière paresseuse à la première utilisation.
order_phaseest l’identifiant de la cohorte. Il s’incrémente chaque fois qu’une cohorte passe de « complètement non remplie » à « partiellement remplie ».orders_amountest le total du jeton d’entrée de la cohorte actuelle (la plus récente).part_filled_orders_remainingsuit la cohorte précédente qui est actuellement remplie par les swaps en cours.unfilled_ratio_x64est un multiplicateur Q64.64 porté sur la cohorte : quand un swap remplit X% de la cohorte, le ratio est multiplié par(1 − X). Chaque ordre ouvert stocke son propre snapshot(order_phase, unfilled_ratio_x64)au moment de l’ouverture, donc les mathématiques de règlement se réduisent à comparer les snapshots.
- Un tick d’extrémité de position t doit satisfaire
t % tick_spacing == 0. Le programme rejette les positions mal espacées. - Le tableau du tick est situé à
floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing). - Un tableau de ticks est initialisé de manière paresseuse : la première position ou le premier swap qui touche un tableau non initialisé le crée, en payant le loyer.
- Un tableau de ticks n’est jamais fermé par le programme. Une fois alloué, il persiste pour la durée de vie du pool, même après que chaque tick à l’intérieur revienne à
liquidity_gross == 0. Les positions et swaps ultérieurs réutilisent le compte existant sans loyer supplémentaire. Il n’existe pas de chemin de nettoyage piloté parClosePositionpour les tableaux de ticks.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (en ligne) couvre la plage « proche du spot » — ±512 tableaux de ticks (TICK_ARRAY_BITMAP_SIZE = 512 ; le champ [u64; 16] est 1 024 bits divisés équitablement entre les indices de départ négatifs et positifs, donc les indices de tableau −512 … +511). En dehors de cette plage (pour les valeurs de tick extrêmes), le programme maintient un compte d’extension :
(MIN_TICK, MAX_TICK)) le nécessitent ; le SDK le résout pour vous.
Positions
Une position CLMM est un ensemble de trois comptes plus un mint :Position NFT mint
Un mint SPL Token ou Token-2022 avec une offre de 1. Le NFT de position dans le portefeuille du propriétaire est un ATA contenant ce jeton unique. Le programme lie l’autorisation au détenteur actuel du solde ATA du NFT, et non à une Pubkey stockée dans l’état. Les nouveaux mints NFT de position définissentpool_state comme leur autorité de gel avant de frapper le jeton unique et de supprimer l’autorité de mint. Définir une autorité de gel ne gèle pas en soi le compte NFT. Le compte reste dégelé et transférable sauf si les deux conditions sont remplies : l’appelant utilise OpenPositionV2 ou OpenPositionWithToken22Nft, et au moins l’autorité de gel d’un mint de coffre-fort sous-jacent apparaît sur la liste des émetteurs restreints de CLMM. Ce n’est que dans ce cas que CLMM gèle le compte NFT après la frappe. Cela ne change aucun octet de PersonalPositionState ou PoolState.
PersonalPositionState
Un par position ouverte. Clé basée sur le mint NFT.
ProtocolPositionState (obsolète)
Les versions plus anciennes de CLMM stockaient la comptabilité agrégée par
(pool, tick_lower, tick_upper) dans un PDA ProtocolPositionState. Les versions plus récentes ne créent ni ne lisent plus ce compte. L’emplacement apparaît toujours sur les listes de comptes OpenPosition / IncreaseLiquidity / DecreaseLiquidity comme un UncheckedAccount pour la compatibilité ABI, mais le programme n’y écrit pas. Les comptes existants en chaîne sont vestigiaux ; l’administrateur peut appeler CloseProtocolPosition pour récupérer le loyer pour eux.La comptabilité de plage agrégée est maintenant dérivée directement des deux ticks d’extrémité (liquidity_gross, liquidity_net, et les fee_growth_outside_* / reward_growths_outside_x64 par tick) dans TickArrayState. La formule de croissance des frais fee_growth_inside = global − outside_lower − outside_upper continue de fonctionner sans un compte de position agrégée.Observation
(tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0) puis price = 1.0001 ** tick. Voir algorithms/clmm-math.
DynamicFeeConfig et DynamicFeeInfo
Les paramètres de frais dynamiques vivent à deux endroits. Le modèle réutilisable — DynamicFeeConfig — est géré par l’administrateur et partagé entre les pools qui l’acceptent. L’état d’exécution par pool — DynamicFeeInfo — est intégré dans PoolState et mis à jour par chaque swap.
DynamicFeeConfig
["dynamic_fee_config", index.to_be_bytes()]. Créé via create_dynamic_fee_config (protégé par l’administrateur) et modifié via update_dynamic_fee_config. Un pool créé avec enable_dynamic_fee = true capture les cinq paramètres d’étalonnage de la configuration (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) dans son propre DynamicFeeInfo au moment de la création ; les modifications ultérieures à DynamicFeeConfig n’affectent pas rétroactivement les pools existants.
DynamicFeeInfo (intégré dans PoolState)
DynamicFeeConfig. Les mathématiques des frais et les règles de décroissance sont documentées sous products/clmm/math et products/clmm/fees.
Constantes utilisées par la formule :
LimitOrderState
Un compte par ordre limite ouvert.
- Ouverture — l’utilisateur appelle
open_limit_order, déposetotal_amountdu jeton d’entrée, l’ordre est lié à une cohorteTickState. - (optionnel) Augmentation / Diminution —
increase_limit_orderajoute àtotal_amount;decrease_limit_orderretourne les jetons non remplis (et tout résultat réglé jusqu’à ce point). - Règlement — quand la cohorte est complètement ou partiellement remplie, le propriétaire ou le gardien opérationnel appelle
settle_limit_orderpour pousser les jetons de sortie vers l’ATA du propriétaire. - Fermeture — une fois que
unfilled_amount == 0, le compte est fermable. Le loyer retourne toujours àowner.
[owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]. Le PDA de l’ordre est donc unique par (owner, nonce_index, order_nonce).
LimitOrderNonce
Compteur par (wallet, nonce_index) qui permet à un utilisateur unique d’exécuter plusieurs pipelines parallèles d’ordres limités sans collision sur les PDAs.
[user_wallet.as_ref(), &[nonce_index]]. La plupart des clients utilisent nonce_index = 0 et laissent order_nonce porter la cardinalité.
Permission (retiré)
Le compte Permission a été supprimé lors de la mise à jour du 2026-10-22. Il servait autrefois à contrôler CreatePermissionedPool, qui est maintenant le CreateCustomizablePoolV2 sans permission. Le programme ne lit ni ne ferme plus ces comptes, et les instructions CreatePermissionPda / ClosePermissionPda ont disparu. Les PDAs créés avant la mise à jour (["permission", authority], 280 octets) restent sur la chaîne en tant que données inactives ; ignorez-les lors du balayage des comptes appartenant à CLMM.
Dérivation des comptes clés
reference/program-addresses.
Référence rapide du cycle de vie
Les comptes
TickArrayState ne sont jamais fermés par le programme — ils persistent pendant toute la durée de vie du pool. Une fois qu’un tableau de tick a été initialisé, il reste sur la chaîne même si chaque tick à l’intérieur revient à liquidity_gross == 0. La réutilisation d’un tableau de tick existant est gratuite ; seule la première position qui touche un tableau jamais initialisé paie son loyer.
Où lire quoi
- Mathématiques des ticks et mécanique des plages :
products/clmm/ticks-and-positions. - Parcours de swap et mathématiques de croissance des frais :
products/clmm/math. - Listes de comptes d’instruction :
products/clmm/instructions. - Frais et accumulation de récompenses :
products/clmm/fees. - IDs de programme canoniques et seeds :
reference/program-addresses.

