Position mapping entry and a PositionNFT ownership record.
Public position
Thepositions 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:
ownerwithdrawaltoken_idtoken0_idtoken1_idpooltick_lowertick_upper
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. It is immutable for that position. Collect does not accept an alternate payout recipient, so the owner cannot redirect a payout while collecting. To use a different withdrawal 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
mintcreates the public mapping row and the firstPositionNFTownership record.increase_liquidityconsumes the record and returns an updated record.decrease_liquiditydoes the same while moving principal into publictokens_owedaccounting.collectreturns an updated ownership record and token payout records.burnconsumes 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, but the stabletoken_id makes public state changes linkable. The mint compliance record gives its investigator owner the token ID, nonce, caller, signer, position owner, and withdrawal address.
Freeze behavior
A freeze is applied to the publictoken_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 aPositionNFT 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.