
Address poisoning: the attack that only needs you to copy the wrong thing
Most attacks on crypto users need you to make a mistake — click a link, type a seed phrase into a form, approve something you didn't read. Address poisoning needs less than that. It needs you to copy an address from your own transaction history.
There is no malware, no phishing site, no signature to trick out of you. The attacker's entire contribution is putting a plausible-looking string somewhere you will later reach for it.
How it works
Start with the thing that makes it possible: nobody reads addresses. A Bitcoin or Ethereum address is thirty-odd characters of base58 or hex with no meaning, no checksum you can eyeball, and no reason to hold in your head. So every wallet, block explorer and exchange shortens them for display — 0x8f3C…9A063 — and every user learns to check the visible ends and skip the middle.
That habit is the whole attack surface.
The attacker generates addresses by brute force until one shares the first few and last few characters with an address you actually use — usually one you've recently sent money to. This is cheap. Generating keypairs is fast, and matching, say, four leading and four trailing characters takes seconds on ordinary hardware. Nobody is cracking anything; they're just rolling dice until a number looks familiar.
Then they get that address into your history. The common methods:
Dusting. They send you a tiny amount — a few satoshis, a fraction of a cent of some token — from the lookalike address. It's an ordinary incoming transaction, so it lands in your history like any other. On UTXO chains the dust also becomes a spendable coin sitting in your wallet, which matters later.
Zero-value transfers. On EVM chains an ERC-20 transfer of zero tokens is a valid transaction. The attacker sends 0 tokens from your address to their lookalike, which some interfaces render as an outgoing payment you made. Your history now shows you apparently sending to an address you never chose.
Fake events. A malicious token contract can emit a Transfer event that never happened. Explorers and wallets that trust event logs will display it. Nothing moved; the record is simply a lie.
Then they wait. Days, sometimes months. The attack pays off the next time you go to pay the same counterparty, scroll your history for "the address I used last time," and copy the wrong row. Both look like 0x8f3C…9A063. You check the ends. The ends match.
Why the usual advice doesn't hold
"Always double-check the address" is the standard guidance, and by itself it fails, because checking is precisely what the attack anticipates. You did check. You compared the six characters your wallet showed you against the six characters in your memory, and they were identical — because the attacker made them identical.
Verification only works when what you compare is expensive to forge. Four or six matching characters cost seconds. Sixteen matching characters would cost more than the theft is worth. The whole game is which end of that curve your habits sit on.
There is a second trap on UTXO chains. That dust payment is now a coin in your wallet, and if your wallet consolidates inputs automatically, it can get swept into a later transaction — linking the dusted address to the rest of your coins, which is a privacy problem rather than a theft one, but it's the reason dust is worth ignoring rather than tidying up.
What actually defends against it
Never source an address from a transaction history. This is the single change that matters. Your history is a record of what happened, not a list of who you trust — and anyone in the world can write to it. Get addresses from the counterparty, over a channel where you'd notice an impostor, or from an address book you populated yourself.
Compare whole addresses, or compare something that summarises the whole address. Reading all forty-two characters is unrealistic. Comparing an identicon — a small image deterministically generated from the entire string — is not, because a lookalike differing anywhere in the middle produces a visibly different picture. Your eye does the work your patience won't.
Use a saved contact. An address you saved once, from a source you verified once, cannot be poisoned later. This is what address books are for, and it is why SSP keeps contacts on your device rather than on a server: a contact list is only trustworthy if nobody else can edit it.
Send a test payment for large or first-time transfers. Small amount, confirm receipt out of band, then send the rest. Fees make this annoying and it is still correct for a payment you'd hate to lose.
Ignore dust. Don't spend it, don't "clean it up," and be careful with automatic consolidation if you care about privacy.
What SSP does about it
Address poisoning is a rendering problem as much as a security one, so part of the answer lives in how addresses are drawn.
SSP truncates addresses with six leading and six trailing characters — 0x8f3C4b…9A0631 — rather than the three or four many interfaces use. That is not a cosmetic choice. Every extra character multiplies the brute-force cost of producing a match, and twelve visible characters puts a convincing lookalike well outside the range of casual generation.
The middle is de-emphasised rather than deleted. In the expanded form the wallet shows the full string with the ends bolded and the middle in a lighter colour, so the part attackers rely on you skipping is still physically present on screen instead of being replaced by an ellipsis that could be hiding anything.
The same code runs in both apps. splitAddressForDisplay in SSP Wallet is a direct port of the one in SSP Key, kept deliberately identical so that an address looks the same on your browser and on your phone. That matters because SSP shows you the transaction twice, on two devices — and a second look is only a real check if both surfaces render the same thing the same way. Two different truncations would let a discrepancy hide in the difference.
On SSP Key's approval screen, the recipient is shown with an identicon generated from the full address, alongside the truncated text, and tapping it expands the complete address as selectable text. The identicon is the part that defeats a mid-string swap: an attacker can match your leading and trailing characters, but they cannot match a picture derived from every character without solving a much harder problem.
None of this is a guarantee. If you paste a poisoned address and approve it on both devices, SSP will sign it — that is what it means to be a wallet you control rather than a custodian who second-guesses you. Two-of-two multisig stops someone else from spending your coins; it cannot stop you from paying the wrong person on purpose. Like every attack that works by getting you to act, the defence has to land before the signing, not during it. What the design can do is make the wrong address harder to mistake for the right one, and that is where the effort goes.
The short version
Address poisoning works because you compare six characters instead of forty-two, and the attacker knows which six. The defence isn't more diligence — it's never taking an address from a place an attacker can write to, and using tools that put the parts you'd skip back in front of you.


