Skip to main content
A documentation changelog entry for the 2026-08-17 CLMM program update. For the index of all updates, see reference/changelog. For the protocol’s own historical timeline, see introduction/history-and-milestones.
This release adds a conditional non-transferability path for selected KYC-restricted issuer pools. It does not freeze every new position, freeze pool assets, or prevent position owners from managing liquidity. The CLMM pool PDA becomes freeze authority for every new position NFT mint, but the NFT token account stays unfrozen by default. The program freezes it only when the position uses OpenPositionV2 or OpenPositionWithToken22Nft and either underlying vault mint carries a freeze authority from the hardcoded restricted-issuer list.

TL;DR for integrators

  • New position NFT mints have a freeze authority, but are not frozen by default. OpenPosition, OpenPositionV2, and OpenPositionWithToken22Nft set the position’s pool_state as mint freeze authority. Mint authority is still removed after the single NFT is minted.
  • Freezing requires a V2 path plus an issuer match. OpenPositionV2 and OpenPositionWithToken22Nft inspect vault_0_mint.freeze_authority and vault_1_mint.freeze_authority. The new NFT account is frozen only if at least one matches the program list. Without a match, it stays unfrozen and transferable.
  • Frozen means bound to the owner. SPL Token rejects NFT transfer and token-account owner changes with its native AccountFrozen error. Increase/decrease liquidity and fee/reward collection continue to work when the NFT owner signs.
  • Close remains available. ClosePosition detects a frozen NFT account, uses the pool PDA to thaw it, then burns the NFT and closes the position atomically.
  • Frozen close requires one remaining account. The client must append personal_position.pool_id as the first remaining account. Missing it returns CLMM AccountLack; passing the wrong pool returns NotApproved.
  • Existing positions are unaffected. The update does not retroactively change NFT mint authorities or freeze existing token accounts.
  • No CLMM state layout or declared IDL account-list change. PoolState, PersonalPositionState, and instruction arguments stay byte-compatible. The close-path requirement is carried through remaining_accounts.

Trigger logic

The program evaluates the two vault mints at open time:
A missing freeze authority does not match. One matching side is sufficient. The initial list contains the same issuer authority used by CLMM’s Superstate asset detection. The current mainnet-beta and devnet match keys live in reference/program-addresses. The check runs in the shared open-position handler only when vault mint accounts are supplied. This means:

Position NFT authority changes

Before this update, a newly-created classic SPL position NFT mint did not retain a freeze authority. After the update, every new position NFT mint names its pool as freeze authority, including positions in ordinary pools. This authority setting alone does not freeze the NFT token account; ordinary and non-matching positions remain unfrozen. Using the pool PDA instead of a global admin or issuer key narrows authority to one pool. An external party cannot sign as the PDA, and CLMM exposes no general-purpose instruction to freeze or thaw arbitrary position accounts. The new code uses the authority in two places only:
  1. Freeze immediately after minting when the underlying issuer check matches.
  2. Thaw during ClosePosition immediately before burn.

ClosePosition migration

The six declared accounts do not change. For a frozen NFT, add the pool as the first remaining account:
The handler verifies the key before loading PoolState, derives the pool signer seeds, and performs:
All steps run in one Solana instruction and therefore commit or revert together. Passing the pool on every close is safe: the handler ignores remaining accounts when the NFT account is not frozen.
Conditional client break. An older client can successfully open a position after the upgrade because the V2 open account layouts are unchanged. If that position is frozen, the same client may later fail to close it because its ClosePosition builder omits the pool remaining account. Update the close builder before allowing users to open positions in affected pools.

Compatibility matrix

No new CLMM custom error variants or numeric shifts are introduced. SPL Token’s native AccountFrozen error rejects transfer or owner change attempts.

Pages updated

  • products/clmm/overview — release summary and restricted transferability caveat.
  • products/clmm/ticks-and-positions — authority model, trigger, owner capabilities, and close migration warning.
  • products/clmm/accounts — position NFT mint and lifecycle behavior.
  • products/clmm/instructions — open postconditions and frozen ClosePosition remaining-account path.
  • products/clmm/code-demos — direct Anchor close example and pinned-SDK warning.
  • user-flows/add-remove-liquidity — user-facing restricted-position behavior.
  • user-flows/burn-and-earn — frozen positions cannot transfer into lock escrow.
  • security/oracle-and-token-risks / security/attack-vectors — issuer and transfer-risk boundaries.
  • reference/token-2022-support — distinction between pool allow-listing and position custody.
  • reference/error-codes — expanded AccountLack and NotApproved causes.
  • reference/program-addresses — restricted-issuer authority match keys.
  • reference/fee-comparison / reference/glossary — transferability exceptions.
Verified 2026-08-13 against:
  • Pre-release CLMM branch feat/position-nft-freeze at ecb157760776f83f97507fa78c6e32cfb30d92a9.
  • Commits 2e95310 (restricted-issuer NFT freezing) and ecb1577 (pool-scoped freeze authority), compared with master at 51fdba2.
  • Program sources under instructions/{open_position,open_position_v2,open_position_with_token22_nft,close_position}.rs and util/token.rs.
  • position-nft-freeze.test.ts, covering ordinary transferability, frozen transfer/owner-change rejection, and V2 plus Token-2022 thaw-before-close flows.
This verification covers the pre-release source branch, not a mainnet-beta deployment or published SDK release. Confirm the deployed program, production restricted-authority list, and SDK close builder before enabling the flow.