Skip to main content
Position state is split between a public Position mapping entry and a PositionNFT ownership record.

Public position

The positions mapping stores a Position under token_id. It contains the pool, range, liquidity, fee-growth checkpoints, and owed token amounts. This data is public because swaps, liquidity changes, and fee settlement need consensus on the same values. An observer can follow the economic lifecycle of a position identifier. The observer can see its range, active amount, principal withdrawal, fee collection, freeze effects, and removal after burn.

PositionNFT ownership record

PositionNFT is an Aleo record with these fields:
  • owner
  • withdrawal
  • token_id
  • token0_id
  • token1_id
  • pool
  • tick_lower
  • tick_upper
The owner field and record contents are encrypted for the record owner under ordinary record handling. Most position operations return a replacement with the same identifying fields. Rebalance is different. It consumes the old record, removes the old public position, and returns a record for a new token ID and range. The program relies on record ownership for authorization. It does not store an owner address in the public Position struct.

Owner and withdrawal are different roles

Mint accepts two independent private addresses: The withdrawal address is embedded in the first PositionNFT and copied into each replacement record. Rebalance also keeps it in the new position. Collect and Rebalance do not accept an alternate payout address. To use a different address, fully close the position and mint a new one. Both addresses are private inputs to mint and are absent from the public positions mapping. Mint validates freezelist non-inclusion proofs for the signer, position owner, and withdrawal address. Collect validates the current record owner and the embedded withdrawal address.

Lifecycle

  • mint creates the public mapping row and the first PositionNFT ownership record.
  • increase_liquidity consumes the record and returns an updated record.
  • rebalance_position removes the full old position and returns a new record with a new token ID.
  • decrease_liquidity returns an updated record and moves principal into public tokens_owed accounting.
  • collect returns an updated ownership record and token payout records.
  • burn consumes the record and removes the mapping row once liquidity and owed balances are zero.

Linkability

The ownership record hides owner and immutable withdrawal addresses from the public mapping. A token ID links increase, decrease, collect, and burn activity for that position. Rebalance creates a new token ID. The rebalance transaction links the removed position to its replacement, and the new MintComplianceRecord attributes the replacement.

Freeze behavior

A freeze is applied to the public token_id. If the position has liquidity, the contract removes it from the pool and settles principal plus fees into tokens_owed. The freeze then blocks increase, decrease, collect, and burn. Unfreeze removes the blocking entry. It does not restore liquidity. The holder can collect settled value and may add liquidity again.

Integration rule

Do not reconstruct a PositionNFT from public fields. A valid record includes cryptographic record metadata and must be discovered, decrypted, and tracked by the owner. After any position operation, persist the returned replacement record before discarding the spent input.