Search Apps Documentation Source Content File Folder Download Copy Actions Download

README.md

3.85 Kb · 183 lines

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