Originally published at rantum.xyz, which is the canonical source.
A Uniswap V3 pool on Ethereum mainnet reports $3,286,019,931 of liquidity. The real assets backing it are 0.000739 WETH, which at $2,410.77 per ETH is about $1.78. Both figures are accurate, and the gap between them is the whole story.
This is what turned up while building a much less interesting thing: a browser extension that flags impersonator tokens in DEX listings.
The challenge
Token discovery surfaces have a verification problem that price feeds do not. A ticker is not an identifier. Anyone can deploy a contract whose name() returns "Dai Stablecoin" and whose symbol() returns "DAI", and nothing in the resulting search result distinguishes it from the real one. The contract address does, and the contract address is exactly the field that gets truncated in every list view.
The usual answer is a blocklist of known scams, which is a race you lose: new contracts deploy faster than any list is maintained. The inverse works better. Instead of enumerating what is fake, enumerate what is canonical, keyed on (ticker, chainId), and flag a row that shares a ticker on the same chain with a different address.
Building that check surfaced something more interesting than the check.
One bytecode, two deployers
Searching a handful of blue-chip tickers on DexScreener returned rows that looked like ordinary duplicates. They were not.
Those first fourteen turned out to be a rounding error. Enumerating every contract the two deployer wallets ever created returns 1,031 deployments, 1,005 of which carry that same 5,150 byte bytecode, split almost exactly evenly at 503 and 502. Running the detector described below across all 1,005 finds 184 impersonating a canonical ticker outright, across 143 distinct real tokens, plus 59 more cloning tickers that have several legitimate claimants. The remaining 762 use names no curated list carries, which is ordinary memecoin noise. That is still a floor: only two deployer wallets were enumerated.
Every one of fourteen contracts returns the same 5,150 byte runtime bytecode, SHA-256 prefix 7ff6feb2ee87face. The tokens they impersonate do not resemble each other at all: real DAI is 7,904 bytes, CRV 4,369, COMP 6,795, PEPE 4,517, every one distinct. Identical bytecode across fourteen supposedly unrelated tokens is a deployment fingerprint, not a coincidence.
Blockscout's contract metadata names the source MintBurnTeamToken, an off-the-shelf mintable template, and attributes all fourteen to just two externally owned accounts, split eight and six. No creation transaction is indexed for any of them, which is consistent with factory deployment instead of direct creation.
The tickers spoofed: DAI, CRV, APE, SHIB and LDO twice each, plus COMP, ENS, GRT and SNX. Nine tickers, fourteen contracts.
The mirage: $3.28 billion from an initialization tick
The impersonation is cheap and common. The reported liquidity is the interesting part. Take the fake DAI pool, 0x90e6...5a87, a Uniswap V3 pool at the 0.3% fee tier, and read its state directly:
balanceOf(fakeDAI, pool) = 2,506,024,274.84 // worthless token
balanceOf(WETH, pool) = 0.000739 // the entire real backing
slot0().tick = -75,180 // chosen at initialization
price(token1/token0) = 0.0005434 WETH // derived from that tick
A Uniswap V3 pool is initialized at whatever price its creator chooses, because that price is a tick rather than a consequence of deposited capital. A V3 position is then defined by a price range, and that is the part that does the work here.
The Mint event for this pool provides liquidity across the range [-75180, 887220]. The lower bound is exactly the initialization tick, the price the pool still sits at today. The upper bound, 887220, is the highest tick the 0.3% fee tier permits, so the range runs from the chosen price to effectively infinite price. When the price sits at the very bottom of a range, the position is denominated entirely in token0 and requires none of token1 at all.
So the deposit was 2,506,024,276 minted tokens and 0.000000000 WETH. Not a rounding error of WETH. None. The same structure appears on the CRV, SHIB and COMP pools, each opened with a single-sided position and zero WETH. The 0.000739 WETH sitting in this pool today did not come from the deployer; it is the accumulated dust of the daily cron buying its own token, a few thousandths of a cent at a time.
DexScreener values those reserves at the pool's spot price and reports the product as liquidity:
2,506,024,274 tokens x $1.31 = $3,286,019,931 of "liquidity."
The displayed price rounds to $1.31, and reproducing the total to the dollar takes the unrounded $1.3112. That rounding is worth $3.1 million on its own, which is a fair illustration of the scale being discussed.
The pool holds 0.000739 WETH, and that is a hard ceiling: it is the most anyone could ever extract by selling the token back into it, whatever the quoted price says. At $2,410.77 per ETH that ceiling is $1.78. The reported figure exceeds it by a factor of roughly 1.8 billion to one. Nothing is wrong with the arithmetic. The arithmetic is correct on inputs that were manufactured.
The fingerprint repeats, exactly
What makes this tractable to detect is that the operation never varied its parameters. Every one of the six pools sampled shows the same signature: a large reported liquidity, one cent of reported 24 hour volume, and precisely one buy and zero sells. Re-read 24 hours later, on 2026-09-02, all six returned identical figures.
That is not neglect. It is a schedule. The fake DAI pool's full swap history is 103 trades between 24 February and 2 September 2026, and in the last sixty days it traded on forty out of sixty days, thirty-seven of them between 04:00 and 04:59 UTC. The other three sampled pools cluster in the same window. Each trade is dust: roughly 0.012 of the fake token out for about 0.0000066 WETH in, about one and a half cents.
So the "one buy, $0.01 of volume" reading is not a stale cache and not a dead pool. It is a daily cron job buying a fraction of a cent of its own token, which is exactly enough to keep the pair looking traded to an indexer that sorts on recent activity. The listing is maintained.
| Ticker spoofed | Pool created | Reported liquidity | 24h volume | Buys / sells |
|---|---|---|---|---|
| DAI | 2026-02-24 | $3,286,019,931 | $0.01 | 1 / 0 |
| CRV | 2026-02-28 | $431,462,383 | $0.01 | 1 / 0 |
| ENS | 2026-03-07 | $389,657,165 | $0.01 | 1 / 0 |
| LDO | 2026-02-28 | $212,719,545 | $0.01 | 1 / 0 |
| COMP | 2026-03-08 | $130,141,448 | $0.01 | 1 / 0 |
| SHIB | 2026-03-08 | $42,017,195 | $0.01 | 1 / 0 |
Those six pools alone account for $4,492,017,667 of reported liquidity. All six were created between 24 February and 8 March 2026, and all six were still live, still listed, and still returned by ticker search on 1 September 2026, more than six months later.
Where the exposure is, and where it is not
This is not evenly distributed across venues, and it would be sloppy to imply it is. A live ticker search for CRV in the Uniswap interface returns six genuine Curve deployments across six chains, plus yCRV and cvxCRV, and none of the fleet. Searching by contract address is a different matter: the picker resolves any address pasted into it, fleet contracts included. What the curated list governs is what surfaces when a user types a ticker, and none of the fourteen appear on the Uniswap Labs default list.
The exposure sits on aggregators like DexScreener that index every pool by design, where comprehensiveness is the product and filtering is left to the reader. That is a stated design choice and not an oversight, which is precisely why the filtering has to come from somewhere else.
Detecting it without accusing the innocent
The detector is a canonical allowlist keyed on (ticker, chainId), built from independently maintained token lists rather than hand entered: 2,289 tickers and 3,675 ticker and chain pairs. Two decisions carry most of the weight.
The chain key is not optional. Keying on ticker alone flags every legitimately bridged token as an impersonator. The same real PEPE appears on seven chains, the same real CRV on six. A ticker only check would have called all of them fraudulent on day one.
Sources are ranked, not pooled. Curated lists (Uniswap Labs Default, 1inch) decide the canonical address. A permissive source (CoinGecko), which lists essentially every token with a market page, gets no vote on the address. It only reports how many other projects claim the same ticker on that chain. Treating all sources as equal peers deletes the tickers that matter most: PEPE, SHIB, UNI and APE all vanish, because a permissive list carries "Pepe King Prawn" and "El Sapo Pepe" alongside the real thing. Their presence is not evidence that real PEPE is ambiguous.
That second signal then gates the accusation. A red "not the canonical contract" verdict is only issued when every source agrees the ticker has exactly one claimant on that chain. Where a ticker has several legitimate claimants, the verdict degrades to "more than one project uses this ticker, check the address yourself."
That gate exists because the first version did not have it, and was wrong twice on a single page. It flagged Milady Cult Coin, its own project with several million in liquidity and trading since December 2024, for not being Cult DAO. It flagged the wojak token doing $202k a day for not being the Wojak Coin doing $5.5k a day, calling the more actively traded asset the fake. Neither was impersonating anything. Both tickers simply have two real claimants, and the canonical holder of a ticker is a curator's assignment rather than a fact. A measurement layer that cannot tell those two situations apart should not be issuing verdicts on either.
What this does not show
Nobody appears to have fallen for it, and that is worth stating precisely because it is stronger than the usual "no victim flow was traced". Reading every swap on four of the pools, the counterparty is always the wallet that deployed the token: 100 of 100 on the fake DAI pool, 99 of 99 on CRV, 93 of 93 on SHIB, 77 of 77 on COMP. In six months these pools have had no external participants at all. The contracts are live, findable and misrepresented, and so far the only person trading them is the person who made them.
Nor is "one operator" established. The two deployer wallets each service only their own tokens, and they are not linked. Both were touched early by the same address, which looked like a possible controller until it was read: it sends one identical 514 byte message to each of 2,996 distinct recipients, and the message decodes to a freelance designer advertising branding work to token deployers. It is unsolicited marketing, not a funding link.
The two deployer accounts were not deanonymised. The MintBurnTeamToken label comes from public contract metadata and was not independently source verified. Pool economics were measured on six pools and the daily schedule on four; the other 999 contracts are confirmed by bytecode and ticker, not by reading each one's pool.
Every number above was read directly from Ethereum mainnet via eth_getCode, eth_call, pool state and swap logs, or from the public DexScreener and Blockscout APIs, on 2026-09-01 and 2026-09-02. Prices move and pools can be removed, which is why the measurements are timestamped.
Why it matters
Verification and indexing are different jobs, and conflating them scales badly. An indexer that reports what a pool says about itself is not lying. It is faithfully reporting manufactured inputs. The gap between reported and real is where the work is, and closing it takes ordinary discipline: read the underlying state directly, key your joins on identifiers instead of labels, and be willing to return "I do not know" instead of a confident wrong answer.
Fabrication is getting cheaper. Seven ten-thousandths of an ETH bought a $3.28 billion listing that survived six months on a major discovery surface. Independent verification gets more valuable in exact proportion.
Top comments (0)