Skip to main content
Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
ID программы и seeds PDA для CPMM перечислены в reference/program-addresses. На этой странице основное внимание уделяется назначению каждого аккаунта и инвариантам, которые он поддерживает, а не жестко закодированным адресам.

Шесть аккаунтов пула CPMM

Каждый пул CPMM полностью описывается шестью программно-производными адресами (PDA) под программой CPMM, плюс один общий аккаунт AmmConfig, на который он ссылается. Имея два mint’а, вы можете детерминированно вывести всё остальное без обращения к сети. И общая конфигурация: И один опциональный аккаунт на создателя:

Вывод пула из двух mint’ов

Всегда сортируйте mint’ы перед выводом PDA пула. Seed хеширует два mint’а в порядке байтов, а не в порядке пользователя. Два пула с (A, B) и (B, A) столкнулись бы в цепи — сортировка — это то, как программа делает отображение каноническим.
ID пула не всегда является каноническим PDA. Initialize принимает произвольную пару ключей подписанта как pool_state в дополнение к PDA выше. Если переданный аккаунт не совпадает с каноническим PDA, программа требует, чтобы он был подписантом — то есть создатель передаёт свежую пару ключей, которую они подписывают. Это защита от фронт-раннинга: любая третья сторона, спешащая захватить канонический PDA, может быть обойдена законным создателем, использующим вместо этого случайную пару ключей. Нижестоящие PDA (lpMint, vault0, vault1, observation) по-прежнему выводятся из poolState.key(), поэтому они остаются уникальными для любого использованного адреса. При индексировании пулов всегда обнаруживайте ID пула из состояния в цепи (например, аккаунты PoolState под программой CPMM), а не путём вывода канонического PDA — последний пропустит пулы со случайными парами ключей.

Макеты аккаунтов

Полные определения на Rust находятся в исходном коде raydium-cp-swap. Поля ниже — это те, которые вы будете читать при интеграции.

PoolState

Что на самом деле нужно читать:
  • lp_supply — внутреннее общее количество LP пула. Оно не равно предложению LP mint’а: оно ровно на 100 базовых единиц выше, потому что 100 заблокированных единиц считаются здесь, но никогда не выпускаются. Вся математика доли LP (deposit, withdraw) делится на lp_supply, поэтому используйте это поле и не подставляйте предложение mint’а из цепи.
  • protocol_fees_token{0,1}, fund_fees_token{0,1} — накопленные комиссии, ещё не собранные. Они не влияют на цену swap’а; они находятся в хранилищах до вызова CollectProtocolFee / CollectFundFee. protocol_fees_token{0,1} также получает долю протокола комиссии создателя при сборе комиссии создателя, поэтому растёт вне swap’ов — см. products/cpmm/fees.
  • status — битовая маска, контролирующая, разрешены ли Swap, Deposit, Withdraw. Обновляется администратором через UpdatePoolStatus. SDK проверяет это перед построением транзакции; если вы CPI’ите напрямую, проверьте это сами.
  • token0_program / token1_program — программа токена для CPI в каждое хранилище. Один может быть классическим SPL Token, а другой Token-2022; они независимы.
  • open_time — временная метка Unix. Swap’ы до этого времени не удаются. Deposit’ы разрешены до open_time, чтобы пул мог быть заполнен.
  • creator_fee_on / enable_creator_fee — вместе контролируют, активна ли опциональная комиссия создателя для этого пула и с какой стороны swap’а она собирается. enable_creator_fee == false полностью обнуляет путь комиссии создателя. Когда включено, creator_fee_on выбирает: 0 = взять комиссию с любого токена, который является входом swap’а (BothToken); 1 = взять комиссию только из token_0 (пропустить на swap’ах token_1 → token_0); 2 = взять комиссию только из token_1. Устанавливается при создании пула через InitializeWithPermission; не может измениться позже.
  • creator_fees_token_{0,1} — накопленные комиссии создателя, собираемые через CollectCreatorFee или CollectCreatorFeePermissionless. Оба пути обнуляют полные счётчики, но с обновлением creator-fee-share от 2026-09-19 из пула уходит только часть баланса: доля протокола добавляется к protocol_fees_token_{0,1} и остаток передаётся создателю. Путь без разрешения фиксирует получателей на канонических ATA pool_creator. Сам PoolState не изменился — нет отдельного счётчика для общей суммы.

AmmConfig

Три вещи, на которые нужно обратить внимание:
  1. trade_fee_rate и creator_fee_rate — доли объёма, обе обозначены в единицах 1/1_000_000. 2500 означает 0.25% от объёма торговли. protocol_fee_rate и fund_fee_rate — доли торговой комиссии (не объёма), в том же знаменателе 1/1_000_000. Комиссия создателя не является долей торговой комиссии — это её собственная независимая ставка. Полная арифметика находится в products/cpmm/fees.
  2. index — это u16, поэтому seed хеш использует 2 байта big-endian. Ошибка на один в порядке байтов — частая ошибка интеграции.
  3. AmmConfig неизменяем на уровне пула. Пул указывает на один AmmConfig при создании и никогда не переключается. Изменения комиссий распространяются, потому что пул читает конфиг при каждом swap’е — но пул не может быть перемещён между уровнями комиссии.
Заметка о комиссиях создателя: сама ставка (creator_fee_rate) находится на AmmConfig и общая для уровня комиссии. Взимает ли конкретный пул её на самом деле (enable_creator_fee) и с какой стороны swap’а она приземляется (creator_fee_on) находятся на PoolState. Комиссия создателя независима от торговой комиссии — это её собственная ставка, накопленная на её собственные счётчики (creator_fees_token_{0,1}), и никогда не уменьшает доли LP / протокола / фонда торговой комиссии. Сборка происходит через CollectCreatorFee или ограниченный по назначению CollectCreatorFeePermissionless, и оба пути передают долю накопленного баланса протоколу на выходе — по creator_fee_share_rate, или по ставке на PDA CreatorFeeShare когда он существует для пары (creator, amm_config). См. products/cpmm/fees для полной механики.

Permission

Небольшой аккаунт контроля доступа, используемый InitializeWithPermission. Программа CPMM поддерживает путь создания пула с разрешением, чтобы другие программы (например, LaunchLab при переводе токена на CPMM) могли доказать, что они имеют право создать пул для данного AmmConfig.
PDA Permission создаётся через CreatePermissionPda либо администратором CPMM, либо выделенным создателем PDA разрешений. С обновлением 2026-09 ClosePermissionPda принимает тех же двух подписантов; раньше это было только администратором. Конечные пользователи не взаимодействуют с этим аккаунтом напрямую — это сантехника для кросс-программных потоков. См. security/admin-and-multisig для границы роли и reference/program-addresses для канонических адресов.

CreatorFeeShare

Опциональный аккаунт, который переопределяет долю протокола в комиссии создателя для одной пары (pool creator, AmmConfig). Добавлено обновлением creator-fee-share от 2026-09-19.
Как это работает:
  • Это опционально, но аккаунт никогда не опционален в инструкции. CollectCreatorFee и CollectCreatorFeePermissionless оба объявляют creator_fee_share с ограничением seed выше и берут его при каждом вызове. Программа затем проверяет, пуст ли аккаунт или принадлежит иностранцу; если так, она возвращается к AmmConfig.creator_fee_share_rate. Поэтому клиент должен всегда выводить и передавать адрес, независимо от того, существует ли аккаунт.
  • share_rate ограничен FEE_RATE_DENOMINATOR_VALUE (1_000_000) при создании и снова при выполнении разделения. 1_000_000 маршрутизирует всю комиссию создателя протоколу; 0 не маршрутизирует ничего.
  • Создаётся и закрывается администратором или выделенным органом власти через CreateCreatorFeeShare / CloseCreatorFeeShare. Закрытие возвращает ренту подписанту и возвращает пару к значению по умолчанию конфига; создатель пула не является подписантом ни на одном пути.
  • Это ключ по создателю, а не по пулу. Один аккаунт управляет каждым пулом, который этот создатель имеет на этом AmmConfig. Создатель с пулами на двух уровнях комиссии нуждается в двух аккаунтах, чтобы быть охваченным на обоих.
Арифметика разделения, которую она управляет, находится в products/cpmm/fees.

Хранилища и Token-2022

vault0 и vault1 принадлежат PDA authority CPMM, и их владелец token-программы (token_program) — это либо SPL Token, либо Token-2022, определяемый при создании пула программой mint’а. Пул прозрачно обрабатывает оба случая — вы передаёте правильный ID token-программы для каждой стороны в аккаунты инструкции Swap / Deposit / Withdraw. CPMM применяет строгий список разрешений расширений при создании пула (is_supported_mint в utils/token.rs). Mint Token-2022 может использоваться в пуле CPMM только если каждое расширение, которое он несёт, находится в этом списке:
  • TransferFeeConfig. Применяется mint’ом при каждом переводе. Пул находится на принимающей стороне для deposit’ов SwapBaseInput и на отправляющей стороне для вывода. Программа вычисляет чистую сумму, попадающую в хранилище, и устанавливает кривую соответственно. См. algorithms/token-2022-transfer-fees.
  • MetadataPointer и TokenMetadata. Стандартные метаданные на mint’е. Никакого влияния на математику swap’а.
  • InterestBearingConfig. UI сумма mint’а начисляет проценты. Хранилище хранит сырые суммы; кривая работает только с сырыми суммами. UI’ы, которые показывают APR, должны вызывать помощников Token-2022 для отображения UI суммы.
  • ScaledUiAmount. Расширение масштабирования отображения UI. Такая же обработка, как InterestBearingConfig — кривая использует сырые суммы.
Любое другое расширение — PermanentDelegate, TransferHook, DefaultAccountState, NonTransferable, ConfidentialTransfer, Group/GroupMember, MintCloseAuthority и т.д. — вызывает отклонение Initialize с NotSupportMint. Единственное исключение — это реестр для каждого mint’а: если PDA SupportMintAssociated существует с seed [b"support_mint", mint], mint допускается независимо от его набора расширений. Этот PDA создаётся и удаляется администратором (или выделенным органом поддержки mint’ов) через CreateSupportMintAssociated / CloseSupportMintAssociated, поэтому подключение конкретного mint’а больше не требует обновления программы.
Изменено в 2026-09. CPMM ранее также содержал жестко закодированный четырёхадресный MINT_WHITELIST, который обходил проверку расширений. Этот массив был удалён; реестр PDA теперь является единственным обходом. Любой mint, который полагался на жестко закодированный список, нуждается в PDA SupportMintAssociated перед созданием нового пула для него — существующие пулы не затронуты, потому что проверка выполняется только при создании пула.
Список проверенных расширений находится в исходном коде CP-Swap под programs/cp-swap/src/utils/token.rs и может измениться с будущими обновлениями программы. См. reference/token-2022-support для матрицы кросс-программ.

Observation

Аккаунт observation — это кольцевой буфер записей ObservationState, каждая хранящая block_timestamp и кумулятивную цену. При каждом swap’е программа добавляет новое наблюдение, если прошло достаточно времени с последнего. TWAP’ы вычисляются путём чтения двух наблюдений и деления Δcumulative / Δtime.
Кольцевой буфер рассчитан на 100 наблюдений. Каждое наблюдение — 40 байт (8 + 16 + 16), поэтому сам массив — 4,000 байт; ObservationState::LEN — ровно 4,075 байт (8 + 1 + 2 + 32 + 4,000 + 8 × 4). Два правила потребителя:
  • Не используйте одно наблюдение как цену. Это кумулятив, а не спот-цена. Используйте два из них для вычисления TWAP.
  • Выбирайте наблюдения по крайней мере на один блок друг от друга. Swap’ы в одном блоке могут не создать новое наблюдение; чтение подряд может вернуть одну и ту же запись.
Больше математики в products/clmm/accounts.

Жизненный цикл аккаунта

Пулы CPMM и их PDA никогда не закрываются. Permission, SupportMintAssociated и CreatorFeeShare — исключения — это автономные управляемые администратором записи, а не состояние пула, и каждый имеет явную инструкцию закрытия. Даже при нулевой ликвидности poolState остаётся. Это намеренно: повторное заполнение того же пула позже сохраняет его исторический буфер наблюдений и его вывод PDA остаётся стабильным.

Что читать где

  • Списки аккаунтов инструкций (какие из вышеперечисленных доступны для записи/подписи для каждой инструкции): products/cpmm/instructions.
  • Семантика начисления комиссий: products/cpmm/fees.
  • Математика swap’а / правило обновления наблюдений: products/cpmm/math.
  • Канонические seed’ы / ID программ: reference/program-addresses.
Источники: