Documentation Index
Fetch the complete documentation index at: https://docs.raydium.io/llms.txt
Use this file to discover all available pages before exploring further.
Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
На этой странице описаны структура и роль каждого аккаунта. Канонические сиды перечислены в
reference/program-addresses. CLMM-пул использует больше аккаунтов, чем CPMM-пул, поскольку ликвидность хранится разреженно по диапазону тиков — понимание этой разреженности составляет основу данной страницы.Перечень аккаунтов
Активный CLMM-пул описывается следующими группами аккаунтов. Все они принадлежат программе CLMM, за исключением двух минтов и их хранилищ.| Аккаунт | Назначение | Количество на пул |
|---|---|---|
AmmConfig | Уровень комиссии: ставка торговой комиссии, доля протокола, доля фонда, шаг тиков по умолчанию. Общий для всех пулов данного уровня. | 1 (общий) |
PoolState | Текущий sqrt_price_x64, текущий тик, общая ликвидность, глобальный прирост комиссий, информация о наградах, указатель на observation. | 1 |
TickArrayState | Блок из TICK_ARRAY_SIZE смежных тиков. Инициализируется по требованию. | 0 ≤ N ≤ диапазон |
TickArrayBitmapExtension | Расширенный bitmap, отслеживающий существующие tick-массивы за пределами встроенного bitmap в PoolState. | 0 или 1 |
PersonalPositionState | По одному на каждую LP-позицию. Хранит диапазон, ликвидность и последнее зафиксированное значение прироста комиссий/наград. Authority = владелец NFT. | 1 на позицию |
| Position NFT mint | Минт с supply = 1, связанный с PersonalPositionState. Передача NFT = передача позиции. | 1 на позицию |
ObservationState | Кольцевой буфер ценовых наблюдений для TWAP. | 1 |
token_0_vault, token_1_vault | Token-аккаунты, хранящие балансы пула. Принадлежат authority пула. | 2 |
DynamicFeeConfig | Переиспользуемый набор параметров механизма динамической комиссии. Пулы, созданные через create_customizable_pool, могут подключиться. Управляется администратором. | общий (по индексу) |
LimitOrderState | По одному на каждый открытый лимитный ордер. Содержит владельца, тик, направление, общий объём и снимок исполненного вывода. | 1 на ордер |
LimitOrderNonce | Счётчик для пары (wallet, nonce_index), обеспечивающий уникальность PDA ордеров. | 1 на (wallet, index) |
PoolState
Текущее состояние пула, считываемое при каждом swap и каждом изменении позиции.
sqrt_price_x64иtick_current— ценовое состояние пула. Обновляются вместе при каждом swap.tick_current— это нижняя целая частьlog_{1.0001}(price).liquidity— активная ликвидность: сумма значенийLдля всех позиций, чей диапазон содержитtick_current. Изменяется каждый раз, когда swap пересекает тик, а также при открытии, закрытии или изменении размера позиции.fee_growth_global_{0,1}_x64— накопленные комиссии на единицу ликвидности за всю историю пула. Позиции используют это значение для расчёта причитающейся им суммы.tick_spacingпривязывается кAmmConfigпри инициализации и никогда не меняется. Определяет, какие индексы тиков допустимы в качестве граничных точек позиций.tick_array_bitmap— встроенный bitmap, охватывающий часто используемый диапазон тиков вблизи спот-цены. Для позиций, выходящих за эти границы, отслеживание ведётся в отдельном аккаунтеTickArrayBitmapExtension.fee_onфиксируется при создании пула. Значение0(FromInput) воспроизводит поведение классического Uniswap V3. Значения1и2направляют комиссию swap на одну из сторон — подробнее о компромиссах см.products/clmm/fees.dynamic_fee_infoхранит состояние волатильности для надбавки динамической комиссии. При включении каждый swap пересчитываетdynamic_fee_componentповерхAmmConfig.trade_fee_rate. Структура описана ниже в разделеDynamicFeeInfo; у пулов без динамической комиссии весь struct равен нулю.
AmmConfig
GET https://api-v3.raydium.io/main/clmm-config):
| Индекс | trade_fee_rate | Шаг тиков | Типичное применение |
|---|---|---|---|
| 0 | 100 (0.01%) | 1 | Стабильные пары, USDC/USDT |
| 1 | 500 (0.05%) | 10 | Коррелированные blue-chip активы |
| 2 | 2_500 (0.25%) | 60 | Стандартные пары |
| 3 | 10_000 (1.00%) | 120 | Волатильные или низколиквидные активы |
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— остаток предыдущей когорты, которая в данный момент исполняется текущими swap-ами.unfilled_ratio_x64— мультипликатор Q64.64 когорты: когда swap заполняет 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). - Tick-массив инициализируется лениво: первая позиция или swap, обращающиеся к неинициализированному массиву, создают его и оплачивают rent.
- Tick-массив никогда не закрывается программой. Однажды выделенный, он существует на протяжении всего жизненного цикла пула, даже если все тики внутри вернулись к
liquidity_gross == 0. Последующие позиции и swap-ы переиспользуют существующий аккаунт без дополнительной оплаты rent. Пути очистки tick-массивов черезClosePositionне существует.
TickArrayBitmapExtension
PoolState.tick_array_bitmap (встроенный) охватывает диапазон «вблизи спота» — ±1 024 tick-массива. За пределами этого диапазона (для экстремальных значений тиков) программа ведёт отдельный аккаунт расширения:
(MIN_TICK, MAX_TICK)) требуют его; SDK разрешает это автоматически.
Позиции
Позиция CLMM — это связка из трёх аккаунтов и одного минта.Position NFT mint
Минт SPL Token с supply = 1. Адрес минта — детерминированный PDA; Position NFT в кошельке владельца — это просто ATA, хранящий этот единственный токен. Передача NFT — это и есть смена владельца позиции: программа привязывает авторизацию к текущему держателю баланса ATA NFT, а не к Pubkey, хранящемуся в состоянии.PersonalPositionState
По одному на каждую открытую позицию. Ключ — адрес NFT-минта.
ProtocolPositionState (устарело)
В ранних версиях CLMM агрегированные данные по диапазону
(pool, tick_lower, tick_upper) хранились в PDA ProtocolPositionState. Новые версии этот аккаунт не создают и не читают. В списке аккаунтов инструкций OpenPosition / IncreaseLiquidity / DecreaseLiquidity слот по-прежнему присутствует как UncheckedAccount для совместимости ABI, но программа в него не записывает. Существующие аккаунты на-чейне являются устаревшими; администратор может вызвать CloseProtocolPosition для возврата rent.Агрегированные данные диапазона теперь вычисляются напрямую из двух граничных тиков (liquidity_gross, liquidity_net и fee_growth_outside_* / reward_growths_outside_x64 по каждому тику) в TickArrayState. Формула прироста комиссии внутри диапазона — 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 и обновляется при каждом swap.
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.
Константы, используемые в формуле:
| Константа | Значение | Смысл |
|---|---|---|
VOLATILITY_ACCUMULATOR_SCALE | 10_000 | Гранулярность аккумулятора волатильности |
REDUCTION_FACTOR_DENOMINATOR | 10_000 | Знаменатель для reduction_factor |
DYNAMIC_FEE_CONTROL_DENOMINATOR | 100_000 | Знаменатель для dynamic_fee_control |
MAX_FEE_RATE_NUMERATOR | 100_000 | Жёсткий потолок ставки комиссии — 10% |
LimitOrderState
По одному аккаунту на каждый открытый лимитный ордер.
- Открытие — пользователь вызывает
open_limit_order, вноситtotal_amountвходящего токена; ордер привязывается к когортеTickState. - (необязательно) Увеличение / Уменьшение —
increase_limit_orderдобавляет кtotal_amount;decrease_limit_orderвозвращает неисполненные токены (и любой накопленный вывод на этот момент). - Расчёт — когда когорта исполнена полностью или частично, владелец или оперативный keeper вызывает
settle_limit_order, чтобы перечислить выходные токены в ATA владельца. - Закрытие — когда
unfilled_amount == 0, аккаунт можно закрыть. Rent всегда возвращается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.
Вычисление ключевых аккаунтов
reference/program-addresses.
Краткий справочник по жизненному циклу
| Событие | Создаваемые аккаунты | Уничтожаемые аккаунты |
|---|---|---|
CreatePool | poolState, observation, token_0_vault, token_1_vault | — |
OpenPosition[WithToken22Nft] | NFT mint + ATA, personalPosition, возможно новые tickArrayState, tickArrayBitmapExtension (если ещё не создан) | — |
IncreaseLiquidity | Возможно новые tickArrayState | — |
DecreaseLiquidity | — | Возможно очищает записи тиков (но сам tickArrayState не закрывается) |
ClosePosition | — | NFT mint, personalPosition |
SwapV2 | Возможно новый tickArrayState | — |
OpenLimitOrder | limitOrderState, возможно limitOrderNonce (init-if-needed), возможно новый tickArrayState | — |
IncreaseLimitOrder | — | — |
DecreaseLimitOrder | — | Закрывает limitOrderState, если ордер полностью исполнен |
SettleLimitOrder | — | — |
CloseLimitOrder | — | limitOrderState (rent → owner) |
CreateDynamicFeeConfig | dynamicFeeConfig | — |
CreateCustomizablePool | poolState, observation, vaults — аналогично CreatePool. Копирует dynamicFeeConfig, если enable_dynamic_fee = true. | — |
CollectRewards | — | — |
UpdateRewardInfos | — | — |
CloseProtocolPosition (admin) | — | Устаревший protocolPositionState (rent → admin) |
TickArrayState программой никогда не закрываются — они существуют на протяжении всего жизненного цикла пула. Однажды инициализированный tick-массив остаётся на-чейне, даже если все тики внутри вернулись к liquidity_gross == 0. Повторное использование существующего tick-массива бесплатно; rent платит только первая позиция, обращающаяся к ранее неинициализированному массиву.
Где искать дополнительную информацию
- Математика тиков и механика диапазонов:
products/clmm/ticks-and-positions. - Алгоритм swap и математика прироста комиссий:
products/clmm/math. - Списки аккаунтов инструкций:
products/clmm/instructions. - Комиссии и начисление наград:
products/clmm/fees. - Канонические ID программ и сиды:
reference/program-addresses.


