Эта страница переведена с помощью ИИ. За эталон принимается английская версия.Открыть английскую версию →
Program ID и PDA seeds для CPMM перечислены в
reference/program-addresses. На этой странице основное внимание уделяется назначению каждого аккаунта и инвариантам, которые он поддерживает, а не жёстко закодированным адресам.Шесть аккаунтов пула CPMM
Каждый пул CPMM полностью описывается шестью адресами, производными от программы (PDA), под программой CPMM, плюс один общий аккаунтAmmConfig, на который он ссылается. Имея два mint’а, вы можете детерминированно вывести всё остальное без обращения к сети.
И общая конфигурация:
Вывод пула из двух mint’ов
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 mint. Используйте его для математики LP-доли; значение должно совпадать с предложением mint в цепи, но чтение его изPoolStateизбегает дополнительной выборки аккаунта.protocol_fees_token{0,1},fund_fees_token{0,1}— накопленные комиссии, которые ещё не были собраны. Они не влияют на цену swap; они остаются в хранилищах до вызоваCollectProtocolFee/CollectFundFee.status— битовая маска, контролирующая, разрешены лиSwap,Deposit,Withdraw. Обновляется администратором черезUpdatePoolStatus. SDK проверяет это перед построением транзакции; если вы CPI’ите напрямую, проверьте это сами.token0_program/token1_program— программа токена для CPI в каждое хранилище. Одна может быть классическим SPL Token, а другая Token-2022; они независимы.open_time— временная метка Unix. Swap’ы до этого времени не удаются. Депозиты разрешены до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. Оба пути обнуляют полные счётчики; путь без разрешения фиксирует получателей на канонические ATApool_creator.
AmmConfig
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.index— этоu16, поэтому seed hash использует 2 байта big-endian. Ошибка на один в порядке байтов — частая ошибка интеграции.AmmConfigнеизменяем на уровне пула. Пул указывает на одинAmmConfigпри создании и никогда не переключается. Изменения комиссий распространяются, потому что пул читает конфиг при каждом swap — но пул не может быть перемещён между уровнями комиссий.
creator_fee_rate) находится на AmmConfig и общая для уровня комиссии. Взимает ли конкретный пул её на самом деле (enable_creator_fee) и с какой стороны swap она приземляется (creator_fee_on) находятся на PoolState. Комиссия создателя независима от торговой комиссии — это её собственная ставка, накопленная на её собственные счётчики (creator_fees_token_{0,1}), и никогда не уменьшает доли LP / протокола / фонда торговой комиссии. Сбор осуществляется через CollectCreatorFee или ограниченный по назначению CollectCreatorFeePermissionless. Полная механика в products/cpmm/fees.
Permission
Небольшой аккаунт контроля доступа, используемый InitializeWithPermission. Программа CPMM поддерживает путь создания пула с разрешением, чтобы другие программы (например, LaunchLab при переводе токена на CPMM) могли доказать, что они имеют право создать пул для данного AmmConfig.
CreatePermissionPda либо администратором CPMM, либо выделенным создателем PDA разрешений. Начиная с обновления 2026-09, ClosePermissionPda принимает тех же двух подписантов; раньше это было только для администратора. Конечные пользователи не взаимодействуют с этим аккаунтом напрямую — это сантехника для кросс-программных потоков. См. security/admin-and-multisig для границы ролей и reference/program-addresses для канонических адресов.
Хранилища и 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 при каждом переводе. Пул находится на принимающей стороне для депозитов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 перед созданием нового пула для него — существующие пулы не затронуты, потому что проверка выполняется только при создании пула.programs/cp-swap/src/utils/token.rs и может измениться при будущих обновлениях программы. См. reference/token-2022-support для матрицы кросс-программ.
Observation
Аккаунт observation — это кольцевой буфер записейObservationState, каждая хранит block_timestamp и кумулятивную цену. При каждом swap программа добавляет новое наблюдение, если прошло достаточно времени с момента последнего. TWAP вычисляются путём чтения двух наблюдений и деления Δcumulative / Δtime.
ObservationState составляет около 4100 байт после окружающих полей и дискриминатора.
Два правила для потребителей:
- Не используйте одно наблюдение как цену. Это кумулятив, а не спот-цена. Используйте два из них для вычисления TWAP.
- Выбирайте наблюдения, разделённые как минимум одним блоком. Swap’ы в одном блоке могут не создать новое наблюдение; чтение подряд может вернуть одну и ту же запись.
products/clmm/accounts.
Жизненный цикл аккаунта
Пулы CPMM и их PDA никогда не закрываются. Даже при нулевой ликвидности
poolState остаётся. Это намеренно: повторное заполнение того же пула позже сохраняет его исторический буфер наблюдений и его вывод PDA остаётся стабильным.
Что читать где
- Списки аккаунтов инструкций (какие из вышеперечисленных являются writable/signer для каждой инструкции):
products/cpmm/instructions. - Семантика начисления комиссий:
products/cpmm/fees. - Математика swap / правило обновления наблюдений:
products/cpmm/math. - Канонические seeds / program IDs:
reference/program-addresses.

