v1 source realm
package v1 manages liquidity positions as NFTs in GnoSwap pools.
View source
Position
NFT-based liquidity position management for concentrated liquidity.
Overview
Each liquidity position is a unique GRC721 NFT containing pool identifier, price range, liquidity amount, accumulated fees, and token balances.
Configuration
- Withdrawal Fee: 1% on collected fees
- Max Position Size: No limit
- Transfer Restrictions: Non-transferable NFTs
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 existing position.
- Maintains same price range
- Pro-rata token amounts
DecreaseLiquidity
Removes liquidity while keeping NFT.
- Two-step: decrease then collect
- Calculates owed tokens
CollectFee
Claims accumulated swap fees.
- No liquidity removal required
- 1% protocol fees applied
Reposition
Updates an existing position's price range.
- Requires position to be cleared first (zero liquidity/tokens owed)
- Reuses the same position ID and NFT
- Adds new liquidity to the updated range
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
Below range (token1 only):
amount1 = L * (sqrtUpper - sqrtLower)
amount0 = 0
Above range (token0 only):
amount0 = L * (sqrtUpper - sqrtLower) / (sqrtUpper * sqrtLower)
amount1 = 0
In range (both tokens):
amount0 = L * (sqrtUpper - sqrtCurrent) / (sqrtUpper * sqrtCurrent)
amount1 = L * (sqrtCurrent - sqrtLower)
Usage
1// Mint new position from the domain proxy into an implementation instance
2tokenId, liquidity, amount0, amount1 := positionManager.Mint(
3 0,
4 cur,
5 "gno.land/r/onbloc/weth", // token0
6 "gno.land/r/gnoswap/test_token/test_usdc", // token1
7 3000, // fee
8 -887220, // tickLower
9 887220, // tickUpper
10 "1000000", // amount0Desired
11 "2000000000", // amount1Desired
12 "950000", // amount0Min
13 "1900000000", // amount1Min
14 deadline,
15 recipient, // mintTo
16 "", // referrer
17)
18
19// Add liquidity
20positionId, liquidity, amount0, amount1, poolPath := positionManager.IncreaseLiquidity(
21 0,
22 cur,
23 tokenId,
24 "500000",
25 "1000000000",
26 "475000",
27 "950000000",
28 deadline,
29)
30
31// Collect fees
32positionId, fee0, fee1, poolPath, token0Path, token1Path := positionManager.CollectFee(
33 0,
34 cur,
35 tokenId,
36)
37
38// Reposition to new range (requires cleared position)
39positionId, liquidity, tickLower, tickUpper, amount0, amount1 := positionManager.Reposition(
40 0,
41 cur,
42 tokenId,
43 -443610, // new tickLower
44 443610, // new tickUpper
45 "1000000", // amount0Desired
46 "2000000000", // amount1Desired
47 "950000", // amount0Min
48 "1900000000", // amount1Min
49 deadline,
50)
Security
- Tick range validation prevents invalid positions
- Slippage protection on all operations
- Deadline prevents stale transactions
- Position NFTs are non-transferable
- Only owner can manage their positions
package v1 manages liquidity positions as NFTs in GnoSwap pools.
Each position is represented as a non-transferable GRC721 NFT with concentrated liquidity within a specific tick range. The package handles position lifecycle including minting, liquidity adjustments, fee collection, and repositioning.
1
1
func NewPositionV1
Action9
type AddLiquidityParams
struct 1type AddLiquidityParams struct {
2 poolKey string // poolPath of the pool which has the position
3 tickLower int32 // lower end of the tick range for the position
4 tickUpper int32 // upper end of the tick range for the position
5 amount0Desired *u256.Uint // desired amount of token0 to be minted
6 amount1Desired *u256.Uint // desired amount of token1 to be minted
7 amount0Min *u256.Uint // minimum amount of token0 to be minted
8 amount1Min *u256.Uint // minimum amount of token1 to be minted
9 caller address // address to call the function
10}type DecreaseLiquidityParams
struct1type DecreaseLiquidityParams struct {
2 positionId uint64 // positionId of the position to decrease liquidity
3 liquidity string // amount of liquidity to decrease
4 amount0Min *u256.Uint // minimum amount of token0 to be minted
5 amount1Min *u256.Uint // minimum amount of token1 to be minted
6 deadline int64 // time by which the transaction must be included to effect the change
7 caller address // address to call the function
8}type FeeGrowthInside
structFeeGrowthInside represents fee growth inside ticks
type IncreaseLiquidityParams
struct1type IncreaseLiquidityParams struct {
2 positionId uint64 // positionId of the position to increase liquidity
3 amount0Desired *u256.Uint // desired amount of token0 to be minted
4 amount1Desired *u256.Uint // desired amount of token1 to be minted
5 amount0Min *u256.Uint // minimum amount of token0 to be minted
6 amount1Min *u256.Uint // minimum amount of token1 to be minted
7 deadline int64 // time by which the transaction must be included to effect the change
8 caller address // address to call the function
9}type MintInput
structtype MintParams
struct 1type MintParams struct {
2 token0 string // token0 path for a specific pool
3 token1 string // token1 path for a specific pool
4 fee uint32 // fee for a specific pool
5 tickLower int32 // lower end of the tick range for the position
6 tickUpper int32 // upper end of the tick range for the position
7 amount0Desired *u256.Uint // desired amount of token0 to be minted
8 amount1Desired *u256.Uint // desired amount of token1 to be minted
9 amount0Min *u256.Uint // minimum amount of token0 to be minted
10 amount1Min *u256.Uint // minimum amount of token1 to be minted
11 deadline int64 // time by which the transaction must be included to effect the change
12 mintTo address // address to mint lpToken
13 caller address // address to call the function
14}type NFTAccessor
interface1type NFTAccessor interface {
2 Approve(_ int, rlm realm, approved address, tid grc721.TokenID) error
3 Mint(_ int, rlm realm, to address, tid grc721.TokenID) grc721.TokenID
4 Burn(_ int, rlm realm, tid grc721.TokenID)
5 TotalSupply() int64
6 Exists(tid grc721.TokenID) bool
7 OwnerOf(tid grc721.TokenID) (address, error)
8}type ProcessedMintInput
structtype TokenPair
struct21
- chain stdlib
- errors stdlib
- gno.land/p/gnoswap/consts package
- gno.land/p/gnoswap/deps/grc721 package
- gno.land/p/gnoswap/gnsmath package
- gno.land/p/gnoswap/rbac package
- gno.land/p/gnoswap/uint256 package
- gno.land/p/gnoswap/utils package
- gno.land/p/nt/ufmt/v0 package
- gno.land/r/gnoswap/access realm
- gno.land/r/gnoswap/common realm
- gno.land/r/gnoswap/emission realm
- gno.land/r/gnoswap/gnft realm
- gno.land/r/gnoswap/halt realm
- gno.land/r/gnoswap/pool realm
- gno.land/r/gnoswap/position realm
- gno.land/r/gnoswap/referral realm
- gno.land/r/gnoswap/staker realm
- strconv stdlib
- strings stdlib
- time stdlib