position source realm
View source
Position
NFT-based liquidity position management for concentrated liquidity.
Overview
Each liquidity position is a unique GRC721 NFT. Stored state includes the pool key, price range, liquidity, fee-growth checkpoints, tokens owed, burned marker, and operator. Current token balances are derived from the current pool price, range, and liquidity; they are not permanently stored balances.
The pool accounting key encodes only the lower/upper tick pair and is scoped by pool. NFTs with the same range in one pool share the pool-level accounting entry.
Gnoweb
The root Render("") delegates to the active implementation and shows realm identity, halt flags, stored position count, and the next position ID. Stored records include burned positions, so the count does not represent active liquidity positions.
Supported routes:
"": the root summary. It reads only aggregate position-store metadata.id/<id>: one position record, selected by a single keyed lookup. The<id>must be an unsigned decimaluint64; malformed, overflowing, missing, and extra-segment paths return404.
For example, /r/gnoswap/position:id/1 shows position 1. Detail pages show
the ID, burn status, NFT owner when available, token realm links, fee tier, tick
range, liquidity, and stored fee accounting.
The composite pool key is inline code; each token reference links to its defining
realm rather than a .SYMBOL URL. Rendering does not enumerate positions or
recompute claimable fees and current token balances. Burned records remain
addressable even when their NFT owner is unavailable.
Configuration
- Withdrawal Fee: 1% by default on fee-bearing swap-fee collection
- Max Position Size: No separate position-level cap; pool tick limits apply
- Transfers: Unstaked NFTs follow GRC721 owner/approval/operator rules; staked NFTs are locked to staker-mediated transfers
Core Functions
Mint
Creates new position NFT with initial liquidity.
- Validates tick range alignment
- Calculates optimal token ratio
- Returns actual amounts used
IncreaseLiquidity
Adds liquidity to an existing position.
- Maintains the existing price range
- Uses the current-price token ratio
- Can clear a burned marker when the position is used again
DecreaseLiquidity
Removes liquidity while keeping the NFT.
- One atomic public operation: internally collects swap fees, burns liquidity,
then collects principal through the pool's fee-free
Collectpath - Returns fee amounts net of the withdrawal fee and collected principal
- Amount-minimum checks apply to the principal actually collected
CollectFee
Claims accumulated swap fees without removing liquidity.
- No liquidity removal required
- Returns net collected amounts plus the raw pre-withdrawal-fee amounts
- The configured withdrawal fee applies only to this fee-bearing path
Reposition
Updates an existing position's price range.
- Requires the position to be clear first (zero liquidity and tokens owed)
- Reuses the same position ID and NFT
- Adds new liquidity to the updated range and clears the burned marker
Technical Details
Tick Alignment
Ticks must align with pool's tick spacing:
0.01% fee: every 1 tick
0.05% fee: every 10 ticks
0.3% fee: every 60 ticks
1% fee: every 200 ticks
Optimal Range Width
Stable Pairs (USDC/USDT):
- Narrow: ±0.05% (max efficiency)
- Medium: ±0.1% (balanced)
- Wide: ±0.5% (safety)
Correlated Pairs (WETH/stETH):
- Narrow: ±0.5%
- Medium: ±1%
- Wide: ±2%
Volatile Pairs (WETH/USDC):
- Narrow: ±5%
- Medium: ±10%
- Wide: ±25%
Capital Efficiency
Concentration factor vs infinite range:
Range ±0.1% → 2000x efficient
Range ±1% → 200x efficient
Range ±10% → 20x efficient
Range ±50% → 4x efficient
Token Calculations
For liquidity L and square-root prices sqrtLower, sqrtCurrent, and
sqrtUpper:
Below range (current < lower, token0 only):
amount0 = L * (sqrtUpper - sqrtLower) / (sqrtUpper * sqrtLower)
amount1 = 0
In range (lower <= current < upper, both tokens):
amount0 = L * (sqrtUpper - sqrtCurrent) / (sqrtUpper * sqrtCurrent)
amount1 = L * (sqrtCurrent - sqrtLower)
Above range (current >= upper, token1 only):
amount0 = 0
amount1 = L * (sqrtUpper - sqrtLower)
Approval and Transfer Requirements
Mint, IncreaseLiquidity, and Reposition pull token0 and token1 from the
caller inside the pool realm, so the approved spender is the pool realm
address, not the position realm.
- Approve the pool realm for both token contracts before calling a liquidity-adding function.
- Approving the position realm alone is not sufficient; the position realm never holds or pulls the pair tokens itself.
- Approve at least
amount0Desired/amount1Desired. Any desired amount the pool does not consume stays with the caller. DecreaseLiquidityandCollectFeepay out to the caller and require no approval.
1// Approve the pool realm for both pair tokens before minting
2poolAddress := access.MustGetAddress(prabc.ROLE_POOL.String())
3weth.Approve(cross(cur), poolAddress, 1000000)
4usdc.Approve(cross(cur), poolAddress, 2000000000)
Usage
These snippets call the public domain proxy from a realm function with a current cur token.
Import the proxy package and qualify its function names in integrating code.
1// Mint new position
2tokenId, liquidity, amount0, amount1 := Mint(
3 cross(cur),
4 "gno.land/r/gnoland/wugnot.wugnot", // token0
5 "gno.land/r/gnoswap/gns.GNS", // token1
6 3000, // fee
7 -887220, // tickLower
8 887220, // tickUpper
9 "1000000", // amount0Desired
10 "2000000000", // amount1Desired
11 "950000", // amount0Min
12 "1900000000", // amount1Min
13 deadline,
14 recipient, // mintTo
15 "", // referrer
16)
17
18// Add liquidity
19positionId, liquidity, amount0, amount1, poolPath := IncreaseLiquidity(
20 cross(cur),
21 tokenId,
22 "500000",
23 "1000000000",
24 "475000",
25 "950000000",
26 deadline,
27)
28
29// Collect fees
30positionId, collected0, collected1, poolPath, rawAmount0, rawAmount1 := CollectFee(
31 cross(cur),
32 tokenId,
33)
34
35// Reposition to new range (requires cleared position)
36positionId, liquidity, tickLower, tickUpper, amount0, amount1 := Reposition(
37 cross(cur),
38 tokenId,
39 -443610, // new tickLower
40 443610, // new tickUpper
41 "1000000", // amount0Desired
42 "2000000000", // amount1Desired
43 "950000", // amount0Min
44 "1900000000", // amount1Min
45 deadline,
46)
Lifecycle
A full decrease that leaves zero liquidity and zero tokens owed sets the
burned marker but does not destroy the NFT. IncreaseLiquidity and
Reposition clear the marker when the position is used again; the marker does
not by itself block an increase.
Security
- Tick range validation prevents invalid positions
- Slippage protection applies to liquidity-changing operations; fee collection has no amount-minimum parameter
- Deadlines prevent stale liquidity-changing transactions
- Unstaked NFTs follow standard GRC721 transfer authorization; staked NFTs can move only through staker-mediated flows
- Liquidity changes and repositioning require the owner; fee collection also permits the position's approved operator where applicable
2
31
func CollectFee
crossing ActionCollectFee collects accumulated fees from a position.
Parameters:
- cur: current realm context; callers use cross(cur) when crossing into this realm
- positionId: position NFT token ID whose fees are collected
Returns:
- positionId: position NFT token ID whose fees were collected
- tokensCollected0: token0 fees paid out to the caller, net of the withdrawal fee
- tokensCollected1: token1 fees paid out to the caller, net of the withdrawal fee
- poolKey: canonical pool key for the position
- totalAmount0: token0 fees collected before the withdrawal fee
- totalAmount1: token1 fees collected before the withdrawal fee
Halt check: reverts while the Withdraw halt scope is active.
func DecreaseLiquidity
crossing ActionDecreaseLiquidity removes liquidity from a position.
Parameters:
- cur: current realm context; callers use cross(cur) when crossing into this realm
- positionId: position NFT token ID to decrease
- liquidityStr: liquidity amount to remove, represented as a decimal string
- amount0MinStr: minimum acceptable token0 amount for slippage protection
- amount1MinStr: minimum acceptable token1 amount for slippage protection
- deadline: transaction expiration timestamp
The accrued swap fees are collected first, so the returned fee amounts are net of the withdrawal fee while the returned principal is not subject to it.
Returns:
- positionId: position NFT token ID that had liquidity removed
- liquidity: removed liquidity amount, represented as a decimal string
- fee0: token0 fees collected, net of the withdrawal fee
- fee1: token1 fees collected, net of the withdrawal fee
- amount0: principal amount of token0 returned to the caller
- amount1: principal amount of token1 returned to the caller
- poolKey: canonical pool key for the position
Halt check: reverts while the Withdraw halt scope is active.
func GetImplementationPackagePath
ActionGetImplementationPackagePath returns the package path of the currently active implementation.
Returns:
- packagePath: package path of the active implementation
func GetPositionFeeGrowthInside0LastX128
ActionGetPositionFeeGrowthInside0LastX128 returns the last fee-growth checkpoint inside the position's range for token0.
Parameters:
- positionId: position NFT token ID whose token0 fee-growth checkpoint is queried
Returns:
- feeGrowthInside0LastX128: token0 fee-growth checkpoint, represented as a decimal string
- err: non-nil when positionId cannot be resolved
func GetPositionFeeGrowthInside1LastX128
ActionGetPositionFeeGrowthInside1LastX128 returns the last fee-growth checkpoint inside the position's range for token1.
Parameters:
- positionId: position NFT token ID whose token1 fee-growth checkpoint is queried
Returns:
- feeGrowthInside1LastX128: token1 fee-growth checkpoint, represented as a decimal string
- err: non-nil when positionId cannot be resolved
func GetPositionFeeGrowthInsideLastX128
ActionGetPositionFeeGrowthInsideLastX128 returns the last fee-growth checkpoints inside the position's range for both tokens.
Parameters:
- positionId: position NFT token ID whose fee-growth checkpoints are queried
Returns:
- feeGrowthInside0LastX128: token0 fee-growth checkpoint, represented as a decimal string
- feeGrowthInside1LastX128: token1 fee-growth checkpoint, represented as a decimal string
- err: non-nil when positionId cannot be resolved
func GetPositionLiquidity
ActionGetPositionLiquidity returns the stored liquidity amount of a position.
Parameters:
- positionId: position NFT token ID whose liquidity is queried
Returns:
- liquidity: position liquidity, represented as a decimal string
- err: non-nil when positionId cannot be resolved
func GetPositionPoolKey
ActionGetPositionPoolKey returns the pool key associated with a position.
Parameters:
- positionId: position NFT token ID whose pool association is queried
Returns:
- poolKey: canonical pool key used by the position
- err: non-nil when positionId cannot be resolved
func GetPositionTickLower
ActionGetPositionTickLower returns the lower tick boundary of a position.
Parameters:
- positionId: position NFT token ID whose lower tick is queried
Returns:
- tickLower: lower tick boundary of the position's price range
- err: non-nil when positionId cannot be resolved
func GetPositionTickUpper
ActionGetPositionTickUpper returns the upper tick boundary of a position.
Parameters:
- positionId: position NFT token ID whose upper tick is queried
Returns:
- tickUpper: upper tick boundary of the position's price range
- err: non-nil when positionId cannot be resolved
func GetPositionTicks
ActionGetPositionTicks returns the lower and upper tick boundaries of a position.
Parameters:
- positionId: position NFT token ID whose tick range is queried
Returns:
- tickLower: lower tick boundary of the position's price range
- tickUpper: upper tick boundary of the position's price range
- err: non-nil when positionId cannot be resolved
func GetPositionToken0Balance
ActionGetPositionToken0Balance returns the token0 balance associated with a position.
Parameters:
- positionId: position NFT token ID
Returns:
- balance: token0 balance
- err: non-nil when positionId cannot be resolved
func GetPositionToken1Balance
ActionGetPositionToken1Balance returns the token1 balance associated with a position.
Parameters:
- positionId: position NFT token ID
Returns:
- balance: token1 balance
- err: non-nil when positionId cannot be resolved
func GetPositionTokenBalances
ActionGetPositionTokenBalances calculates the current token0/token1 balances for a position from its liquidity, tick range, and pool price.
These are derived balances, not permanently stored token amounts.
Parameters:
- positionId: position NFT token ID
Returns:
- balance0: current token0 balance
- balance1: current token1 balance
- err: non-nil when positionId cannot be resolved
func GetPositionTokensOwed
ActionGetPositionTokensOwed returns the token0 and token1 amounts accrued and owed to a position.
Parameters:
- positionId: position NFT token ID whose accrued token debt is queried
Returns:
- tokensOwed0: token0 amount currently owed to the position
- tokensOwed1: token1 amount currently owed to the position
- err: non-nil when positionId cannot be resolved
func GetPositionTokensOwed0
ActionGetPositionTokensOwed0 returns the token0 amount accrued and owed to a position.
Parameters:
- positionId: position NFT token ID whose token0 debt is queried
Returns:
- tokensOwed0: token0 amount currently owed to the position
- err: non-nil when positionId cannot be resolved
func GetPositionTokensOwed1
ActionGetPositionTokensOwed1 returns the token1 amount accrued and owed to a position.
Parameters:
- positionId: position NFT token ID whose token1 debt is queried
Returns:
- tokensOwed1: token1 amount currently owed to the position
- err: non-nil when positionId cannot be resolved
func GetPositions
ActionGetPositions returns a read-only view of all positions.
Returns:
- positions: read-only tree keyed by decimal position ID; callers paginate with IterateByOffset
func GetUnclaimedFee
ActionGetUnclaimedFee returns the unclaimed fees for both tokens of a position as decimal strings.
Parameters:
- positionId: position NFT token ID whose unclaimed fees are queried
Returns:
- fee0: unclaimed token0 fee amount, represented as a decimal string
- fee1: unclaimed token1 fee amount, represented as a decimal string
- err: non-nil when positionId or the associated pool fee-growth data cannot be resolved
func IncreaseLiquidity
crossing ActionIncreaseLiquidity adds liquidity to an existing position.
Parameters:
- cur: current realm context; callers use cross(cur) when crossing into this realm
- positionId: position NFT token ID to increase
- amount0DesiredStr: desired token0 amount, represented as a decimal string
- amount1DesiredStr: desired token1 amount, represented as a decimal string
- amount0MinStr: minimum acceptable token0 amount for slippage protection
- amount1MinStr: minimum acceptable token1 amount for slippage protection
- deadline: transaction expiration timestamp
Returns:
- positionId: position NFT token ID that received the liquidity
- liquidity: liquidity amount added to the position (the delta), represented as a decimal string
- amount0: actual token0 amount added, represented as a decimal string
- amount1: actual token1 amount added, represented as a decimal string
- poolKey: canonical pool key for the position
Halt check: reverts while the Position halt scope is active.
func IsBurned
ActionIsBurned reports whether the position's empty-position marker is set.
Parameters:
- positionId: position NFT token ID
Returns:
- burned: whether the position's empty-position marker is set
- err: non-nil when positionId cannot be resolved
func IsInRange
ActionIsInRange reports whether a position's ticks contain the current pool tick.
Parameters:
- positionId: position NFT token ID
Returns:
- inRange: whether the position is currently in range
- err: non-nil when positionId cannot be resolved or the associated pool tick cannot be read
func Mint
crossing ActionMint creates a new liquidity position NFT.
Parameters:
- cur: current realm context; callers use cross(cur) when crossing into this realm
- token0: path of the first token in the pool
- token1: path of the second token in the pool
- fee: pool fee tier used to identify the pool
- tickLower: lower tick boundary of the position's price range
- tickUpper: upper tick boundary of the position's price range
- amount0Desired: desired amount of token0 to provide
- amount1Desired: desired amount of token1 to provide
- amount0Min: minimum acceptable amount of token0 after price/slippage calculation
- amount1Min: minimum acceptable amount of token1 after price/slippage calculation
- deadline: transaction expiration timestamp
- mintTo: recipient address of the position NFT
- referrer: referrer identifier used for reward tracking
Returns:
- positionId: newly minted position NFT token ID
- liquidity: liquidity minted into the position, represented as a decimal string
- amount0: actual amount of token0 added to the position, represented as a decimal string
- amount1: actual amount of token1 added to the position, represented as a decimal string
Halt check: reverts while the Position halt scope is active.
func NewPositionsTree
ActionNewPositionsTree allocates an empty BP-tree for position entries under the position realm context.
Returns:
- positionsTree: empty position BP-tree allocated with fanout 16
func RegisterInitializer
crossing Action1func RegisterInitializer(cur realm, initializer func(_ int, rlm realm, positionStore IPositionStore) IPosition)RegisterInitializer registers a new position implementation version. This function is called by each version (v1, v2, etc.) during initialization to register their implementation with the proxy system.
The initializer function creates a new instance of the implementation using the provided positionStore interface.
Parameters:
- cur: current realm context; callers use cross(cur) when crossing into this realm
- initializer: callback that receives the implementation realm context and position store, then returns that version's IPosition implementation
Security: Only contracts within the domain path can register initializers. Each package path can only register once to prevent duplicate registrations.
func Render
Render delegates web rendering to the active implementation.
func Reposition
crossing ActionReposition changes the tick range of a position.
Parameters:
- cur: current realm context; callers use cross(cur) when crossing into this realm
- positionId: position NFT token ID to reposition
- tickLower: new lower tick boundary of the position's price range
- tickUpper: new upper tick boundary of the position's price range
- amount0DesiredStr: desired token0 amount for the new range, represented as a decimal string
- amount1DesiredStr: desired token1 amount for the new range, represented as a decimal string
- amount0MinStr: minimum acceptable token0 amount for slippage protection
- amount1MinStr: minimum acceptable token1 amount for slippage protection
- deadline: transaction expiration timestamp
Returns:
- positionId: position NFT token ID that was repositioned
- liquidity: new liquidity amount, represented as a decimal string
- tickLower: new lower tick boundary
- tickUpper: new upper tick boundary
- amount0: actual token0 amount added to the new range, represented as a decimal string
- amount1: actual token1 amount added to the new range, represented as a decimal string
Halt check: reverts while the Position halt scope is active.
func SetPositionOperator
crossing ActionSetPositionOperator sets an operator for a position.
Parameters:
- cur: current realm context; callers use cross(cur) when crossing into this realm
- positionId: position NFT token ID whose operator is changed
- operator: operator address to approve; the zero address removes the operator
func UpgradeImpl
crossing ActionUpgradeImpl switches the active position implementation to a different version. This function allows seamless upgrades from one version to another without data migration or downtime.
Parameters:
- cur: current realm context; callers use cross(cur) when crossing into this realm
- packagePath: fully qualified package path of a previously registered replacement implementation
Security: Only admin or governance can perform upgrades. The new implementation must have been previously registered via RegisterInitializer.
func NewPositionStore
ActionNewPositionStore creates a position store backed by the provided KV store. The upgrade system uses it to construct storage instances for each implementation.
Parameters:
- kvStore: Domain-owned KV store shared by position implementations.
Returns:
- IPositionStore: Position storage wrapper backed by the supplied store.
func NewPosition
ActionNewPosition constructs a position from its persisted pool, range, liquidity, fee-growth, owed-token, marker, and operator values.
Parameters:
- poolKey: pool key encoding the position's token pair and fee tier
- tickLower: lower tick boundary of the position's range
- tickUpper: upper tick boundary of the position's range
- liquidity: decimal string representing the position's liquidity
- feeGrowthInside0LastX128: decimal-encoded Q128 token0 fee-growth checkpoint
- feeGrowthInside1LastX128: decimal-encoded Q128 token1 fee-growth checkpoint
- tokensOwed0: accrued token0 amount awaiting collection, in token units
- tokensOwed1: accrued token1 amount awaiting collection, in token units
- burned: empty-position marker to store
- operator: approved operator address; the empty address means no operator
Returns:
- position: pointer to a position initialized with all supplied values
6
type IPosition
interfacetype IPositionGetter
interface 1type IPositionGetter interface {
2 // GetPositions returns a read-only view of all positions.
3 //
4 // Returns:
5 // - positions: read-only tree keyed by decimal position ID
6 GetPositions() *rotree.ReadOnlyTree
7 // IsBurned reports whether a position's empty-position marker is set.
8 //
9 // Parameters:
10 // - positionId: position NFT token ID whose burned marker is queried
11 //
12 // Returns:
13 // - burned: true when the position's empty-position marker is set
14 // - err: non-nil when positionId cannot be resolved
15 IsBurned(positionId uint64) (bool, error)
16 // IsInRange reports whether a position's tick range contains the current pool tick.
17 //
18 // Parameters:
19 // - positionId: position NFT token ID whose range is checked
20 //
21 // Returns:
22 // - inRange: true when the current pool tick lies within the position's tick range
23 // - err: non-nil when positionId cannot be resolved or the associated pool tick cannot be read
24 IsInRange(positionId uint64) (bool, error)
25 // GetPositionOperator returns the approved operator address for a position.
26 //
27 // Parameters:
28 // - positionId: position NFT token ID whose operator is queried
29 //
30 // Returns:
31 // - operator: approved operator address; the zero address means no operator is set
32 // - err: non-nil when positionId cannot be resolved
33 GetPositionOperator(positionId uint64) (address, error)
34 // GetPositionPoolKey returns the pool key associated with a position.
35 //
36 // Parameters:
37 // - positionId: position NFT token ID whose pool is queried
38 //
39 // Returns:
40 // - poolKey: canonical pool key used by the position
41 // - err: non-nil when positionId cannot be resolved
42 GetPositionPoolKey(positionId uint64) (string, error)
43 // GetPositionTickLower returns the lower tick boundary of a position.
44 //
45 // Parameters:
46 // - positionId: position NFT token ID whose lower tick is queried
47 //
48 // Returns:
49 // - tickLower: lower tick boundary of the position's price range
50 // - err: non-nil when positionId cannot be resolved
51 GetPositionTickLower(positionId uint64) (int32, error)
52 // GetPositionTickUpper returns the upper tick boundary of a position.
53 //
54 // Parameters:
55 // - positionId: position NFT token ID whose upper tick is queried
56 //
57 // Returns:
58 // - tickUpper: upper tick boundary of the position's price range
59 // - err: non-nil when positionId cannot be resolved
60 GetPositionTickUpper(positionId uint64) (int32, error)
61 // GetPositionLiquidity returns the stored liquidity amount of a position.
62 //
63 // Parameters:
64 // - positionId: position NFT token ID whose liquidity is queried
65 //
66 // Returns:
67 // - liquidity: position liquidity represented as a decimal string
68 // - err: non-nil when positionId cannot be resolved
69 GetPositionLiquidity(positionId uint64) (string, error)
70 // GetPositionTokenBalances returns current token0 and token1 balances derived for a position.
71 //
72 // Parameters:
73 // - positionId: position NFT token ID whose balances are queried
74 //
75 // Returns:
76 // - balance0: current token0 balance derived from liquidity, ticks, and pool price
77 // - balance1: current token1 balance derived from liquidity, ticks, and pool price
78 // - err: non-nil when positionId cannot be resolved
79 GetPositionTokenBalances(positionId uint64) (int64, int64, error)
80 // GetPositionFeeGrowthInside0LastX128 returns the last fee-growth checkpoint inside a position's range for token0.
81 //
82 // Parameters:
83 // - positionId: position NFT token ID whose token0 fee-growth checkpoint is queried
84 //
85 // Returns:
86 // - feeGrowthInside0LastX128: token0 fee-growth checkpoint as a decimal string
87 // - err: non-nil when positionId cannot be resolved
88 GetPositionFeeGrowthInside0LastX128(positionId uint64) (string, error)
89 // GetPositionFeeGrowthInside1LastX128 returns the last fee-growth checkpoint inside a position's range for token1.
90 //
91 // Parameters:
92 // - positionId: position NFT token ID whose token1 fee-growth checkpoint is queried
93 //
94 // Returns:
95 // - feeGrowthInside1LastX128: token1 fee-growth checkpoint as a decimal string
96 // - err: non-nil when positionId cannot be resolved
97 GetPositionFeeGrowthInside1LastX128(positionId uint64) (string, error)
98 // GetPositionFeeGrowthInsideLastX128 returns the last fee-growth checkpoints inside a position's range for both tokens.
99 //
100 // Parameters:
101 // - positionId: position NFT token ID whose fee-growth checkpoints are queried
102 //
103 // Returns:
104 // - feeGrowthInside0LastX128: token0 fee-growth checkpoint as a decimal string
105 // - feeGrowthInside1LastX128: token1 fee-growth checkpoint as a decimal string
106 // - err: non-nil when positionId cannot be resolved
107 GetPositionFeeGrowthInsideLastX128(positionId uint64) (string, string, error)
108 // GetPositionTicks returns the lower and upper tick boundaries of a position.
109 //
110 // Parameters:
111 // - positionId: position NFT token ID whose tick range is queried
112 //
113 // Returns:
114 // - tickLower: lower tick boundary of the position's price range
115 // - tickUpper: upper tick boundary of the position's price range
116 // - err: non-nil when positionId cannot be resolved
117 GetPositionTicks(positionId uint64) (int32, int32, error)
118 // GetPositionTokensOwed0 returns the token0 amount accrued and owed to a position.
119 //
120 // Parameters:
121 // - positionId: position NFT token ID whose token0 debt is queried
122 //
123 // Returns:
124 // - tokensOwed0: token0 amount currently owed to the position
125 // - err: non-nil when positionId cannot be resolved
126 GetPositionTokensOwed0(positionId uint64) (int64, error)
127 // GetPositionTokensOwed1 returns the token1 amount accrued and owed to a position.
128 //
129 // Parameters:
130 // - positionId: position NFT token ID whose token1 debt is queried
131 //
132 // Returns:
133 // - tokensOwed1: token1 amount currently owed to the position
134 // - err: non-nil when positionId cannot be resolved
135 GetPositionTokensOwed1(positionId uint64) (int64, error)
136 // GetPositionTokensOwed returns token0 and token1 amounts accrued and owed to a position.
137 //
138 // Parameters:
139 // - positionId: position NFT token ID whose accrued token debt is queried
140 //
141 // Returns:
142 // - tokensOwed0: token0 amount currently owed to the position
143 // - tokensOwed1: token1 amount currently owed to the position
144 // - err: non-nil when positionId cannot be resolved
145 GetPositionTokensOwed(positionId uint64) (int64, int64, error)
146 // GetUnclaimedFee returns unclaimed fees for both tokens of a position.
147 //
148 // Parameters:
149 // - positionId: position NFT token ID whose unclaimed fees are queried
150 //
151 // Returns:
152 // - fee0: unclaimed token0 fee amount as a uint256 value
153 // - fee1: unclaimed token1 fee amount as a uint256 value
154 // - err: non-nil when positionId or the associated pool fee-growth data cannot be resolved
155 GetUnclaimedFee(positionId uint64) (*u256.Uint, *u256.Uint, error)
156 // GetPositionOwner returns the owner address of a position NFT.
157 //
158 // Parameters:
159 // - positionId: position NFT token ID whose owner is queried
160 //
161 // Returns:
162 // - owner: address that owns the position NFT
163 // - err: non-nil when the NFT owner lookup fails
164 GetPositionOwner(positionId uint64) (address, error)
165}type IPositionManager
interface 1type IPositionManager interface {
2 // Mint creates a new liquidity position NFT.
3 //
4 // Parameters:
5 // - _: leading integer discriminator; callers pass 0
6 // - rlm: propagated realm context; implementations validate it as current before changing state
7 // - token0: path of the first token in the pool
8 // - token1: path of the second token in the pool
9 // - fee: pool fee tier used to identify the pool
10 // - tickLower: lower tick boundary of the position's price range
11 // - tickUpper: upper tick boundary of the position's price range
12 // - amount0Desired: desired amount of token0 to provide
13 // - amount1Desired: desired amount of token1 to provide
14 // - amount0Min: minimum acceptable token0 amount for slippage protection
15 // - amount1Min: minimum acceptable token1 amount for slippage protection
16 // - deadline: transaction expiration timestamp
17 // - mintTo: recipient address of the position NFT
18 // - referrer: referrer identifier used for reward tracking
19 //
20 // Returns:
21 // - positionId: newly minted position NFT token ID
22 // - liquidity: liquidity minted into the position, represented as a decimal string
23 // - amount0: actual amount of token0 added, represented as a decimal string
24 // - amount1: actual amount of token1 added, represented as a decimal string
25 Mint(
26 _ int,
27 rlm realm,
28 token0 string,
29 token1 string,
30 fee uint32,
31 tickLower int32,
32 tickUpper int32,
33 amount0Desired string,
34 amount1Desired string,
35 amount0Min string,
36 amount1Min string,
37 deadline int64,
38 mintTo address,
39 referrer string,
40 ) (uint64, string, string, string)
41
42 // IncreaseLiquidity adds liquidity to an existing position.
43 //
44 // Parameters:
45 // - _: leading integer discriminator; callers pass 0
46 // - rlm: propagated realm context; implementations validate it as current before changing state
47 // - positionId: position NFT token ID to increase
48 // - amount0DesiredStr: desired token0 amount, represented as a decimal string
49 // - amount1DesiredStr: desired token1 amount, represented as a decimal string
50 // - amount0MinStr: minimum acceptable token0 amount for slippage protection
51 // - amount1MinStr: minimum acceptable token1 amount for slippage protection
52 // - deadline: transaction expiration timestamp
53 //
54 // Returns:
55 // - positionId: position NFT token ID that received the liquidity
56 // - liquidity: liquidity amount added to the position (the delta), represented as a decimal string
57 // - amount0: actual token0 amount added, represented as a decimal string
58 // - amount1: actual token1 amount added, represented as a decimal string
59 // - poolKey: canonical pool key for the position
60 IncreaseLiquidity(
61 _ int,
62 rlm realm,
63 positionId uint64,
64 amount0DesiredStr string,
65 amount1DesiredStr string,
66 amount0MinStr string,
67 amount1MinStr string,
68 deadline int64,
69 ) (uint64, string, string, string, string)
70
71 // DecreaseLiquidity removes liquidity from a position.
72 //
73 // Parameters:
74 // - _: leading integer discriminator; callers pass 0
75 // - rlm: propagated realm context; implementations validate it as current before changing state
76 // - positionId: position NFT token ID to decrease
77 // - liquidityStr: liquidity amount to remove, represented as a decimal string
78 // - amount0MinStr: minimum acceptable token0 amount for slippage protection
79 // - amount1MinStr: minimum acceptable token1 amount for slippage protection
80 // - deadline: transaction expiration timestamp
81 //
82 // Returns:
83 // - positionId: position NFT token ID that had liquidity removed
84 // - liquidity: removed liquidity amount, represented as a decimal string
85 // - fee0: token0 fees collected, net of the withdrawal fee
86 // - fee1: token1 fees collected, net of the withdrawal fee
87 // - amount0: principal amount of token0 returned to the caller
88 // - amount1: principal amount of token1 returned to the caller
89 // - poolKey: canonical pool key for the position
90 DecreaseLiquidity(
91 _ int,
92 rlm realm,
93 positionId uint64,
94 liquidityStr string,
95 amount0MinStr string,
96 amount1MinStr string,
97 deadline int64,
98 ) (uint64, string, string, string, string, string, string)
99
100 // Reposition changes the tick range of an existing position.
101 //
102 // Parameters:
103 // - _: leading integer discriminator; callers pass 0
104 // - rlm: propagated realm context; implementations validate it as current before changing state
105 // - positionId: position NFT token ID to reposition
106 // - tickLower: new lower tick boundary of the position's price range
107 // - tickUpper: new upper tick boundary of the position's price range
108 // - amount0DesiredStr: desired token0 amount for the new range, represented as a decimal string
109 // - amount1DesiredStr: desired token1 amount for the new range, represented as a decimal string
110 // - amount0MinStr: minimum acceptable token0 amount for slippage protection
111 // - amount1MinStr: minimum acceptable token1 amount for slippage protection
112 // - deadline: transaction expiration timestamp
113 //
114 // Returns:
115 // - positionId: position NFT token ID that was repositioned
116 // - liquidity: new liquidity amount, represented as a decimal string
117 // - tickLower: lower tick boundary applied to the position
118 // - tickUpper: upper tick boundary applied to the position
119 // - amount0: actual token0 amount added to the new range, represented as a decimal string
120 // - amount1: actual token1 amount added to the new range, represented as a decimal string
121 Reposition(
122 _ int,
123 rlm realm,
124 positionId uint64,
125 tickLower int32,
126 tickUpper int32,
127 amount0DesiredStr string,
128 amount1DesiredStr string,
129 amount0MinStr string,
130 amount1MinStr string,
131 deadline int64,
132 ) (uint64, string, int32, int32, string, string)
133
134 // CollectFee collects accumulated fees from a position.
135 //
136 // Parameters:
137 // - _: leading integer discriminator; callers pass 0
138 // - rlm: propagated realm context; implementations validate it as current before changing state
139 // - positionId: position NFT token ID whose fees are collected
140 //
141 // Returns:
142 // - positionId: position NFT token ID whose fees were collected
143 // - tokensCollected0: token0 fees paid out to the caller, net of the withdrawal fee
144 // - tokensCollected1: token1 fees paid out to the caller, net of the withdrawal fee
145 // - poolKey: canonical pool key for the position
146 // - totalAmount0: token0 fees collected before the withdrawal fee
147 // - totalAmount1: token1 fees collected before the withdrawal fee
148 CollectFee(
149 _ int,
150 rlm realm,
151 positionId uint64,
152 ) (uint64, string, string, string, string, string)
153
154 // SetPositionOperator sets or removes the approved operator for a position.
155 //
156 // Parameters:
157 // - _: leading integer discriminator; callers pass 0
158 // - rlm: propagated realm context; implementations validate it as current before changing state
159 // - positionId: position NFT token ID whose operator is changed
160 // - operator: operator address to approve; the zero address removes the operator
161 SetPositionOperator(
162 _ int,
163 rlm realm,
164 positionId uint64,
165 operator address,
166 )
167}type IPositionStore
interface 1type IPositionStore interface {
2 // HasPositionsStoreKey reports whether the positions tree exists in storage.
3 //
4 // Returns:
5 // - exists: true when the positions storage key is present
6 HasPositionsStoreKey() bool
7 // GetPositions returns the mutable positions tree.
8 //
9 // Returns:
10 // - positions: positions tree keyed by decimal position ID
11 GetPositions() *bptree.BPTree
12 // SetPositions stores the complete positions tree.
13 //
14 // Parameters:
15 // - _: leading integer discriminator; callers pass 0
16 // - rlm: propagated realm context; implementations require it to be current for storage writes
17 // - positions: positions tree to persist, keyed by decimal position ID
18 //
19 // Returns:
20 // - err: nil when the tree is stored; non-nil when the realm is spoofed or the write fails
21 SetPositions(_ int, rlm realm, positions *bptree.BPTree) error
22
23 // HasPositionNextIDStoreKey reports whether the next-position-ID value exists.
24 //
25 // Returns:
26 // - exists: true when the next-position-ID storage key is present
27 HasPositionNextIDStoreKey() bool
28 // GetPositionNextID returns the next position NFT ID to allocate.
29 //
30 // Returns:
31 // - nextID: next position ID stored for minting
32 GetPositionNextID() uint64
33 // SetPositionNextID stores the next position NFT ID.
34 //
35 // Parameters:
36 // - _: leading integer discriminator; callers pass 0
37 // - rlm: propagated realm context; implementations require it to be current for storage writes
38 // - nextID: next position ID to persist for the next mint
39 //
40 // Returns:
41 // - err: nil when nextID is stored; non-nil when the realm is spoofed or the write fails
42 SetPositionNextID(_ int, rlm realm, nextID uint64) error
43
44 // HasPosition reports whether an NFT ID is present in the positions tree.
45 //
46 // Parameters:
47 // - positionId: position NFT token ID to look up
48 //
49 // Returns:
50 // - exists: true when positionId has a stored position
51 HasPosition(positionId uint64) bool
52 // GetPosition loads a position by NFT ID.
53 //
54 // Parameters:
55 // - positionId: position NFT token ID to look up
56 //
57 // Returns:
58 // - position: stored position value, or the zero Position when absent
59 // - exists: true when positionId is present; false when no position is stored
60 GetPosition(positionId uint64) (Position, bool)
61 // SetPosition inserts or replaces a position in storage.
62 //
63 // Parameters:
64 // - _: leading integer discriminator; callers pass 0
65 // - rlm: propagated realm context; implementations require it to be current for storage writes
66 // - positionId: position NFT token ID used as the storage key
67 // - position: complete position value to persist
68 //
69 // Returns:
70 // - err: nil when the position tree is updated; non-nil when the realm is spoofed, storage is missing, or the write fails
71 SetPosition(_ int, rlm realm, positionId uint64, position Position) error
72 // RemovePosition deletes a position from storage.
73 //
74 // Parameters:
75 // - _: leading integer discriminator; callers pass 0
76 // - rlm: propagated realm context; implementations require it to be current for storage writes
77 // - positionId: position NFT token ID to remove
78 //
79 // Returns:
80 // - err: nil when the position tree is updated; non-nil when the realm is spoofed, storage is missing, or the write fails
81 RemovePosition(_ int, rlm realm, positionId uint64) error
82}type Position
struct 1type Position struct {
2 operator address // address that is approved for spending this token
3 poolKey string // poolPath of the pool which this has lp token
4 tickLower int32 // the lower tick of the position, bounds are included
5 tickUpper int32 // the upper tick of the position
6 liquidity string // liquidity of the position
7
8 // fee growth of the aggregate position as of the last action on the individual position
9 feeGrowthInside0LastX128 string
10 feeGrowthInside1LastX128 string
11
12 // how many uncollected tokens are owed to the position, as of the last computation
13 tokensOwed0 int64
14 tokensOwed1 int64
15
16 burned bool // empty-position marker; the NFT itself is not burned
17}Position represents a liquidity position in a pool. Each position tracks liquidity, fee-growth checkpoints, tokens owed, and a burned marker for the position NFT. All uint256 fields are stored as decimal strings to reduce realm object overhead.
Methods on Position
func Burned
method on PositionBurned reports the position's empty-position marker.
Returns:
- burned: true when the position is marked empty after its balances clear; the position NFT itself is not burned
func FeeGrowthInside0LastX128
method on PositionFeeGrowthInside0LastX128 returns the token0 fee-growth checkpoint.
Returns:
- feeGrowthInside0LastX128: decimal-encoded Q128 fee growth inside the position's range at its last update
func FeeGrowthInside1LastX128
method on PositionFeeGrowthInside1LastX128 returns the token1 fee-growth checkpoint.
Returns:
- feeGrowthInside1LastX128: decimal-encoded Q128 fee growth inside the position's range at its last update
func IsClear
method on PositionIsClear reports whether liquidity and tokens owed are all zero; it does not describe the burned marker.
Returns:
- clear: true when stored liquidity and both token-owed counters are zero, regardless of the burned marker
func Liquidity
method on PositionLiquidity returns the position's stored liquidity amount.
Returns:
- liquidity: decimal-encoded liquidity currently held by the position
func Operator
method on PositionOperator returns the address approved to operate on the position.
Returns:
- operator: approved operator address, or the empty address when no operator is set
func PoolKey
method on PositionPoolKey returns the pool identifier associated with the position.
Returns:
- poolKey: pool key encoding the position's token pair and fee tier
func SetBurned
method on PositionSetBurned stores the position's empty-position marker.
Parameters:
- burned: marker indicating whether the position is considered empty
func SetFeeGrowthInside0LastX128
method on PositionSetFeeGrowthInside0LastX128 stores the token0 fee-growth checkpoint.
Parameters:
- feeGrowthInside0LastX128: decimal-encoded Q128 fee growth inside the position's range
func SetFeeGrowthInside1LastX128
method on PositionSetFeeGrowthInside1LastX128 stores the token1 fee-growth checkpoint.
Parameters:
- feeGrowthInside1LastX128: decimal-encoded Q128 fee growth inside the position's range
func SetLiquidity
method on PositionSetLiquidity stores the position's liquidity amount.
Parameters:
- liquidity: decimal string representing the position's liquidity
func SetOperator
method on PositionSetOperator stores the address approved to operate on the position.
Parameters:
- operator: approved operator address; the empty address removes the operator
func SetPoolKey
method on PositionSetPoolKey stores the pool identifier associated with the position.
Parameters:
- poolKey: pool key encoding the position's token pair and fee tier
func SetTickLower
method on PositionSetTickLower stores the lower tick boundary of the position's range.
Parameters:
- tickLower: lower tick boundary used for the position's range
func SetTickUpper
method on PositionSetTickUpper stores the upper tick boundary of the position's range.
Parameters:
- tickUpper: upper tick boundary used for the position's range
func SetTokensOwed0
method on PositionSetTokensOwed0 stores the amount of token0 owed to the position.
Parameters:
- tokensOwed0: accrued token0 amount awaiting collection, in token units
func SetTokensOwed1
method on PositionSetTokensOwed1 stores the amount of token1 owed to the position.
Parameters:
- tokensOwed1: accrued token1 amount awaiting collection, in token units
func TickLower
method on PositionTickLower returns the lower tick boundary of the position's range.
Returns:
- tickLower: lower tick boundary, inclusive in range checks
func TickUpper
method on PositionTickUpper returns the upper tick boundary of the position's range.
Returns:
- tickUpper: upper tick boundary, used as the exclusive end in range checks
func TokensOwed0
method on PositionTokensOwed0 returns the stored amount of token0 owed to the position.
Returns:
- tokensOwed0: accrued token0 amount awaiting collection, in token units
func TokensOwed1
method on PositionTokensOwed1 returns the stored amount of token1 owed to the position.
Returns:
- tokensOwed1: accrued token1 amount awaiting collection, in token units
type StoreKey
ident10
- errors stdlib
- gno.land/p/gnoswap/store/v1 package
- gno.land/p/gnoswap/uint256/v1 package
- gno.land/p/gnoswap/utils/v1 package
- gno.land/p/gnoswap/version_manager/v1 package
- gno.land/p/nt/bptree/rotree/v0 package
- gno.land/p/nt/bptree/v0 package
- gno.land/p/nt/ufmt/v0 package
- gno.land/r/gnoswap/access/v1 realm
- gno.land/r/gnoswap/rbac/v1 realm