This is an adapted excerpt from Chapter 6 of my book, The DeFi Data Quick-Start: Reading On-Chain Truth with Dune Analytics. The book goes from your first Dune query to a dashboard you can defend. This chapter is the hardest problem in it.
The one field that isn’t there
A row in dex.trades tells you the chain, the venue, the tokens, the amounts, and the transaction hash. It tells you everything except the one field half the money in DeFi wishes existed: where the trade came from. No origin: uniswap-web-app, no frontend: metamask-swaps, nothing.
That missing field is worth a great deal. Incentive programs, business development deals, and market-share claims all hinge on an answer nobody can read directly off the chain. Reconstructing it is the discipline called attribution, and it is mostly a matter of knowing where to look.
Two identical rows, two different worlds
Consider two rows from dex.trades: same day, same pool, each a swap of 2 WETH for USDC minutes apart. In the curated table they are nearly indistinguishable.
Behind the first is a person. She opened her wallet app, tapped the built-in swap button, and accepted a quote. Her wallet’s backend called an aggregator, the aggregator picked the route, and the trade settled through a router into the pool. Four parties touched that flow, and if anyone deserves credit for bringing the user, it is the wallet whose button she tapped.
Behind the second is a bot: a market-making program calling the pool contract directly. No frontend, no human, no quote, just an automated rebalancing loop.
A volume dashboard counts these two rows identically. An incentive program that rewards “adoption” pays them identically. Attribution is the work of telling them apart, at scale, from public data alone.
Why the obvious answers are wrong
The chain gives you two address fields per transaction, and it pays to see exactly why neither answers the question.
tx_from is the wallet that signed the transaction. It tells you who traded, not which interface brought them. Ten thousand different tx_from addresses might all be customers of a single wallet app.
tx_to is the first contract the transaction called. This is the field naive dashboards actually use, and it systematically credits the wrong layer. It names the router, the plumbing, not the frontend. Every trade through a given aggregator’s contract shows the same tx_to, whether the user came from the aggregator’s own site, a wallet’s swap tab, or an integration none of us has heard of. Attributing by tx_to is like attributing retail sales to the delivery truck.
The true origin, the app or interface where the user actually was, usually never appears on-chain as an address at all. It has to be inferred from the shape of the transaction. Different origins leave different fingerprints. There are four kinds in practice, and the first is nearly free when it is present.
When the trade signs its own work
Sometimes a transaction carries more than the trade itself. A few APIs append a few identifying bytes to the end of the call data: a tag the contract never reads, riding along to say “this order was built by integration X.” The 0x API’s affiliate suffix worked this way. Others pass the integrator as an explicit argument that the contract decodes, the way 1inch’s referral parameter routes referral fees. Both land on-chain, permanently, in every block explorer.
Where these tags exist, attribution is one join away: extract the marker, join to dex.trades on the transaction hash, and map tags to names. Here is the appended-tag form as a runnable probe. It ranks the most common 16-byte call-data tails across a few hours of Ethereum DEX flow:
with tails as (
select
bytearray_substring(
tx.data,
bytearray_length(tx.data) - 15,
16
) as calldata_tail,
t.tx_hash,
t.amount_usd
from dex.trades t
join ethereum.transactions tx
on t.tx_hash = tx.hash
and tx.block_time >= now() - interval '6' hour
where t.blockchain = 'ethereum'
and t.block_time >= now() - interval '6' hour
and bytearray_length(tx.data) >= 16
)
select
calldata_tail,
-- tags ride on transactions, not fills
count(distinct tx_hash) as txs,
sum(amount_usd) as volume_usd
from tails
where calldata_tail
<> 0x00000000000000000000000000000000
group by 1
order by txs desc
limit 25
Run it and the tagging convention stares back at you. The query drops the all-zero tail up front, because that bucket is mostly untagged flow and call data that ends in zero-padded arguments. What remains is candidates. When I ran this in July 2026 while drafting the book, one high-frequency tail held the hex spelling of a short ASCII name with a counter beside it: an integrator marking its own orders in plain sight. Run the probe yourself and you will find it, or whoever is tagging this month.
One caution before you attribute anything to a tail. It can also be the end of an ordinary function argument, since token addresses produce repeating fragments too. Treat a candidate tag as a hypothesis. Pull a handful of its transactions, check the entry contract, and confirm the pattern holds across several days before it earns a name.
The real limit is the word voluntary. Tagging is a convention some APIs offer and some integrators use. It is not a standard, and it is not enforced. Absence of a tag is not evidence of absence of a frontend. A system that counts only tagged flow will undercount exactly the integrators who never opted in, and overstate the “direct” share by the same amount.
The other three techniques, in brief
When a trade carries no tag, three more techniques pick up the flow:
- Known-contract registries. Routers, aggregator entry points, wallet swap contracts, and custom proxies all have stable addresses. Label one once, and every past and future trade through it becomes attributable retroactively. A single proxy label can reclassify millions in volume. This is why ClearTrace tracks over 172,000 attributed contracts across Ethereum, Base, Arbitrum, and Optimism: the unlabeled long tail is where misattribution hides.
- Trace fingerprints. The internal call tree has a shape. A protocol’s own frontend produces a compact tree, a wallet-native swap adds a fee hop and an extra transfer, an aggregator split fans across several pools, and a bot calling the pool directly shows almost no tree at all. No single shape is definitive, but across thousands of transactions from one entry point they classify with high confidence.
- Fee-recipient clustering. Most frontends skim a small fee to a collection address as part of the swap. That address is a signature: every trade paying the same recipient came through the same integration, named or not. I wrote a full walk-through of this one on its own, Who Got Paid: Identifying Anonymous DEX Frontends by Their Fee Recipient.
The part most dashboards skip
The four techniques combine into a cascade, strongest evidence first. One sensible ordering: explicit call-data tag, then registry match, then trace fingerprint, then fee-recipient cluster. A real system tunes that order to its own confidence in each signal, and screens out known bot and MEV contracts before classifying anything. And then the step that matters most:
If none of them fires, leave the trade unattributed.
That is the design, not a failure mode. A neutral attribution system reports its unattributed share instead of forcing every trade into a bucket, and it treats that residual as a headline number about its own coverage. When you see an attribution chart that sums to a clean 100% with no “unknown” slice, you are looking at a method that either got very lucky or made something up. No serious system attributes everything; a real one measures its own coverage and reports the gap.
So here is ClearTrace’s gap, for the record. As of August 2026, roughly 10% of DEX volume across Ethereum, Base, Arbitrum, and Optimism sits in the unattributed bucket, ranging from 8% on Ethereum to 17% on Optimism. The shape underneath is the interesting part: nearly 99% of tracked contract rows are unnamed, while nearly 90% of volume is named. The head is easy. The long tail is the job.
State the method, show the denominator, publish the residual.
The DeFi Data Quick-Start is on Amazon now, in Kindle and paperback. The book’s runnable queries and a live dashboard are on the free companion page at rantum.xyz/quickstart.