Headroom, LP opportunity discovery
In PoolscopeFind the pairs where new liquidity would earn more in fees than it gives up to arbitrage.
Part of Poolscope. Ranks the pairs where added liquidity would net the most after the arbitrage benchmark, then sizes the capital per range preset on the production router: routed, direct and arbitrage fees kept apart, with the minimum-viable, most capital-efficient and highest-net capital.
- LP funds
- ALMs and vault managers
- DEX teams
Where would new liquidity net the most?
Sample response · illustrative numbersEvery pair with at least $50 of fees a day, screened with $100K added full range: fees the position would earn by component, minus the benchmark arbitrage loss (LVR). Ranked by net LP dollars a day, then by net per $1K. Pick a row for its capital curve.
| Fees by component | Flags | |||||||
|---|---|---|---|---|---|---|---|---|
WETH/cbBTC uniswap-v3 0x70ac…bae1 · 30 bp | +$2.26 | +$0.02 | 1.30 | 1.56 | Fees cover the benchmark arbitrage loss | medium | few-competitors | |
USDC/AERO aerodrome-slipstream 0x6cdc…971d · 30 bp | +$1.20 | +$0.01 | 1.16 | 1.22 | Fees cover the benchmark arbitrage loss | low | few-competitors | |
WETH/USDC uniswap-v3 0x6c56…1372 · 30 bp | −$1.38 | −$0.01 | 0.81 | 0.98 | Fees do not cover the benchmark arbitrage loss | medium | few-competitors |
- Routed
- Direct
- Unclassified
- Arbitrage
14 screened pairs below the fee floor left out.
Sample in the shape of GET /ext/market/lp-opportunities on Base. Routed fees count only aggregator transactions we observe: a lower bound. Direct flow stays at its venue and is shared with the added liquidity; arbitrage fees use the measured rate per unit of in-range liquidity at the fee tier.
WETH/USDC: what each capital size would net
Sample response · illustrative numbersAdded capital on a range centred on the reference price. Routed fees come from the production router at each depth, so they flatten as the pool takes more of the flow; direct flow is shared; arbitrage fees scale with the added liquidity; LVR accrues only while in range.
LP-net fees over LVR, by capital
- Min viable$19.1K
- Max total$2.50M
- Match median$10.0K
- Beat best$10.0K
Shaded: 10th–90th percentile of an hour bootstrap of the LVR path. Each source is shown on its own, never combined. Dashed line: fees equal the benchmark loss.
Against the pair's other pools
| Target | uniswap-v3 0x6c56…1372 | 30 bp | 0.98 |
| Best competitor | solidly-v3 0x551a…221b | 5 bp | 0.56 |
Volume-weighted median of the other pools: 0.56. The added position matches it from $10.0K and beats the best from $10.0K.
Sample in the shape of the lp-opportunity-curve answer (72-hour window, illustrative router points). The routed share is checked in-sample only so far (error -3.0%); the out-of-sample check on real liquidity changes is not run yet. Fee tiers are the DEX's standard tiers only.
How to read the figures
Sample response · illustrative numbers- Good> 100
- Fine10–100
- Watch2–10
- Thin1–2
- Not covered< 1
Bands apply to a ratio of fees over the benchmark arbitrage loss. A pool that passes 80 % of its fees to LPs covers the loss from a gross ratio of 1.25. Where fees reach LPs through an off-chain rewarder, per-position income is not forecast.
- Gross F/LVR
- All swap fees over the benchmark loss to arbitrage (LVR) on the pair's reference price.
- LP-net F/LVR
- Gross × the DEX's documented LP share. At 1 or more, LP fees cover the benchmark loss.
- Expected position return
- Needs a range and capital: Headroom's capital curve.
- Realised position return
- One position's actual P&L: not modelled.
What Headroom gives you
A capital scenario, not a ratio
Ask with capital, a range preset, a standard fee tier, the LP share and a horizon. The answer is fees and arbitrage loss per day for that position, while it is in range.
Three kinds of fee income, kept apart
Aggregator flow is replayed through the production router with your liquidity added. Direct flow stays where it trades and is only shared. Arbitrage fees come from the pair's pools at the same fee tier.
Three answers on one curve
Where LP fees first cover the arbitrage benchmark, where each added dollar earns the most, and where total net income peaks. The curve is searched point by point and never assumed to rise.
Uncertainty you can read
Price, routing and demand uncertainty are shown separately, and the routing back-test is published with every curve.
How it works
- 01
Rank
Pairs are screened at full range from stored fees, flow classes and arbitrage loss, and sorted by projected net LP income per day.
- 02
Route
For a chosen pool and range, the production router replays the window's aggregator trades with each capital amount added.
- 03
Decide
Read the capital points, the competitors' F/LVR and the uncertainty bands, per range preset.
Call it from code
Pairs ranked by the projected incremental net LP income per day of a full-range capital scenario, with the routed, direct and arbitrage volume, each fee component, the competitors' F/LVR, the target pool and confidence. Pairs below a minimum of daily fees are left out.
GET /api/v1/ext/market/lp-opportunities · 100 CU
Send your key in x-api-key.
The ranking does not route: the target keeps its own routed and direct fees, diluted by the added liquidity. Use the capital curve for the router.
Example values are illustrative. Token addresses are real Base contracts; amounts are raw integer units as decimal strings.
curl -s "https://llens.abanchev.com/api/v1/ext/market/lp-opportunities?chainId=8453&capitalUsd=100000&horizonDays=30&windowHours=72" \
-H "x-api-key: $LL_API_KEY"{
"chainId": "8453",
"from": "2026-10-15T19:00:00.000Z",
"to": "2026-10-22T19:00:00.000Z",
"windowHours": 168,
"total": 3,
"belowFeeFloor": 14,
"minPairFeesUsdPerDay": 50,
"offset": 0,
"nextOffset": null,
"pairs": [
{
"tokenA": "0x4200000000000000000000000000000000000006",
"tokenB": "0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf",
"symbolA": "WETH",
"symbolB": "cbBTC",
"routedVolumeUsd": 22400000,
"directVolumeUsd": 4100000,
"arbVolumeUsd": 12700000,
"unclassifiedVolumeUsd": 1200000,
"pairFeesUsdPerDay": 102578,
"pools": 2,
"pricedPools": 2,
"bestCompetitor": {
"pool": "0x8c7080564b5a792a33ef2fd473fba6364d5495e5",
"dex": "solidly-v3",
"ratio": 0.559632,
"feeBps": 5,
"volumeUsd": 7742.51
},
"medianCompetitorRatio": 0.559632,
"target": {
"kind": "pool",
"pool": "0x70acdf2ad0bf2402c957154f944c19ef4e1cbae1",
"dex": "uniswap-v3",
"ratio": 1.56403,
"band": "uncovered",
"lpNetRatio": 1.30284,
"coverage": "does-not-cover",
"depthUsd": 1385500000,
"feeTierBps": 30
},
"assumedFeeBps": 30,
"screening": {
"capitalUsd": 100000,
"rangePreset": "full",
"lpShare": {
"share": 0.833,
"source": "Uniswap protocol-fee expansion (Base, 2026): 1/4 of the 0.01%/0.05% tiers, 1/6 of 0.3%/1%",
"given": false
},
"feesUsdPerDay": {
"routed": 4.77646,
"direct": 2.09698,
"unclassified": 0.582495,
"arb": 4.19427
},
"lvrUsdPerDay": 7.44918,
"ratioGross": 1.56396,
"ratioLpNet": 1.30278,
"netUsdPerDay": 2.25544,
"netUsdPerDayPer1k": 0.0225544,
"horizonDays": 30,
"netUsdHorizon": 67.6633,
"coverage": "covers",
"arbRate": {
"perUnitLPerHour": 0.000170473,
"tierBps": 30,
"match": "same-tier",
"pools": 1
}
},
"pairDepthUsd": 1385510000,
"confidence": "medium",
"flags": [
"few-competitors"
]
},
{
"tokenA": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"tokenB": "0x940181a94a35a4569e4529a3cdfb74e38fd98631",
"symbolA": "USDC",
"symbolB": "AERO",
"routedVolumeUsd": 3100000,
"directVolumeUsd": 600000,
"arbVolumeUsd": 1400000,
"unclassifiedVolumeUsd": 200000,
"pairFeesUsdPerDay": 15386.6,
"pools": 1,
"pricedPools": 1,
"bestCompetitor": null,
"medianCompetitorRatio": null,
"target": {
"kind": "pool",
"pool": "0x6cdcb1c4a4d1c3c6d054b27ac5b77e89eafb971d",
"dex": "aerodrome-slipstream",
"ratio": 1.2219,
"band": "uncovered",
"lpNetRatio": 1.1608,
"coverage": "does-not-cover",
"depthUsd": 207824000,
"feeTierBps": 30
},
"assumedFeeBps": 30,
"screening": {
"capitalUsd": 100000,
"rangePreset": "full",
"lpShare": {
"share": 0.95,
"source": "fee-earning (unstaked) LPs; staked LPs earn emissions and their fees go to voters",
"given": false
},
"feesUsdPerDay": {
"routed": 3.73008,
"direct": 1.6376,
"unclassified": 0.454888,
"arb": 3.27677
},
"lvrUsdPerDay": 7.44918,
"ratioGross": 1.22152,
"ratioLpNet": 1.16045,
"netUsdPerDay": 1.1952,
"netUsdPerDayPer1k": 0.011952,
"horizonDays": 30,
"netUsdHorizon": 35.8559,
"coverage": "covers",
"arbRate": {
"perUnitLPerHour": 0.000133182,
"tierBps": 30,
"match": "same-tier",
"pools": 1
}
},
"pairDepthUsd": 207824000,
"confidence": "low",
"flags": [
"few-competitors"
]
},
{
"tokenA": "0x4200000000000000000000000000000000000006",
"tokenB": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"symbolA": "WETH",
"symbolB": "USDC",
"routedVolumeUsd": 41200000,
"directVolumeUsd": 9800000,
"arbVolumeUsd": 30100000,
"unclassifiedVolumeUsd": 3400000,
"pairFeesUsdPerDay": 256444,
"pools": 2,
"pricedPools": 2,
"bestCompetitor": {
"pool": "0x551a0e3d267bea87048f08cc94cc6035ad99221b",
"dex": "solidly-v3",
"ratio": 0.559632,
"feeBps": 5,
"volumeUsd": 15485
},
"medianCompetitorRatio": 0.559632,
"target": {
"kind": "pool",
"pool": "0x6c561b446416e1a00e8e93e221854d6ea4171372",
"dex": "uniswap-v3",
"ratio": 0.977519,
"band": "uncovered",
"lpNetRatio": 0.814274,
"coverage": "does-not-cover",
"depthUsd": 3463740000,
"feeTierBps": 30
},
"assumedFeeBps": 30,
"screening": {
"capitalUsd": 100000,
"rangePreset": "full",
"lpShare": {
"share": 0.833,
"source": "Uniswap protocol-fee expansion (Base, 2026): 1/4 of the 0.01%/0.05% tiers, 1/6 of 0.3%/1%",
"given": false
},
"feesUsdPerDay": {
"routed": 2.98542,
"direct": 1.31067,
"unclassified": 0.364075,
"arb": 2.62142
},
"lvrUsdPerDay": 7.44918,
"ratioGross": 0.977501,
"ratioLpNet": 0.814259,
"netUsdPerDay": -1.38362,
"netUsdPerDayPer1k": -0.0138362,
"horizonDays": 30,
"netUsdHorizon": -41.5086,
"coverage": "does-not-cover",
"arbRate": {
"perUnitLPerHour": 0.000106546,
"tierBps": 30,
"match": "same-tier",
"pools": 1
}
},
"pairDepthUsd": 3463770000,
"confidence": "medium",
"flags": [
"few-competitors"
]
}
],
"method": "capital scenario: routed (router), direct (diluted) and arbitrage (tier rate) fees over LVR in range; see the method field of a live answer"
}Endpoints
Every call returns JSON with the block it was computed on.
Plans
- Pro
- Enterprise
Included with Poolscope keys. Capital curves run on a shared engine lane: one at a time and 20 a day per organization.
Pricing on request.
Good to know
- Fee inputs are the DEX family's standard tiers only: no custom or dynamic fees and no fee search.
- Routed fees are a lower bound: only aggregator flow we observe is routed.
- Out-of-sample back-tests on real liquidity changes are not published yet; routing uncertainty is in-sample.
- Where fees reach LPs through an off-chain rewarder: pool-level figures only; per-position income is not forecast.
- Live on Base and Sonic.
Other Liquidity Lens products
- Liquidity LensTruefill, Execution-price oracleThe price you can actually execute, at your size, with the route that proves it.
- Liquidity LensPoolscope, Pool earnings and flow analyticsKnow what every pool of your pair earned, hour by hour, and who traded through it.
- Liquidity LensRangefinder, LP range and capital backtestsTest a range or a capital size against the swaps that actually hit the pool, before you deploy.
- Liquidity LensTripwire, Execution and flow alertsHear about a widening execution gap or a shift in a pool's flow, without polling.