THE MATH.
No black box. A wallet's record is rebuilt from what the chain says happened, in six steps, and every figure on screen comes out of them. Here is each one, with its formula and where it is only an estimate.
00Where this started
At first I wanted WGG to talk to the blockchain directly: my own nodes, reading every block back to block zero. It turns out that is far too complicated, and far too expensive: a cluster indexing every transaction ever made, and the price of each one, just to answer "what did this wallet do?".
Then I came across Alchemy, whose getAssetTransfers answers that exact question in a single request. I built on it, and the foundations of the project became enormously simpler.
The next challenge was the dollar value of each transaction. A transfer says how many tokens moved, not what they were worth, so the prices come from CoinGecko.
It helps to know what that price is. CoinGecko does not quote one exchange: it takes a token's most traded pairs across every venue it tracks, centralized exchanges and the liquidity pools of decentralized ones alike. It drops the pairs that have gone stale, the pools too thin to trust and the prices that stray from the pack, then it averages what is left, weighted by volume. A pool counts for as much as the trading that goes through it. So a figure here is the market's consensus price, not the exact rate of your swap. That is why, when a transaction prices itself, that is used first.
The last one was a token's price history: what it was worth on the day you bought it, years ago. For that I paid for CoinGecko's $100 plan, which opens ten years of history, ran the most popular tokens through it, and kept the result on my side. That archive is what the "daily close" below is read from.
Gaël
01Every transfer becomes a priced leg
A scan reads every transfer in and out of the address, tokens and the native coin alike, and gives each one a dollar value at the time it happened. Where that price comes from is kept with the leg, because not all prices are worth the same:
| SOURCE | WHAT IT IS | RELIABILITY |
|---|---|---|
| Counterparty leg | What was paid or received in the same transaction. A swap prices itself. | Exact |
| Daily close | The asset's closing price for that UTC day, from the price archive. | Approximate |
| Peg | A stablecoin counted at $1. Wrong during a depeg. | Assumed |
| Last observed swap | The last trade seen on a token no market quotes. | Estimated |
| None | No price at all: the leg is left out of the totals and flagged. | Excluded |
Tokens screened as scam airdrops are left out of the totals too, and counted separately: a fake token "worth" millions should not move your P&L.
02Fees go into the basis
What you paid for a token is not only its price. The network fee of the transaction that bought it is part of its cost, and the fee of the one that sold it comes off what the sale brought in.
cost basis = value acquired + fee paid to acquire it net proceeds = value sold − fee paid to sell it
That is why the P&L here is usually lower than the one a price chart suggests: the chart never paid gas.
03Lots are matched first-in, first-out
Each acquisition opens a lot: a quantity and what it cost. Each disposal eats into the oldest lots still open, in order, until its quantity is covered. The gain banked is what the sale brought in, less the basis of the lots it consumed.
realized P&L = net proceeds − basis of the lots consumed (oldest first)
- Quantities are matched in whole integer units of the token, so a closed lot is exactly empty, not empty to nine decimals.
- FIFO is recomputed whole for a token whenever its history changes: one older purchase found late reorders everything after it.
- A disposal no lot covers (tokens sold that the record never saw arrive) is flagged on its own row rather than hidden in the total.
04What is still held is marked to the live price
The lots still open carry the basis that remains. Against the current price, that gives the unrealized side:
market value = quantity held × live price unrealized P&L = market value − basis of the open lots
A token with no price counts for nothing on either side, and is listed as unpriced instead of being shown at $0.
05Gas is estimated first, then measured
A Bitcoin or Solana transaction carries its fee, so those are exact from the start. On Ethereum the fee is on a receipt that has to be fetched one transaction at a time, the slow part of a scan.
So the record opens with an estimate: transactions are grouped by year and kind, up to 12 receipts are read per group, and their average stands in for the rest. The real receipts keep arriving in the background and replace the estimate one by one. Until they are all in, figures print with a ~ and the grade with a ?: an error bar that tightens, not a guess that flips.
06The grade is four scores, weighted
Each component is scored from 0 to 100 on the wallet's own record, with no comparison to other wallets, and the grade is their weighted average.
| COMPONENT | WEIGHT | SCORE |
|---|---|---|
| Exit timing | 35% | What your sales brought in, against what the same tokens would be worth today. Selling at half today's price scores 50; selling before a fall scores 100. |
| Network fees | 25% | Lifetime fees as a share of all the capital ever deployed. 0% scores 100; 10% or more scores 0. |
| Held through the dip | 25% | How far what you hold has come back from its worst point. At the trough it scores 0; at 1.5× the trough, 58. |
| Concentration | 15% | How spread the cost basis is. One asset scores 30; four in equal shares, or better, score 100. |
exit timing = 100 × proceeds ÷ value if held (100 if the sale beat holding) network fees = 100 × (1 − (fees ÷ capital deployed) ÷ 10%) held the dip = 100 × √(1 − worst value ÷ current value) concentration = 30 + 70 × min(1, (1 − Σ share²) ÷ 0.75) grade = Σ score × weight ÷ Σ weight
| A | B | C | D | E | F |
|---|---|---|---|---|---|
| 90+ | 75–89 | 60–74 | 45–59 | 30–44 | 0–29 |
- A component with no data (nothing sold yet, no price series) is dropped and the remaining weights rescaled. Missing data is not a zero.
- While gas is still estimated, its uncertainty carries into the grade in proportion to the fees component's weight: that is the ? after the letter.
- A stacked portfolio is graded on its pooled amounts, not on an average of its wallets' grades.
07What this is not
It is a FIFO reconstruction from public chain data, for understanding where the gains went. It is not a tax report: your jurisdiction may require another method, and nothing here knows what happened off-chain, on an exchange, or in another wallet.