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é àAmmConfigà 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 « proche du spot » — ±1 024 tableaux de ticks. Pour les pools dont les positions s’étendent loin, le suivi du débordement vit dans le compteTickArrayBitmapExtensionsé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 redé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
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. - Le tableau du tick est situé à
floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing). - Un tableau de ticks est initialisé paresseusement : 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 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 tableaux de ticks.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (inline) couvre la plage « proche du spot » — ±1 024 tableaux de ticks. En dehors 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. Ce n’est que alors que 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 CLMM plus anciennes 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 de la config (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) dans son propre DynamicFeeInfo à 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 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 supprimé via ClosePermissionPda (le loyer est remboursé à l’appelant). Les deux instructions admin acceptent soit l’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 sont jamais fermés par le programme — ils persistent pour la durée de vie du pool. Une fois qu’un tableau de ticks a été initialisé, il reste on-chain même quand chaque tick à l’intérieur revient à liquidity_gross == 0. Réutiliser un tableau de ticks existant est gratuit ; seule la première position qui touche un tableau jamais initialisé paie son loyer.
Quoi lire où
- 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.

