Skip to main content

The Fee That Never Was: USDT's Ghost Mechanism Runs in Every Block

· 4 min read
Aubury Essentian
Ethereum Research

Buried in the USDT contract source code is a comment that reads: "additional variables for use if transaction fees ever became necessary." Beneath it: basisPointsRate = 0 and maximumFee = 0. Both initialized to zero. Never changed. The fee mechanism was coded in 2017 in case Tether ever wanted to charge for transfers. They never did.

But the code that reads those variables runs on every USDT transfer. And USDT transfers happen in virtually every Ethereum block.

Here's what that looks like in the raw execution trace data. Querying canonical_execution_storage_reads — a table that records every storage slot accessed during block execution — against 30 days of mainnet history:

SELECT 
contract_address,
slot,
count() AS total_reads,
count(DISTINCT block_number) AS blocks_present,
round(count() / count(DISTINCT block_number), 1) AS avg_reads_per_block
FROM canonical_execution_storage_reads
WHERE meta_network_name = 'mainnet'
AND block_number >= 24475000
AND block_number <= 24555000 -- ~30 days, ~79,743 blocks
GROUP BY contract_address, slot
HAVING blocks_present >= 72000
ORDER BY total_reads DESC

The result is stark. USDT's four core storage slots — owner address (slot 0), basisPointsRate (slot 3), maximumFee (slot 4), and a deprecation flag (slot 10) — are present in 79,743 out of 79,743 blocks. Not 99.9%. Not 99.99%. Every single block in the window.

5.1 million reads of the deprecation flag. 5.0 million reads of the fee rate. 5.0 million reads of the fee cap. All returning zero.

USDT storage hotspot chart

The read intensity column tells the rest: 64 reads per block of the deprecation slot, 62–63 reads per block of the fee slots. That's roughly 62 USDT transfers happening per block, every block, each one checking the same three parameters before proceeding.

The check isn't optional. The USDT transfer function always calls calcFee, which reads basisPointsRate and maximumFee, computes fee = (value × basisPointsRate) / 10000, and caps it at maximumFee. Since both inputs are zero, fee is zero. The transfer proceeds, fee-free, as it has since 2017.

The cost isn't zero, though. Under EIP-2929, a cold SLOAD costs 2,100 gas. Each USDT transfer starts fresh — no warm cache carries over between transactions — so it pays for three cold reads on the fee slots: roughly 6,300 gas per transfer just to confirm the fee is nothing. Across 62 transfers per block and 7,200 blocks per day, that's about 2.7 billion gas per day spent on this confirmation. Equivalent to roughly 45 full Ethereum blocks of capacity, daily, answering the same question with the same answer.

USDC is almost as universal, appearing in 99.99% of blocks with ~42 reads per block. But USDC's pattern is different: it's a proxy contract, and two of its hot slots (0x7050... and 0x10d6...) are mapping-derived addresses — almost certainly the token balances of specific high-volume DeFi addresses (major Uniswap pools or similar) being read constantly by routing logic. Those slots change frequently as liquidity moves. The USDT fee slots never change at all.

The Uniswap V3 USDT/ETH pool (identified as 0xc7bbec68... on Etherscan) adds another tier: present in 91.8% of blocks, with 3.9 reads per block. This is its pool state slot — the packed struct containing the current price, tick, and liquidity — read whenever any transaction needs the current exchange rate for routing. Dynamic, meaningful data.

Then there's the USDT fee slots: static, zero-valued, and inescapable.

This has a practical consequence for any parallel EVM scheme. Optimistic parallelism works by speculatively executing transactions simultaneously and detecting conflicts after the fact. Two transactions that read but never write the same slot can usually coexist — no conflict. But transactions that both read and write the same slot must be serialized. USDT fee slots are read by every USDT transfer and never written — they're pure read-only at this point, which is actually fine for parallelism. The deeper bottleneck is the per-validator balance slots, the isBlacklisted mapping, and other USDT state that IS written per-transfer. But the fee slots illustrate a broader point: specific storage locations in Ethereum don't just have high access frequency — they have structural, inescapable access frequency that no optimization can route around without redeploying the contract.

Tether can't upgrade USDT without migrating all liquidity, integrations, and institutional custody arrangements. The fee mechanism is permanent. So is the gas it consumes.

Every block, somewhere between 60 and 65 Ethereum transactions ask: "Is the USDT fee rate non-zero?" Every block, the EVM reads the answer from storage and says: no.

Data: canonical_execution_storage_reads (xatu, 30-day mainnet window, blocks 24,475,000–24,555,000) · Contract source: Etherscan USDT