Fees
The one number
The fee is 1.5% of every swap, buy or sell, plus 0.1% that is automatically returned to the pool as locked liquidity — so the total charged in-swap is 1.6%, and that total is what a quote from the V4 Quoter already reflects. Never subtract anything again when displaying an expected output.
There is no separate token tax, and nothing else is deducted anywhere.
These are the standing rates. For the first ten seconds of a pool's life an anti-snipe schedule opens at 80% and decays down, and the rate is per-pool configuration rather than a protocol constant. Always quote. See Liquidity layer.
Nothing to integrate
Because the fee is taken at the pool level, there is no fee step in your integration — nothing to collect, route, register or account for, and no way to accidentally skip it. A swap sent through the Universal Router, or through any other path into the pool, pays the same fee before the trader receives their output. Fee accrual and distribution are handled entirely by the protocol's own contracts.
Fees fund the agent's creator, the agent's own treasury (capital the agent itself uses), and the protocol. The creator-side split is configurable at launch. From an integrator's perspective this is background: it never changes what a trader pays or what your swap needs to encode.
The one fee fact your indexer needs
The total is charged as two legs by two different mechanisms, and only one of them is visible to Uniswap's own accounting:
LP leg
0.1%
The Swap event's fee field
Hook leg
1.5%
Hook deltas — never in Swap.fee
So Swap.fee reads 1000 (0.1%) on a normal trade — displaying it as the trading cost understates by 16x. Use the quoter for cost; the split above is only there to explain why that field looks wrong.
Reconstructing what a trade actually cost
There is no per-swap fee event, and per the table above neither Swap.fee nor amount0/amount1 tells you the trader's real rate.
For a live or pending trade, the quoter is exact and cheap: quoteExactInputSingle is already net of both legs.
For a historical trade there are two options, both with costs worth knowing up front:
Token transfers. Sum the
Transferlogs to and from the taker in that transaction. This gives what they actually paid and received, and needs no archive node — but you must identify the taker first, which is the transaction'sfrom, notSwap.sender.Re-quote at the block. Simulate
quoteExactInputSingleat block N−1 and compare. Exact, but needs an archive node and one call per trade.
If you only need a fee column rather than per-trade precision, showing the pool's standing rate is reasonable — provided you do not present it as measured, and you handle the first ten seconds of a pool's life separately.
What the chart shows: two small sells after every buy
On any trade feed you will see each buy followed by two small Sell rows from 0x4e3468…a544. That is the fee engine executing in-swap, not holders exiting:
First sell
~1.4% of the buy
The revenue fee, taken on the buy's token output and converted to the numeraire immediately — this is why creators and the protocol earn ETH (or the paired stock) instead of decaying tokens.
Second sell
~0.05% of the buy
The auto-compound rebalance: half of the compound slice is converted so both sides can be re-added as full-range, protocol-owned liquidity.
On sells the fee is taken from the numeraire output directly, so there is no conversion row — you may instead see a tiny hook buy when the compound slice rebalances the other way. The math reconciles to the pool's standing rate to the basis point; treat these rows as protocol activity when rendering feeds.
Last updated
Was this helpful?

