$npx -y skills add agiprolabs/claude-trading-skills --skill lp-mathAMM liquidity provision mathematics including constant-product, concentrated liquidity, price impact, and LP share calculations
| 1 | # LP Math — AMM Liquidity Provision Mathematics |
| 2 | |
| 3 | Automated Market Makers (AMMs) replace traditional orderbooks with liquidity pools. Instead of matching buyers and sellers, a mathematical formula determines prices based on reserve ratios. Liquidity providers (LPs) deposit both assets into a pool and earn fees from every trade. |
| 4 | |
| 5 | Understanding the math behind AMMs is essential for: |
| 6 | - Evaluating whether providing liquidity is profitable after impermanent loss |
| 7 | - Estimating price impact before executing large trades |
| 8 | - Comparing capital efficiency across pool types (constant product vs concentrated) |
| 9 | - Calculating expected fee revenue for a given pool position |
| 10 | |
| 11 | **Related skills**: See `impermanent-loss` for IL calculations, `yield-analysis` for LP yield modeling, `liquidity-analysis` for pool depth assessment. |
| 12 | |
| 13 | --- |
| 14 | |
| 15 | ## 1. Constant Product AMM (xy = k) |
| 16 | |
| 17 | The foundational AMM model used by Raydium V4 and most Solana DEXes. |
| 18 | |
| 19 | ### Core Invariant |
| 20 | |
| 21 | ``` |
| 22 | x * y = k |
| 23 | ``` |
| 24 | |
| 25 | Where: |
| 26 | - `x` = reserve amount of token X (e.g., SOL) |
| 27 | - `y` = reserve amount of token Y (e.g., USDC) |
| 28 | - `k` = constant product (increases over time from fees) |
| 29 | |
| 30 | ### Spot Price |
| 31 | |
| 32 | ``` |
| 33 | P = x / y (price of Y in terms of X) |
| 34 | P = y / x (price of X in terms of Y) |
| 35 | ``` |
| 36 | |
| 37 | For a pool with 100 SOL and 10,000 USDC: price of SOL = 10,000 / 100 = 100 USDC. |
| 38 | |
| 39 | ### Trade Execution |
| 40 | |
| 41 | When a trader swaps Δx of token X into the pool: |
| 42 | |
| 43 | ```python |
| 44 | # Output amount (before fees) |
| 45 | delta_y = y * delta_x / (x + delta_x) |
| 46 | |
| 47 | # With fee (e.g., 0.3%) |
| 48 | delta_y_after_fee = delta_y * (1 - fee_rate) |
| 49 | |
| 50 | # New reserves |
| 51 | x_new = x + delta_x |
| 52 | y_new = y - delta_y_after_fee |
| 53 | ``` |
| 54 | |
| 55 | The key insight: larger trades get worse prices because each unit moves the ratio further. |
| 56 | |
| 57 | ### Inverse Calculation |
| 58 | |
| 59 | To get a specific output amount Δy, the required input is: |
| 60 | |
| 61 | ```python |
| 62 | delta_x = x * delta_y / (y - delta_y) |
| 63 | ``` |
| 64 | |
| 65 | ### Price After Trade |
| 66 | |
| 67 | ```python |
| 68 | price_new = y_new / x_new |
| 69 | ``` |
| 70 | |
| 71 | ### Worked Example |
| 72 | |
| 73 | Pool: 100 SOL / 10,000 USDC (k = 1,000,000), fee = 0.3% |
| 74 | |
| 75 | Buy 5 SOL worth of USDC: |
| 76 | 1. Gross output: `10,000 * 5 / (100 + 5) = 476.19 USDC` |
| 77 | 2. Fee: `476.19 * 0.003 = 1.43 USDC` |
| 78 | 3. Net output: `474.76 USDC` |
| 79 | 4. Effective price: `474.76 / 5 = 94.95 USDC/SOL` (vs spot 100) |
| 80 | 5. Price impact: `(100 - 94.95) / 100 = 5.05%` |
| 81 | 6. New reserves: 105 SOL / 9,525.24 USDC |
| 82 | 7. New k: `105 * 9,525.24 = 1,000,150.2` (k increased from fees) |
| 83 | |
| 84 | See `references/amm_formulas.md` for complete derivations. |
| 85 | |
| 86 | --- |
| 87 | |
| 88 | ## 2. Concentrated Liquidity (CLMM) |
| 89 | |
| 90 | Used by Orca Whirlpool, Raydium CLMM, and Meteora DLMM. Liquidity is only active within a chosen price range [P_lower, P_upper]. |
| 91 | |
| 92 | ### Key Concepts |
| 93 | |
| 94 | ``` |
| 95 | L = sqrt(x * y) # Liquidity within the active range |
| 96 | price_at_tick = 1.0001^tick # Tick-to-price conversion |
| 97 | ``` |
| 98 | |
| 99 | ### Capital Efficiency |
| 100 | |
| 101 | Concentrating liquidity in a narrow range provides more depth per dollar: |
| 102 | |
| 103 | ```python |
| 104 | # Capital efficiency ratio |
| 105 | efficiency = sqrt(P_upper / P_lower) / (sqrt(P_upper / P_lower) - 1) |
| 106 | |
| 107 | # Example: ±5% range around $100 SOL |
| 108 | P_lower, P_upper = 95, 105 |
| 109 | efficiency = sqrt(105/95) / (sqrt(105/95) - 1) # ≈ 20.5x |
| 110 | ``` |
| 111 | |
| 112 | A ±5% range is ~20x more capital-efficient than full-range, but the position goes 100% into one asset if price moves outside the range. |
| 113 | |
| 114 | ### Position Value |
| 115 | |
| 116 | For a CLMM position with liquidity L in range [P_lower, P_upper] at current price P: |
| 117 | |
| 118 | ```python |
| 119 | if P <= P_lower: |
| 120 | # All in token X (below range) |
| 121 | value_x = L * (1/sqrt(P_lower) - 1/sqrt(P_upper)) |
| 122 | value_y = 0 |
| 123 | elif P >= P_upper: |
| 124 | # All in token Y (above range) |
| 125 | value_x = 0 |
| 126 | value_y = L * (sqrt(P_upper) - sqrt(P_lower)) |
| 127 | else: |
| 128 | # In range — holds both tokens |
| 129 | value_x = L * (1/sqrt(P) - 1/sqrt(P_upper)) |
| 130 | value_y = L * (sqrt(P) - sqrt(P_lower)) |
| 131 | ``` |
| 132 | |
| 133 | ### Range Strategy Comparison |
| 134 | |
| 135 | | Range | Efficiency | IL Risk | Fee Capture | Best For | |
| 136 | |-------|-----------|---------|-------------|----------| |
| 137 | | ±2% | ~50x | Very high | High if in range | Stablecoins, tight pegs | |
| 138 | | ±5% | ~20x | High | Good for trending | Active management | |
| 139 | | ±25% | ~4x | Moderate | Consistent | Semi-passive | |
| 140 | | ±100% | ~2x | Low | Lower per $ | Passive, volatile pairs | |
| 141 | | Full range | 1x | Baseline | Always earning | Set and forget | |
| 142 | |
| 143 | See `references/amm_formulas.md` for full CLMM derivations. |
| 144 | |
| 145 | --- |
| 146 | |
| 147 | ## 3. Price Impact |
| 148 | |
| 149 | ### Constant Product Impact |
| 150 | |
| 151 | ```python |
| 152 | # Price impact as a fraction |
| 153 | price_impact = delta_x / (x + delta_x) |
| 154 | |
| 155 | # As percentage of pool |
| 156 | pool_fraction = trade_value / pool_tvl |
| 157 | |
| 158 | # Rule of thumb: impact ≈ 2 * pool_fraction for constant product |
| 159 | ``` |
| 160 | |
| 161 | ### Multi-Hop Impact |
| 162 | |
| 163 | For a route through multiple pools, compound the impacts: |
| 164 | |
| 165 | ```python |
| 166 | def multi_hop_impact(hops: list[dict]) -> float: |
| 167 | """Calculate total price impact across route legs. |
| 168 | |
| 169 | Args: |
| 170 | hops: List of {reserve_in, trade_amount} for each leg. |
| 171 | |
| 172 | Returns: |
| 173 | Total price impact as a fraction. |
| 174 | """ |
| 175 | remaining = 1.0 |
| 176 | for hop |