Liquidity concepts
What you are really doing when you provide liquidity: how prices are set, what a range is, where fees come from, and why you can lose money even when fees are coming in.
What liquidity provision is
An automated market maker (AMM) lets people trade tokens without an order book. Instead of matching buyers with sellers, traders swap against a pool of tokens that other people have deposited. Those depositors are liquidity providers (LPs). Each trade pays a fee, and the fee goes to the LPs whose liquidity was used.
Providing liquidity is therefore a business of selling small amounts of each asset as the price moves, in return for fees. It is not a savings account. Your outcome depends on how much trading happens, how the price moves, and how well you choose where your liquidity sits.
How a pool sets its price
Uniswap's original design keeps the product of the two token amounts in the pool constant: x × y = k. The price is the ratio of the two amounts. A worked example with round numbers:
| Step | ETH in pool | USDC in pool | Price (USDC per ETH) |
|---|---|---|---|
| Start | 100 | 250,000 | 2,500 |
| A trader buys 1 ETH | 99 | 252,525.25 | 2,550.76 |
| What the trader paid | 2,525.25 USDC | average 2,525.25 per ETH |
Because k = 100 × 250,000 = 25,000,000 must stay the same, removing 1 ETH forces the USDC side up to 25,000,000 ÷ 99 = 252,525.25. The trader paid slightly more than the starting price of 2,500: that gap is price impact, and it is larger when the trade is large relative to the pool. Deeper pools (more liquidity) move the price less.
Uniswap v2, v3 and v4 at a glance
| v2 | v3 | v4 | |
|---|---|---|---|
| Where liquidity sits | Across every price (0 to ∞) | In a price range you choose | In a price range you choose |
| What you hold | Fungible LP tokens (ERC-20) | A position NFT (ERC-721) | A position NFT (ERC-721) |
| Fee tiers | One: 0.30% | Several: 0.01%, 0.05%, 0.30%, 1% | Any fee the pool creator sets; may be dynamic |
| Pools are | Separate contracts | Separate contracts | State inside one PoolManager contract |
| Native ETH | Wrapped (WETH) | Wrapped (WETH) | Supported directly |
| Hooks | No | No | Optional, per pool |
| Fees are | Added to the pool and compound | Tracked per position, collected manually | Tracked per position, collected manually |
| In Self-Quantum Liquidity | Read | Read Create | Read |
“In v3 and v4, fees are collected separately and must be manually redeemed by the position owner.”
In v2 every pool charges a flat 0.30% and the fee stays in the pool, so it compounds automatically. In v3 and v4 the fees you earn sit in your position as a claimable balance until you collect them. Self-Quantum Liquidity shows this as Owed fees on a position.
“Uniswap v4 removes fixed tiers entirely. Pool creators can set any fee from 0% to 100% in 0.0001% increments (hundredths of a bip), and pools can use dynamic fees that adjust in real time through hooks.”
“Unlike previous versions where each pool was a separate smart contract, v4 manages pools through a single contract: PoolManager.”
Price ranges and ticks
In v3 and v4 the continuous price line is divided into discrete steps called ticks. A position is defined by a lower tick and an upper tick, and it provides liquidity only while the price is between them.
“Ticks are spaced such that an increase or decrease of 1 tick represents a 0.01% increase or decrease in price at any point in price space.”
The mathematical link between a tick and a price is price = 1.0001^tick, measured as token1 per token0 in each token's smallest unit. Decimals matter: to turn it into a human price you multiply by 10^(decimals0 − decimals1). For WETH (18 decimals) and USDC (6 decimals) that factor is 10^12.
// price of 1 WETH in USDC at a given tick
const priceAtTick = (tick: number) => 1.0001 ** tick * 1e12;
priceAtTick(-198080); // ≈ 2,499.91 (USDC per WETH)
priceAtTick(-199140); // ≈ 2,248.50
priceAtTick(-197120); // ≈ 2,751.79
// and back: which tick is a price?
const tickAtPrice = (price: number) => Math.log(price / 1e12) / Math.log(1.0001);
tickAtPrice(2500); // ≈ -198079.65
Tick spacing follows the fee tier
You cannot use every tick. A pool only lets positions start and end on ticks that are multiples of its tick spacing, and the spacing is tied to the fee tier.
| Fee tier | Tick spacing | Smallest range step |
|---|---|---|
| 0.01% | 1 | 0.01% |
| 0.05% | 10 | 0.10% |
| 0.30% | 60 | 0.60% |
| 1.00% | 200 | 2.02% |
“Lower fee tiers allow closer potentially active ticks, and higher fees allow a relatively wider spacing of potential active ticks.”
This is why the Builder says Range (snapped to ticks). If you ask for a range of 2,250 to 2,750 in a 0.05% pool, Self-Quantum Liquidity rounds the lower bound down and the upper bound up to the nearest allowed ticks. The real range becomes about 2,248.50 to 2,751.79: slightly wider than you asked, never narrower.
Concentrated liquidity and capital efficiency
“The defining idea of Uniswap v3 is concentrated liquidity: liquidity that is allocated within a custom price range.”
“In the constant product market maker formula used by Uniswap v1 and v2, only a fraction of the assets in the pool are available at a given price.”
A v2 position spreads your capital over every possible price, but the price only ever visits a small part of that line. The rest of your capital sits idle. The Uniswap docs give a striking example for a stablecoin pair:
“the v2 DAI/USDC pair uses ~0.50% of total available capital for trading between $0.99 and $1.01, the price range where most volume typically occurs.”
Concentrating your capital in a narrower range makes the same money behave like much more liquidity inside that range. This is called capital efficiency. For a range from Pa to Pb it is, compared with full range:
const efficiency = (Pa: number, Pb: number) => 1 / (1 - (Pa / Pb) ** 0.25);
efficiency(0.9, 1.1); // ≈ 20.4 (±10%)
efficiency(0.5, 1.5); // ≈ 4.2 (±50%)
| Range around price | Price multiple | Capital efficiency vs full range | Capital needed for same depth |
|---|---|---|---|
| ±0.1% | 0.999 – 1.001 | ≈ 2000× | 0.05% |
| ±0.5% | 0.995 – 1.005 | ≈ 400× | 0.25% |
| ±1% | 0.990 – 1.010 | ≈ 200× | 0.50% |
| ±5% | 0.950 – 1.050 | ≈ 40.5× | 2.47% |
| ±10% | 0.900 – 1.100 | ≈ 20.4× | 4.89% |
| ±25% | 0.750 – 1.250 | ≈ 8.3× | 11.99% |
| ±50% | 0.500 – 1.500 | ≈ 4.2× | 24.02% |
Active, inactive and single-asset positions
“When the price exits a position's interval, the position's liquidity is no longer active and no longer earns fees.”
“As price moves in one direction, LPs gain more of one asset as swappers demand the other, until their entire position consists of a single asset.”
Think of it as your position automatically selling the asset that is rising and buying the asset that is falling, across the range. When the price runs through your upper edge you have sold everything you were willing to sell, and you hold only the quote asset. When the price falls through your lower edge you have bought everything, and you hold only the base asset.
- In range: earning fees, holding a mix of both assets that changes with the price.
- Out of range: not earning fees, holding one asset. If the price returns, the position becomes active again.
- Self-Quantum Liquidity shows this as the status tile: IN RANGE OUT OF RANGE CLOSED.
Where fees come from
A swap fee is charged on every trade and shared among the LPs whose liquidity was active at the time, in proportion to how much liquidity each provided.
“LP fee income depends on two factors: how much liquidity you provide, and how well your chosen range tracks the market price.”
A worked example
Suppose a 0.05% pool sees $10,000 of volume while your position is in range. The fees paid by traders are $10,000 × 0.0005 = $5. If your liquidity is 1% of the liquidity active at those prices, your share is $5 × 1% = $0.05. Fees are small per trade and add up through volume, time in range, and your share of the active liquidity.
Protocol fees
Part of the swap fee can go to the Uniswap protocol rather than to LPs on some pools. The docs describe the current arrangement:
“At launch, protocol fees are set to approximately 1/6 of the swap fee on enabled pools.”
So a pool's headline fee tier is not always exactly what LPs receive. Check the current rules in the Uniswap fee documentation before relying on a specific number.
Choosing a fee tier
| Tier | Typically fits | Why |
|---|---|---|
| 0.01% | Stablecoin ↔ stablecoin | Prices barely move, so traders pay very little and volume is high. |
| 0.05% | Large, liquid pairs (ETH/USDC) | Tight spreads attract lots of volume; ranges can be narrow. |
| 0.30% | Standard pairs | The long-standing default; balanced between fee and volume. |
| 1.00% | Volatile or thin pairs | Compensates LPs for higher risk, but traders go elsewhere if cheaper pools exist. |
The tier with the most liquidity usually has the best prices for traders and therefore most of the volume. The Pools tab sorts by TVL so the deepest pool for a pair comes first.
Impermanent loss
“There is a risk of losing money during large and sustained movement in the underlying asset price compared to simply holding an asset.”
Impermanent loss (also called divergence loss) is the difference between what your position is worth and what you would have if you had simply kept the two tokens in your wallet. It appears whenever the price moves away from where you started, in either direction.
“Of course, if the price were to return to the same value as when the liquidity provider added their liquidity, this loss would disappear. For this reason, we can call it an impermanent loss.”
For a full-range, 50/50 constant-product pool the loss, ignoring fees, depends only on the price ratio:
// ratio = newPrice / startPrice
const impermanentLoss = (ratio: number) => (2 * Math.sqrt(ratio)) / (1 + ratio) - 1;
impermanentLoss(2); // -0.0572 → 5.7% less than holding
impermanentLoss(0.5) // -0.0572 → the same loss for a halving
| Price ratio | Move | Position vs holding |
|---|---|---|
| 1.25× | 25% up (or the same ratio down) | -0.6% |
| 1.5× | 50% up (or the same ratio down) | -2.0% |
| 2× | 100% up (or the same ratio down) | -5.7% |
| 3× | 200% up (or the same ratio down) | -13.4% |
| 4× | 300% up (or the same ratio down) | -20.0% |
| 5× | 400% up (or the same ratio down) | -25.5% |
These are the same figures quoted in the Uniswap docs (for example a 2× change gives a 5.7% loss, and the loss is the same for a doubling or a halving).
Concentrated ranges amplify it
The table above is for v2-style full range. In a concentrated range the same price move costs much more, because your capital is working harder. This table uses the exact v3 formulas, starting at the middle of the range, no fees:
| Range | −5% price | +5% | +10% | +20% | −20% |
|---|---|---|---|---|---|
| Full range | -0.0% | -0.0% | -0.1% | -0.4% | -0.6% |
| ±50% | -0.1% | -0.1% | -0.5% | -1.8% | -2.5% |
| ±25% | -0.3% | -0.2% | -1.0% | -3.5% | -5.1% |
| ±10% | -0.7% | -0.6% | -2.3% | -6.6% | -9.1% |
| ±5% | -1.3% | -1.2% | -3.5% | -7.8% | -10.2% |
For example a ±10% range loses about 2.3% versus holding when the price rises 10% (the top edge), while a full-range position loses only about 0.1% for the same move. Beyond the edge the loss keeps growing in the table because the position is fully converted into one asset.
[ CALCULATOR ] Impermanent loss vs holding (no fees)
- If you just held
- 1.500
- Position value
- 1.414
- Difference vs holding
- -5.72%
Start: value 1.00, half in each asset. Trading fees earned while in range are not included and can offset some or all of this difference.
“The more chop and back and forth, the better.”
That line explains where fees fit in. Fees are earned on trades, and price chopping back and forth inside your range generates many trades without moving the price far, which is the best case for an LP. A steady one-way move is the worst case: little fee income, maximum loss versus holding.
[ CALCULATOR ] Do fees beat impermanent loss?
- Impermanent loss
- -7.08%
- Fee income (assumed)
- +1.64%
- Net vs holding
- -5.44%
Fee APR needed just to break even over 30 days: 86%. The fee APR above is your assumption, not a prediction. If the price ends outside the range, this tool halves the fee income as a rough stand-in for the time spent out of range. Real results depend on volume, fee tier, and how long the price stays in range.
Range orders
Because a range can sit entirely above or below the current price, a position can behave like a limit order.
“In Uniswap v3 and v4, you can approximate a limit order by providing a single asset as liquidity within a specific range.”
Example (our numbers, the same idea as the Uniswap docs): ETH is 2,500 USDC and you would like to sell some at 3,000. Provide ETH in a range just above 2,500 up to or around 3,000. As the price rises through the range, the pool sells your ETH for USDC at prices you chose, and you collect fees while it happens. A buy-the-dip order works the same way in reverse, using USDC in a range below the price.
“range orders, unlike traditional limit orders, will be unfilled if the spot price crosses the given range and then reverses to recross in the opposite direction before the target asset is withdrawn.”
“Selecting a wider range may generate more fees if there is price churn within your range, at the cost of increasing the risk of having your order unfilled if the spot price reverses before completing your full range.”
Uniswap v4: hooks and the singleton
“Hooks allow developers to customize and extend the behavior of liquidity pools. They are external smart contracts that can be attached to individual pools to intercept and modify the execution flow at specific points during pool-related actions.”
Hooks can add dynamic fees, custom pricing, on-chain limit orders and more. They also mean that two pools with the same tokens can behave very differently. A pool with a hook is only as safe as that hook's code.
- Self-Quantum Liquidity reads hookless v4 pools. It does not interpret hooks. If you find a v4 pool in a lookup, check on the explorer whether it has a hook before you trust its price or liquidity.
- All v4 pools live in one contract (the PoolManager), so a pool's own token balance is not readable per pool. That is why TVL shows a dash for v4 rows.
- Native ETH is supported directly in v4, so many ETH pools use the native coin instead of WETH. The Builder labels these as native.
“The Uniswap v3 core contracts are also non-upgradeable, with some parameters controlled by governance as described in Section 4.”
Where your funds live
- When you add liquidity the tokens move from your wallet into Uniswap's contracts.
- The contract mints you a position NFT recording your range and share. That NFT is the proof of your position and sits in your wallet.
- Whoever holds the NFT controls the position. Never send it to, or approve it for, anyone you do not fully trust.
- To get tokens back you decrease the liquidity, collect the tokens and fees, and optionally burn the empty NFT.
Key takeaways
- A range is a bet on where the price will mostly stay. Narrow ranges earn more per dollar while the price is inside and hurt more when it leaves.
- Fees compete with impermanent loss. Neither is guaranteed.
- Out of range means earning nothing, not losing everything. You decide whether to wait, adjust or withdraw.
- The tier and tick spacing limit which ranges you can pick.
- Next: use the app, or read strategies and tactics.
These docs are educational. They are not financial, legal or tax advice. Providing liquidity carries risk, including loss of funds. Self-Quantum Liquidity is new software and has not been audited.