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 franchit 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 ticks sont autorisés à être des points de terminaison 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éé viaCreatePermissionedPoolet l’index fait partie des seeds du 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 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 publié de paliers de frais CLMM (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 seul enregistrement par tick. Ce serait des milliards de comptes. À la place, il groupe TICK_ARRAY_SIZE ticks adjacents initialisés ou non (généralement 60 ou 88 selon la version du programme) dans un TickArrayState qui est créé paresseusement à la première utilisation.
order_phaseest l’id de cohorte. Il s’incrémente chaque fois qu’une cohorte passe de « tout non rempli » à « partiellement rempli ».orders_amountest le total du token d’entrée de la cohorte actuelle (la plus nouvelle).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 de point de terminaison de position t doit satisfaire
t % tick_spacing == 0. Le programme rejette les positions hors espacement. - L’array du tick est situé à
floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing). - Un array de ticks est initialisé paresseusement : la première position ou swap qui touche un array non initialisé le crée, en payant le loyer.
- Un array de ticks 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’y a pas de chemin de nettoyage entraîné parClosePositionpour les arrays de ticks.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (inline) couvre la plage « proche du spot » — ±512 arrays de ticks (TICK_ARRAY_BITMAP_SIZE = 512 ; le champ [u64; 16] est 1 024 bits divisés équitablement entre les indices de démarrage négatifs et positifs, donc les indices d’array −512 … +511). Au-delà de cette plage (pour les valeurs de ticks 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 :Mint du NFT de position
Un mint SPL Token ou Token-2022 avec supply 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, pas à une Pubkey stockée dans l’état. Les nouveaux mints de 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 du 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 vault sous-jacent apparaît sur la liste des émetteurs restreints de CLMM. Seulement alors CLMM gèle le compte du 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 du NFT.
ProtocolPositionState (déprécié)
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 on-chain sont vestigiaux ; l’admin peut appeler CloseProtocolPosition pour récupérer le loyer pour eux.La comptabilité agrégée de plage est maintenant dérivée directement des deux ticks de point de terminaison (liquidity_gross, liquidity_net, et les fee_growth_outside_* / reward_growths_outside_x64 par tick) dans TickArrayState. La formule de croissance des frais internes fee_growth_inside = global − outside_lower − outside_upper continue de fonctionner sans un compte de position agrégé.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’admin et partagé entre les pools qui s’inscrivent. 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 (gated admin) et modifié via update_dynamic_fee_config. Un pool créé avec enable_dynamic_fee = true capture les cinq paramètres de calibrage du config (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) dans son propre DynamicFeeInfo à la création ; les modifications ultérieures au 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 token d’entrée, l’ordre est lié à une cohorteTickState. - (optionnel) Augmentation / Diminution —
increase_limit_orderajoute àtotal_amount;decrease_limit_orderretourne les tokens non remplis (et toute sortie réglée jusqu’à ce point). - Règlement — quand la cohorte est entièrement ou partiellement remplie, le propriétaire ou le gardien opérationnel appelle
settle_limit_orderpour pousser les tokens de sortie vers l’ATA du propriétaire. - Fermeture — une fois
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 d’ordre est donc unique par (owner, nonce_index, order_nonce).
LimitOrderNonce
Compteur par (wallet, nonce_index) qui permet à un seul utilisateur d’exécuter plusieurs pipelines parallèles d’ordres limites sans collisionner 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
Un compte de capacité dont l’existence est la subvention : si un PDA Permission est dérivé pour une autorité donnée, cette autorité peut appeler CreatePermissionedPool. Il ne stocke rien au-delà de l’autorité pour laquelle il a été créé.
["permission", authority.as_ref()]. Créé par un admin via CreatePermissionPda et démonté via ClosePermissionPda (le loyer est remboursé à l’appelant). Les deux instructions admin acceptent soit le admin du programme, soit une clé permission_pda_admin dédiée. Fermer le PDA révoque la subvention — l’autorité ne peut plus créer de pools supplémentaires, mais les pools qu’elle a déjà créés ne sont pas affectés.
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 pour la durée de vie du pool. Une fois qu’un array de ticks a été initialisé, il reste on-chain même quand chaque tick à l’intérieur revient à liquidity_gross == 0. Réutiliser un array de ticks existant est gratuit ; seule la première position qui touche un array jamais initialisé paie son loyer.
Quoi lire où
- Mathématiques des ticks et mécaniques de plage :
products/clmm/ticks-and-positions. - Marche du 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.

