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