Every “LP removed ≥ $100k” ping is a decision: unwind, hedge, or ignore. He gets several a week and cannot tell them apart from the alert — the data that would is in the same API, one query away, and nobody joins it.
Every “LP removed” alert stops at the row that fired it. This one follows the wallet.
2 min 12 s later the same wallet put 99.8% of it — the same 1,962,475.54 UNI — into the pool next door.
Every “LP removed ≥ $100k” ping is a decision: unwind, hedge, or ignore. He gets several a week and cannot tell them apart from the alert — the data that would is in the same API, one query away, and nobody joins it.
$ python3 scripts/forwarding.py investigate --platform ethereum --address 0x1f9840…01f984 forwarding address — keyless · ethereum · 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984 following the wallet GET /v1/dex/token address=0x1f98…f984 platform=ethereum 200 487 ms GET /v1/dex/liquidity-change/list address=0x1f98…f984 minVolume=100000 platform=eth… 200 1004 ms GET /v1/dex/liquidity-change/list address=0x1f98…f984 lastId=AVd6RT…PQ== minVolume=… 200 641 ms GET /v1/dex/liquidity-change/list address=0x1f98…f984 lastId=AVd6RT…PQ== minVolume=… 200 573 ms GET /v1/dex/token/pools address=0x1f98…f984 platform=ethereum size=20 200 516 ms GET /v1/dex/liquidity-change/list address=0x1f98…f984 maker=0x4f0a…b9a9 platform=et… 200 806 ms GET /v1/dex/search q=0x1f98…f984 200 466 ms GET /v1/dex/search q=UNI 200 1180 ms GET /v2/cryptocurrency/info id=7083 200 297 ms GET /v1/dex/liquidity-change/list address=0xbf51…e9b1 maker=0x4f0a…b9a9 platform=bsc 200 522 ms GET /v1/dex/liquidity-change/list address=0xfa7f…f7f0 maker=0x4f0a…b9a9 platform=ar… 200 501 ms GET /v1/dex/liquidity-change/list address=0x8f18…ea21 maker=0x4f0a…b9a9 platform=un… 200 541 ms GET /v1/dex/liquidity-change/list address=0xb33e…180f maker=0x4f0a…b9a9 platform=po… 200 955 ms GET /v4/dex/pairs/quotes/latest contract_address=0x8626…7306 network_slug=ethereum 200 647 ms ● LP REMOVED −$21,330,275 Ring Exchange (Ethereum) · UNI/WBTC 2026-09-02 03:59:11 UTC maker 0x4f0aa5900b8292273b2f9a178d5468f8048bb9a9 ◆ MIGRATION · severity amber 99.8% recovered — $21,287,255 of $21,330,275 +$21,287,255 into Ring Exchange (Ethereum) · UNI/WETH 2 min 12 s later · pool now holds $102,239,395 21,287,254.93 ÷ 21,330,274.56 = 0.9980 14 calls · 14 × 200 · 0 credits · 50.6 s · keyless
{
"ts": "1788321551000",
"tp": "remove",
"tu": -21330274.564875204,
"m": "0x4f0aa5900b8292273b2f9a178d5468f8048bb9a9",
"t0s": "UNI", "t1s": "WBTC",
"a0": -1962475.5391248302
}
{
"ts": "1788321683000",
"tp": "add",
"tu": 21287254.934237212,
"m": "0x4f0aa5900b8292273b2f9a178d5468f8048bb9a9",
"t0s": "UNI", "t1s": "WETH",
"a0": 1962475.5391248302
}
| endpoint | what the agent takes from it |
|---|---|
/v1/dex/liquidity-change/list | the trigger, and with maker= the join: one wallet's adds and removes across every pool of the token, in one call |
/v1/dex/token/pools | every pool the wallet could have moved to — address, depth now, creation time |
/v1/dex/search | address → CoinMarketCap id, then the same id on every other chain |
/v2/cryptocurrency/info | the canonical cross-chain contract registry the sibling rows are checked against |
/v4/dex/pairs/quotes/latest | the destination pool's depth now — the money actually arrived |
/v1/dex/token | the card header: name, symbol, token liquidity |
A plain call shows the removal. The maker join, the five-way adjudication and the rewritten severity are what no endpoint returns — and no model of ours produces a number.
and the join needs four systems — a multi-chain liquidity-event indexer, a per-DEX pool registry, a cross-chain contract registry, a pool-depth oracle — to replace six free endpoints.
$ claude mcp add forwarding -- python3 $PWD/scripts/mcp_server.py tools exposed: largest_removals · where_did_liquidity_go · follow_maker › where did the UNI liquidity go? → where_did_liquidity_go {platform: ethereum, address: 0x1f9840…} MIGRATION · 99.8% recovered — $21,287,255 of $21,330,275 into Ring Exchange (Ethereum) · UNI/WETH 2 min 12 s later › and DAI, txn 0x3f8c69…f2fd84? → where_did_liquidity_go {platform: ethereum, address: 0x6b1754…, txn: 0x3f8c69…f2fd84} REFUSED — txn 0x3f8c69…f2fd84 is not an event — it adds and removes in the same transaction (JIT) the model never produced a number of its own
Rows carry no pool contract, so two fee tiers of one pair collapse into one identity — and the hero's share of its pool is unknown, printed as unknown, never as a number.
±6 h, walked with the cursor because startTime is plan-gated keyless. A wallet that comes back tomorrow reads as an Exit for that window, and the card says which window it searched.
Liquidity moved through a second wallet is not followed. Guessing one would put a number on the card that no row supports — deliberately not built.
The tier throttles per IP; the tool backs off 15 / 30 / 60 s and records every retry. A throttled follow is INCOMPLETE, never an Exit. The base rate follows same-chain only, so its Exit count is an upper bound.
$ git clone https://github.com/edycutjong/forwarding.git $ cd forwarding $ python3 scripts/forwarding.py investigate \ --platform ethereum \ --address 0x1f9840a85d5af5bf1d1762f925bdaddc4201f984
The alert was true.
The panic was not.