Search Apps Documentation Source Content File Folder Download Copy Actions Download

README.md

3.72 Kb · 177 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
 2tokenId, liquidity, amount0, amount1 := Mint(
 3    "gno.land/r/onbloc/weth",  // token0
 4    "gno.land/r/onbloc/usdc",  // token1
 5    3000,                      // fee
 6    -887220,                   // tickLower
 7    887220,                    // tickUpper
 8    "1000000",                 // amount0Desired
 9    "2000000000",              // amount1Desired
10    "950000",                  // amount0Min
11    "1900000000",              // amount1Min
12    deadline,
13    recipient,                 // mintTo
14    caller,                    // caller
15    "",                        // referrer
16)
17
18// Add liquidity
19positionId, liquidity, amount0, amount1, refund := IncreaseLiquidity(
20    tokenId,
21    "500000",
22    "1000000000",
23    "475000",
24    "950000000",
25    deadline,
26)
27
28// Collect fees
29positionId, token0Path, token1Path, fee0, fee1, poolPath := CollectFee(
30    tokenId,
31    false,  // unwrapResult
32)
33
34// Reposition to new range (requires cleared position)
35positionId, liquidity, tickLower, tickUpper, amount0, amount1 := Reposition(
36    tokenId,
37    -443610,                   // new tickLower
38    443610,                    // new tickUpper
39    "1000000",                 // amount0Desired
40    "2000000000",              // amount1Desired
41    "950000",                  // amount0Min
42    "1900000000",              // amount1Min
43    deadline,
44)

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