Liquidity positions

What providing liquidity actually costs — the quote-asset ledger, impermanent loss, break-even volume, V3 range, and why none of it is revenue until it is realised.

4 min readUpdated 4 August 2026admin, liquidity, impermanent-loss, pnl, positions

Once you have seeded a pool you hold a position, and the honest question about a position is not "how much has it earned" but "did providing this liquidity beat simply holding the two tokens". That is the headline figure on this console, it is signed, and it is frequently negative.

A page led by fee income says "this is working" on a position that is losing money. Fees are always positive and always growing; impermanent loss is the thing they have to cover.

The three figures, in the order they matter

  1. Negative means worse than simply holding
  2. Above the warn share, you are the market

1. The quote-asset ledger — the headline

Real money in versus real money out, in the quote token. No pricing, no valuation, no circularity. On a pool of your own token it is the only figure that cannot lie to you.

2. Position value versus holding — impermanent loss

What the position is worth now against what the same two amounts would be worth if you had never put them in a pool. Negative is a loss relative to holding. It is never presented as an opportunity: it is the cost of the fee income shown beside it.

Where the only available price is the pool's own, every dollar figure renders with "no independent price" rather than a number. A self-referential mark is worse than no mark.

3. Fees — and on V2, never bookable

A Uniswap-V2-style pool mixes fees into principal with no on-chain event separating them. There is no fact to book, so V2 fee income is real and will only ever show as a growing position. A V3-style collect() is different: it is decodable evidence, and the fee half of it accrues for the sweep once the principal released since the last collect has been subtracted.

Why the two headline figures disagree

They can disagree by more than a factor of two, and the case where they do is the common one. Seed 1,000,000 of your own token plus 100,000 USDC at $0.10, and let the token fall 90%:

Value
Impermanent loss −$46,754 (−42.5%)
USDC actually left $31,623, down from $100,000 (−68.4%)

The impermanent-loss figure understates the damage by more than half, because it is priced off the very pool that drained. The quote-asset ledger cannot be, which is why it leads.

Break-even volume

Impermanent loss divided by your share of the fee — and it uses lpFeeShareBps, not the fee tier. The tier is what the swapper pays; the LP share is what reaches your position after the venue's protocol cut, and a projection built on the tier overstates income by 17–20%.

On the conventional example — 10 ETH and 40,000 USDC at ETH = $4,000, ETH doubling — the loss is $6,863 and the LP share is 0.25%, so $2,745,000 of cumulative volume has to pass through an $80,000 pool during the move for fees to cover it. That number, not an APR, is what turns "the pool earns 0.3%" into a question you can answer.

V3: out of range earns nothing

Outside its tick range a V3 position earns zero. Not less — zero. The pool keeps quoting from everybody else's liquidity, your position keeps showing a value, and the fee line simply stops moving. There is no error anywhere, which is why the console carries it as a danger chip rather than a footnote.

v1 mints full-range positions only. A concentrated range the price leaves goes 100% one-sided and the market reads as an outage with no cause — that is a market-making product decision, not a listing step.

Concentration

Your liquidity divided by the pool's. Above dexDirectPoolOperatorShareWarnBps the console carries a permanent warning, because above it you are the market: most trades on that pool have you as the counterparty, including the ones your users lose.

None of this is revenue

Its value changes. adminProfit is a realised-revenue ledger, and a mark-to-market number in it makes one row mean "money we hold" and another "money we might collect" — at which point the dashboard number stops being auditable.

DEX_LP_FEE rows are written from a V3 collect() receipt whose fee half has been separated from its principal half, and only after the sweep credits them. Nothing on this console reaches the profit report.

DEX_LP_FEE is also a separate profit type from DEX_SWAP. One is a fee charged to a user on a trade you routed; the other is yield on capital you put at risk. Folding them makes "is the liquidity position actually profitable" unanswerable.