Most articles about phantom gains, including ours, explain the mechanism and stop there. This one runs it on a real wallet cluster and publishes the number.

We took the most public address cluster on Ethereum — vitalik.eth plus the Etherscan-tagged VB, Vb 2 and Vb 3 addresses and one media-documented cold wallet — and computed realized gains on its native-ETH history twice. Same engine, same data, same classifications. The only difference between the two runs: whether transfers between the entity's own wallets carry their cost basis, or lose it.

Losing it is what per-wallet tools do when they don't link the wallets together. On this cluster it overstates lifetime realized gains by $44,975,739.

realized gain (genesis → 2023-03-31)
naive per-wallet tool (transfers lose basis) $164,130,459
transfer-aware $119,154,719
overstated "phantom" gain $44,975,739

To be explicit about what this is and isn't: this is a measurement of how two ways of handling self-transfers diverge on one public dataset. It is not a claim about anyone's actual tax position, filings, or liability. We have no visibility into either. Every address here is identified by an on-chain ENS name, an Etherscan public name tag, or mainstream press coverage — there is nothing here that wasn't already public. This is not tax advice.

Why this cluster

We needed a subject that does the specific things that break naive tools, and that we could name without exposing anyone.

This cluster does all of them: multi-hop self-transfers (VB → vitalik.eth, VB → Safe → cold wallet), self-staking, WETH wraps, and large disposals years after the transferred coins were acquired. The five addresses:

address label how it's attributed
0xd8da6bf2…96045 vitalik.eth ENS name, on-chain
0xab5801a7…aec9b VB (legacy) Etherscan public name tag
0x1db3439a…a6ee6 Vb 2 Etherscan public name tag
0x220866b1…a3a9d Vb 3 (Safe) Etherscan public name tag
0xd04daa65…28fd7 cold wallet received 70,000 ETH from Vb 3 after a 1-ETH test send; widely reported

The moves that a per-wallet tool books at $0 basis on arrival are large and old:

date from to amount
2021-05-12 VB (legacy) Vb 3 (Safe) 320,000 ETH
2016-08-05 VB (legacy) Vb 2 100,000 ETH
2016-08-10 Vb 2 VB (legacy) 79,462.66 ETH
2022-11-24 Vb 3 (Safe) cold wallet 40,000 ETH
2022-05-16 Vb 3 (Safe) cold wallet 30,000 ETH

Coins acquired in 2015 and moved in 2016 get sold in 2021. A tool that lost the basis at the 2016 transfer prices that 2021 sale against zero.

The damage concentrates in two years

year naive transfer-aware overstatement
2016 $5,216,955 $5,065,243 $151,711
2017 $38,034,500 $37,728,650 $305,849
2018 $3,932,439 $3,793,849 $138,590
2019 $1,636,279 $1,533,193 $103,085
2020 $2,734,481 $2,627,965 $106,516
2021 $55,404,397 $32,238,166 $23,166,232
2022 $31,336,181 $10,476,703 $20,859,478
2023 $25,835,884 $25,691,607 $144,277

2022 is the clearest case. The naive run reports $31.3M of realized gains. Carry the basis correctly across the entity's own transfers and the same disposals come out at $10.5M.

Look at what happens at the level of individual disposals, and the sign flips:

date naive gain actual gain phantom
2021-12-14 $7,565,791 −$799,790 $8,365,581
2021-09-26 $4,413,005 −$1,860,762 $6,273,767
2021-07-01 $2,279,354 −$1,903,436 $4,182,790
2022-01-09 $2,318,839 −$818,254 $3,137,093

These are losses being reported as multi-million-dollar gains. That is the part worth sitting with: the error isn't a percentage off a large number, it's the wrong direction.

Why you can trust the arithmetic

A number this size is only worth anything if the ledger reconciles to the chain. Here is the balance tie-out at the cutoff block (16,950,600), with gas priced from each transaction's own receipt:

wallet ledger (ETH) on-chain (ETH) diff tie-out
vitalik.eth 5149.62524 5149.62524 0 PASS
VB (legacy) 59.41928 59.41928 0 PASS
Vb 2 7.904313 7.904313 0 PASS
Vb 3 (Safe) 244001.011354 244001.011354 0 PASS
cold wallet 50001.094312 50001.094312 0 PASS

Five of five wallets reconcile within 0.0001 ETH. The cutoff is deliberately before Shapella withdrawals began, so the native-ETH ledger is closed under transaction lists plus proposer fees — any residual would be a data defect, not an excuse.

The method, in short: 5,334 raw rows from the key-less Blockscout public API became 6,175 canonical events. Every one of the 2,671 transaction receipts was read for exact gas (gasUsed × effectiveGasPrice). Prices are DefiLlama daily closes. Validator deposits and WETH wraps are not sales. Safe delegatecall traces are dropped, because Blockscout reports them with the parent call's value and any pipeline that keeps them double-counts every Safe execution.

Two defects we found in our own pipeline

Both were producing an "ETH from nowhere" signature, and both invalidated every figure this analysis carried before 2026-07-29. We are publishing them because a tie-out that only ever passes is a tie-out nobody is testing.

Gas came from the explorer's indexed fields. Neither gasUsed nor gasPrice as indexed is the receipt value — gasPrice is maxFeePerGas under EIP-1559. Fees are modeled as mini-disposals, so a wrong fee is a wrong realized gain as well as a broken tie-out. Fixing it moved vitalik.eth from −0.685055 ETH to exactly zero.

Proposer income was cached as zero when the fetch failed. 270 of Vb 2's 627 proposed blocks were stored with a zero priority fee and a null timestamp, because rate-limited responses were read optimistically. They are real income: 4.29 ETH recorded against 7.16 ETH on chain. Repaired, Vb 2's difference fell from −3.04 ETH to −0.18 ETH.

What remains is contract-internal ETH that block explorers don't index per address. We bisected it to the block: VB (legacy) first diverges at block 13,787,699, where the on-chain balance rises by 0.0085 ETH with no transaction and no internal transaction returned for that address. Closing it needs trace-level ingestion — and one caveat we measured while testing that: trace_filter returns frames from reverted sub-calls, and counting them naively over-credited VB by 0.067 ETH. Trace ingestion has to prune every subtree under a reverted ancestor before it's an improvement.

What this means for a normal wallet

You almost certainly don't move 320,000 ETH between your own addresses. But the mechanism doesn't care about size, and two things make it more likely to hit you now than it used to:

Since 2025, Rev. Proc. 2024-28 requires per-wallet basis tracking rather than a universal pool. Per-wallet is exactly the mode in which an unlinked self-transfer looks like an acquisition at zero.

And Form 1099-DA reporting means brokers now send the IRS their own view of your disposals. Where a broker never saw your acquisition — because it happened in a wallet, on another exchange, or years earlier — the basis field is where the gap shows up.

The check is the same at any size: for each sale in your report, find the acquisition it was matched against. If the tool can't show you one, that line is priced against zero.


This is not tax advice, and none of the above is a substitute for a qualified tax professional looking at your actual records.

If you'd rather have the breaks in your basis chain found for you, Verilot Check reads your Ethereum wallets directly on-chain and flags every transfer between your own addresses that would otherwise be booked as a sale, with a tx-hash on every line. Free and read-only — no wallet connection, no sign-up, up to 5 wallets and 500 events per scan, Ethereum mainnet today. Run my free scan.