A native Pi payment carries no observable per-unit mining origin on the Pi Mainnet ledger.
You receive 10 π from an exchange. Later you receive 100 π that you mined yourself. They sit in one wallet. Someone claims the exchange π has “tainted” the wallet — that the taint has spread to the mined π, so that anything you now send is partly tainted.
A note on direction — this is deliberately the inbound case.
The questionable π arrives into your wallet from the exchange’s address (a withdrawal). That is the harder direction, and it is the one used here. Sending to an exchange would only add a second account-level fact — your address appears on the exchange’s inbound side — and would not change a single line of the argument below.
Direction is a property of the transaction. No unit has a direction, because there is no unit for a direction to attach to.
This is the most intuitive-sounding of all the objections, because “contagion” is a real pattern in the physical world: dye spreads in water, rust spreads through metal, a disease spreads on contact.
The question is whether it spreads in a ledger. It does not — for two independent reasons, either of which is sufficient on its own.
Contagion requires two things:
The Pi Mainnet ledger supplies neither.
The ledger state for the native asset is:
bal(account, native) -> a non-negative integer
That is the entire state. There is no taint field, no tag list, no origin vector, no set of previous
holders attached to a balance. A payment is:
bal(S) -= a ; bal(D) += a
Pure scalar arithmetic. Nothing is copied between accounts except the number a.
So the mark has nowhere to live, and there is no rule that could move it. The contagion model does not merely fail to apply — the objects it needs are absent from the data model.
This is the same argument that defeats every “origin” claim, applied to a different word. There is no
originfield to be wrong about, and there is notaintfield to be spread around. Changing the vocabulary does not add a field to the ledger.
Assume for the sake of argument that taint exists. Now make it concrete:
| You mined | 100 π |
| You withdrew from an exchange | 10 π |
| Balance | 110 π |
You send 10 π to a merchant. Which 10?
| Rule | Would send | Resulting taint |
|---|---|---|
| FIFO (first in, first out) | the 10 mined π | merchant receives “tainted” π |
| LIFO (last in, first out) | the 10 exchange π | merchant receives “clean” π |
| Largest first | 10 of the mined π | merchant receives “tainted” π |
| Random | either | either |
The ledger endorses none of these. It does not record the order of inflows for spending purposes, it does not track “lots”, and it does not know which units are which. It simply subtracts 10 from 110 and stores 100.
This is not a gap that better analytics would close. To make taint computable at all, the ledger would have to maintain per-lot accounting — which is a UTXO model or an explicit lot register. Pi uses an Account/Balance model instead. The question “which coins did you send?” is not unanswered; it is undefined, because there are no “which coins”.
This is exactly the well-known problem of tracing the US dollar. A dollar that passed through a ransom payment is not observably different from any other dollar, and no rule exists to say which dollar you spent. Fungibility is what makes that question ill-formed — and it is the same reason it is ill-formed here.
This is the most plausible-sounding form of the objection, and it fails for a precise reason:
Dilution presupposes prior segregation. To dilute something, there must first have been separable parts that later got mixed.
An Account/Balance ledger never had those parts. Your balance was never a stack of labelled lots that exchange-π then invaded — it was a single integer from the first π you received, and it remains a single integer. Nothing was commingled, because nothing was ever separate.
So “dilution” quietly imports a UTXO or lot-register model that this ledger does not have. Granting the word would grant exactly the per-unit structure whose absence is the entire point.
And notice the symmetry with the table above: “which 10 of the exchange’s balance came to you?” is just as undefined as “which 10 of your balance did you send?” — the exchange’s balance is a scalar too, and it has no lots either. Direction changes nothing.
What is true is narrower, and Part D already concedes it: you received π from an address that can be labelled as an exchange. That is an account-level fact. It attaches no property to units.
Now take the contagion rule seriously and follow it to the end.
Say taint spreads on contact: A is tainted → A pays B → B is now tainted → B pays C → C is tainted.
The Pi network is heavily connected, and exchanges are pervasive counterparties. Follow the rule forward:
exchange → you → merchant → their supplier → …
Every hop propagates the mark. After enough hops — which for a widely-used asset is a short number of hops — every π in existence is tainted.
And here the argument collapses under its own weight:
A property that everything possesses distinguishes nothing.
If all Pi is tainted, then “tainted” partitions the set into {all} versus {}. The label carries zero
information. It cannot separate one coin from another, because there is no unmarked remainder to compare
against. Calling some Pi “tainted” would be like calling all water “wet” — true, and useless as a
classification.
| If taint is… | then… | consequence |
|---|---|---|
| non-transitive (stops at your wallet) | it dies at the first commingling | Part B: it cannot be allocated to any specific unit |
| transitive (spreads on contact) | it reaches every Pi in existence | Part C: it is universal, therefore vacuous |
There is no consistent third option. Either taint fails as a measurement or it fails as a distinction. Both roads end at the same place: no per-unit property, no difference.
It would be dishonest to stop at Part C, because something adjacent is real.
Address-level flagging works — and it is why AML works at all.
If an address is publicly labelled (a sanctioned entity, a known illicit service), an exchange can and does freeze funds reaching it. That is a genuine, enforced mechanism. But notice precisely what it operates on:
| What it acts on | Is it a per-coin property? | |
|---|---|---|
| Address labelling | an account | ❌ No |
| Chain analysis | accounts and transaction edges | ❌ No |
| KYC / AML records | a person’s identity | ❌ No |
| The ledger | a scalar balance | — has no per-coin property at all |
So the honest statement is:
The mark attaches to who you are, not to what you hold. Those are different things, and conflating them is the entire error this page addresses.
Full treatment of the account-level boundary: FAQ-RECIPIENT-CANNOT-TELL.md §3.
Zero dependencies, read-only, GET only. No wallet, no passphrase, no keys, no signing.
node examples/mixing-check.mjs # live Mainnet read
node examples/model-check.mjs # 2 000 randomised histories
node examples/exhaustive-check.mjs # every history over the model
What each layer shows for this objection:
| Script | Result | What it establishes here |
|---|---|---|
mixing-check.mjs |
✅ live Mainnet, exit 0 |
Real inflows from different counterparties collapse into one number. The full outgoing payment record contains no origin/taint field. |
model-check.mjs |
2 000 seeds — 2 000 non-injective | No random history reconstructs per-unit origin. There is no hidden arrangement to be contaminated. |
exhaustive-check.mjs |
1 452 histories, 204 groups — 2 passed, 0 failed | Every possible history in the model yields one state and one view. Exhaustive, not sampled. |
The mixing-check.mjs output states the mechanism directly:
The ledger state is bal(account, native) -> a non-negative integer.
A payment does: bal(S) -= a ; bal(D) += a (purely scalar math).
The state has NO per-unit identity. 'Which coin did I send?'
is therefore NOT A QUESTION the ledger can answer — it is undefined.
❌ Do not say: “All Pi tokens were created at the same time, so they cannot have different origins.”
This is factually false and it will be used against you. Mined π is created over time as miners earn it — units genuinely have different creation times, and the ledger records transaction timestamps.
The claim does not need it, and is better without it. The sound premise is different and simpler:
✅ There is no origin field, and the balance is a scalar.
Creation-time differences do not produce provenance tracking. A ledger that records when a transaction happened is not a ledger that records which units moved. Timestamps are properties of transactions, not of coins — which is the same distinction the whole repo rests on.
Proves:
Does not prove:
Claims A / B / C in full: SCOPE.md.
Exact pinned revision of every source: SOURCES.md §0.
Back to the FAQ index · repository