Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
reference/program-addresses. Пул CLMM требует больше аккаунтов, чем пул CPMM, потому что ликвидность хранится разреженно по диапазону тиков; понимание этой разреженности — основная часть этой страницы.
Инвентарь аккаунтов
Активный пул CLMM описывается следующими семействами аккаунтов. Все принадлежат программе CLMM, кроме двух минтов и их хранилищ.PoolState
Текущее состояние пула, читается при каждом своппе и каждом изменении позиции.
sqrt_price_x64иtick_current— состояние цены пула. Обновляются вместе при каждом своппе.tick_current— это пол отlog_{1.0001}(price).liquidity— это активная ликвидность — сумма значенийLдля всех позиций, диапазон которых содержитtick_current. Изменяется каждый раз, когда своп пересекает тик, и каждый раз, когда позиция открывается/закрывается/изменяется.fee_growth_global_{0,1}_x64— кумулятивные комиссии, заработанные на единицу ликвидности по всей истории пула. Позиции читают это, чтобы вычислить, что им причитается.tick_spacingпривязан кAmmConfigпри инициализации и никогда не меняется. Он определяет, какие индексы тиков могут быть конечными точками позиции.tick_array_bitmap— это встроенная битовая карта, охватывающая часто используемый диапазон тиков вокруг спотовой цены. Для пулов, позиции которых простираются далеко, отслеживание переполнения находится в отдельномTickArrayBitmapExtension.fee_onфиксируется при создании пула.0(FromInput) воспроизводит классическое поведение Uniswap-V3.1и2направляют комиссию своппа на одну сторону книги — см.products/clmm/feesдля анализа компромиссов.seed_index— это[0, 0]для каждого пула, созданного черезCreatePool/CreateCustomizablePool(один канонический пул на пару). Ненулевое значение означает, что пул был создан черезCreateCustomizablePoolV2(до 2026-10-22 называлсяCreatePermissionedPool) и индекс является частью семян PDA пула, позволяя нескольким пулам сосуществовать для одной и той же(config, mint0, mint1). Чтобы повторно вывести адрес такого пула, вы должны знать егоseed_index.dynamic_fee_infoсодержит состояние волатильности для надбавки динамической комиссии. Когда включено, каждый своп пересчитываетdynamic_fee_componentповерхAmmConfig.trade_fee_rate. Структура документирована подDynamicFeeInfoниже; пулы без динамической комиссии оставляют всю структуру нулевой.
AmmConfig
CreateAmmConfig записывает жестко закодированный protocol_fee_owner::ID программы в owner и fund_fee_owner::ID в fund_owner. До этого он копировал ключ подписавшего администратора в оба. Существующие конфиги сохраняют то, на что они были созданы или ротированы, поэтому читайте оба поля с аккаунта. Параметры UpdateAmmConfig 3 / 4 по-прежнему их ротируют. Адреса находятся в reference/program-addresses.
Типичный опубликованный набор уровней комиссий CLMM (подтвердите против GET https://api-v3.raydium.io/main/clmm-config):
protocol_fee_rate и fund_fee_rate — это доли торговой комиссии; то же соглашение, что и в CPMM. См. products/clmm/fees.
TickArrayState
CLMM не хранит отдельную запись для каждого тика. Это потребовало бы миллиарды аккаунтов. Вместо этого программа группирует TICK_ARRAY_SIZE соседних инициализированных или неинициализированных тиков (обычно 60 или 88 в зависимости от версии программы) в TickArrayState, который создаётся лениво при первом использовании.
order_phase— это идентификатор когорты. Он увеличивается каждый раз, когда когорта переходит из состояния «полностью неисполненная» в «частично исполненная».orders_amount— это общее количество входного токена текущей (новейшей) когорты.part_filled_orders_remainingотслеживает предыдущую когорту, которая в настоящий момент исполняется текущими свопами.unfilled_ratio_x64— это множитель Q64.64, привязанный к когорте: когда своп исполняет X% когорты, коэффициент умножается на(1 − X). Каждый открытый ордер хранит свой снимок(order_phase, unfilled_ratio_x64)в момент открытия, поэтому математика расчёта сводится к сравнению снимков.
- Конечный тик позиции t должен удовлетворять условию
t % tick_spacing == 0. Программа отклоняет позиции с неправильным интервалом. - Массив тика расположен по адресу
floor(t / (TICK_ARRAY_SIZE * tick_spacing)) * (TICK_ARRAY_SIZE * tick_spacing). - Массив тиков инициализируется лениво: первая позиция или своп, которые касаются неинициализированного массива, создают его и оплачивают ренту.
- Массив тиков никогда не закрывается программой. После выделения он сохраняется на протяжении всего времени существования пула, даже после того, как каждый тик внутри него вернётся к
liquidity_gross == 0. Последующие позиции и свопы повторно используют существующий аккаунт без дополнительной ренты. Нет пути очистки массивов тиков, управляемогоClosePosition.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (встроенный) охватывает диапазон «близко к спот» — ±512 массива тиков (TICK_ARRAY_BITMAP_SIZE = 512; поле [u64; 16] содержит 1024 бита, поровну разделённые между отрицательными и положительными начальными индексами, поэтому индексы массива −512 … +511). За пределами этого диапазона (для экстремальных значений тиков) программа поддерживает аккаунт расширения:
(MIN_TICK, MAX_TICK)) требуют его; SDK разрешает это за вас.
Позиции
Позиция CLMM — это набор из трёх аккаунтов плюс минт:Минт NFT позиции
Минт SPL Token или Token-2022 с предложением 1. NFT позиции в кошельке владельца — это ATA, содержащий этот единственный токен. Программа привязывает авторизацию к текущему держателю баланса ATA NFT, а не к Pubkey, хранящемуся в состоянии. Новые минты NFT позиции устанавливаютpool_state как свой freeze authority перед минтингом единственного токена и удалением mint authority. Установка freeze authority не замораживает сам аккаунт NFT. Аккаунт остаётся разморозенным и передаваемым, если только не выполнены оба условия: вызывающий использует OpenPositionV2 или OpenPositionWithToken22Nft, и freeze authority хотя бы одного базового минта хранилища появляется в списке ограниченных издателей CLMM. Только тогда CLMM замораживает аккаунт NFT после минтинга. Это не изменяет ни один байт PersonalPositionState или PoolState.
PersonalPositionState
Один на открытую позицию. Привязан к минту NFT.
ProtocolPositionState (устарело)
Более старые версии CLMM хранили агрегированную бухгалтерию по
(pool, tick_lower, tick_upper) в PDA ProtocolPositionState. Новые версии больше не создают и не читают этот аккаунт. Слот по-прежнему появляется в списках аккаунтов OpenPosition / IncreaseLiquidity / DecreaseLiquidity как UncheckedAccount для совместимости ABI, но программа не записывает в него. Существующие аккаунты в цепи — это рудименты; администратор может вызвать CloseProtocolPosition для возврата ренты.Агрегированная бухгалтерия диапазона теперь выводится непосредственно из двух конечных тиков (liquidity_gross, liquidity_net и полей fee_growth_outside_* / reward_growths_outside_x64 для каждого тика) в TickArrayState. Формула fee-growth-inside fee_growth_inside = global − outside_lower − outside_upper продолжает работать без аккаунта агрегированной позиции.Observation
(tick_cumulative[t1] − tick_cumulative[t0]) / (t1 − t0), а затем price = 1.0001 ** tick. См. algorithms/clmm-math.
DynamicFeeConfig и DynamicFeeInfo
Параметры динамической комиссии находятся в двух местах. Переиспользуемый шаблон — DynamicFeeConfig — управляется администратором и используется пулами, которые согласились. Состояние выполнения для каждого пула — DynamicFeeInfo — встроено в PoolState и обновляется каждым свопом.
DynamicFeeConfig
["dynamic_fee_config", index.to_be_bytes()]. Создаётся через create_dynamic_fee_config (с ограничением администратора) и изменяется через update_dynamic_fee_config. Пул, созданный с enable_dynamic_fee = true, снимает пять параметров калибровки конфига (filter_period, decay_period, reduction_factor, dynamic_fee_control, max_volatility_accumulator) в свой собственный DynamicFeeInfo при создании; более поздние изменения DynamicFeeConfig не влияют ретроактивно на существующие пулы.
DynamicFeeInfo (встроено в PoolState)
DynamicFeeConfig. Математика комиссии и правила затухания задокументированы в products/clmm/math и products/clmm/fees.
Константы, используемые формулой:
LimitOrderState
Один аккаунт на открытый лимитный ордер.
- Open — пользователь вызывает
open_limit_order, депонируетtotal_amountвходного токена, ордер привязывается к когортеTickState. - (опционально) Increase / Decrease —
increase_limit_orderдобавляет кtotal_amount;decrease_limit_orderвозвращает неисполненные токены (и любой исполненный выход до этого момента). - Settle — когда когорта полностью или частично исполнена, владелец или оперативный хранитель вызывает
settle_limit_orderдля отправки выходных токенов на ATA владельца. - Close — как только
unfilled_amount == 0, аккаунт можно закрыть. Рента всегда возвращаетсяowner.
[owner.as_ref(), limit_order_nonce.key().as_ref(), limit_order_nonce.order_nonce.to_be_bytes().as_ref()]. Таким образом, PDA ордера уникален для каждого (owner, nonce_index, order_nonce).
LimitOrderNonce
Счётчик для каждой пары (wallet, nonce_index), позволяющий одному пользователю запускать несколько параллельных конвейеров лимитных ордеров без коллизий на PDA.
[user_wallet.as_ref(), &[nonce_index]]. Большинство клиентов используют nonce_index = 0 и позволяют order_nonce нести кардинальность.
Permission (снято с производства)
Аккаунт Permission был удалён в обновлении от 2026-10-22. Раньше он ограничивал доступ к CreatePermissionedPool, которая теперь является бесправовой CreateCustomizablePoolV2. Программа больше не читает и не закрывает эти аккаунты, а инструкции CreatePermissionPda / ClosePermissionPda удалены. PDA, созданные до обновления (["permission", authority], 280 байт), остаются в цепи как инертные данные; игнорируйте их при сканировании аккаунтов, принадлежащих CLMM.
Получение ключевых аккаунтов
reference/program-addresses.
Краткий справочник жизненного цикла
Аккаунты
TickArrayState никогда не закрываются программой — они сохраняются на протяжении всей жизни пула. После инициализации tick array он остаётся в цепи даже когда каждый tick внутри него возвращается к liquidity_gross == 0. Повторное использование существующего tick array бесплатно; только первая позиция, касающаяся никогда не инициализированного массива, платит его rent.
Что читать где
- Математика tick и механика диапазонов:
products/clmm/ticks-and-positions. - Прохождение swap и математика роста комиссий:
products/clmm/math. - Списки аккаунтов инструкций:
products/clmm/instructions. - Комиссии и начисление вознаграждений:
products/clmm/fees. - Канонические ID программ и seed:
reference/program-addresses.

