Coverage
Finding a trade without knowing what a DEX is, and the 2.6% that still gets away.
The engine does not know what a DEX is. It reads money moving and works out which movements were trades. That sounds like a philosophical difference and it is worth about fifty eight percentage points.
The version that kept a list
The first engine watched the Uniswap V3 Swap signature, decoded what came back, and looked like it was working. Pools appeared, prices moved, the screener filled up.
Then it was measured against the chain rather than against itself. 39.8% of the chain's swap transactions. The rest were happening at venues the list had never been told about, and on a chain where a new pad deploys most weeks, that gap was going to widen on its own.
Enumerating venues is a losing game with a clock on it.
What the measurements said
Before rebuilding anything, every candidate approach was measured against a live sample.
| Strategy | Coverage of swap transactions |
|---|---|
| Uniswap V3 only, the old engine | 39.8% |
| Uniswap V4 only | 59.8% |
| V3 and V4 signature decode | 95.9% |
| Value flow netting plus V4 event | 99.7% detected |
Two findings moved the design, and both contradicted the plan that existed before the measuring started.
Transfer netting alone covers V4 at about thirty percent, not the sixty five that had been assumed. Native ETH emits no log when it moves, and 59.8% of V4 pools quote in native ETH rather than WETH. So the plan's primary mechanism had a hole precisely where the chain's volume is.
Enumerating venues is still wrong, and not for philosophical reasons. In a 120 block sample, netting found trades at five contracts that no known signature explains. Signature enumeration cannot find those at any level of effort, and it loses ground every time somebody deploys something new.
So the shape is netting first, with V4's own event patching one structural blind spot rather than serving as a second list.
How it works now
The engine reads the Transfer events every token emits anyway. For each
transaction it nets the value moving through each address, and any address that
comes out two sided is a venue that just did a trade.
Uniswap V2, V3, V4, Curve, an aggregator, a pad that launched this morning. They all look identical to it, because money moving is money moving.
Native ETH is the one thing this cannot see, because it emits no log at all. V4's own Swap event covers that leg and nothing else.
V4 amounts are inverted relative to V3
Uniswap V4 reports amounts from the caller's perspective. Uniswap V3 reports them from the pool's. They are exact inverses.
Proven against one live transaction where amount0 read negative 0.09012
WETH while WETH was demonstrably moving into the pool. Read it the wrong way
round and every buy books as a sell, the entire leaderboard inverts, and
nothing looks wrong, because all the numbers remain individually plausible.
This is the single easiest catastrophic mistake in the codebase.
Why venues are learned instead of listed
Inside a single transaction, a trader and their pool are indistinguishable.
Both net two sided, and their balances are exact mirrors. The trader is minus A plus C, the pool is plus A minus C. There is no structural way to tell them apart from one transaction, and the first netting design summed every two sided address to find the trade, which cancels to zero for every simple swap.
What separates them is repetition. A pool trades against many counterparties, a trader does not. So venues are learned over two trades, and anything emitting a recognised Swap signature is accepted as a venue immediately.
That signature list still exists in the codebase and it is worth being precise about its job. It is only an accelerator. Nothing is ever found by it. An unlisted venue is still caught, one trade later, which is the property enumeration can never have.
What it catches
97.4% of the chain's position moving swap transactions, scored on a fresh range against signature ground truth.
That is not the number to watch, though. The number to watch is that the engine continuously books trades at contracts no known signature explains, running at roughly seventeen hundred every few minutes. A list can never do that no matter how long it gets.
The visible proof is the venues column on the terminal. One token trades at fifty distinct venues, another at thirty five. The old engine saw one.
The 2.6% that gets away
Counted and published under the health endpoint rather than rounded away.
Complex nets. A venue that nets three or more tokens in one transaction is several pools inside one contract. Splitting the quote between them needs per pool amounts that nothing has, and a guessed split is a wrong cost basis rather than a missing one.
Unpriced trades. Two non quote tokens changing hands. Real activity, no price attached to it.
Quote only trades. WETH against USDG, or wrapping ETH. These are detected and deliberately not booked, because there is no position in them. This is not a miss, and it is why the coverage figure is quoted against position moving transactions specifically.
A handful move value somewhere no log can see.
The canary
detector.unknownVenueTrades on the health endpoint should never sit at
zero.
Zero means the engine has quietly gone back to finding only what it was told to look for, which is the exact failure this whole design exists to prevent. It would keep serving plausible data the entire time. This counter is how you find out.