Address poisoning detection
What is address poisoning detection?
Address poisoning detection is finding the transfers an attacker plants in a user’s history from an address that starts and ends like one the user has paid, and stopping the user from paying that lookalike by mistake.
An address poisoning attack leaves a few cents of the same token, a zero-value transfer that seems to come from the user, or a fake token, and it works because wallets often show only an address’s first and last characters.
Wallet apps and exchanges run this check because their users copy addresses from the history the app shows them, and a payment to the wrong address can’t be reversed: in May 2024, one holder sent 1,155 wrapped bitcoin, then worth about $68 million, to a poisoned address.
With Goldsky, you can stream your users’ token transfers through Turbo Pipelines and flag lookalikes as they land, or call the Feeds transfers API for a user’s past payments when they enter a destination.
Who uses address poisoning detection?
Self-custody and embedded wallet apps, wallet infrastructure providers, and crypto exchanges and custodians that check where customers withdraw to; alerts when your own wallets move large amounts are crypto wallet monitoring instead.
How address poisoning detection works
The diagram follows one poisoning attempt, from a user’s real payment to the warning that stops them paying the lookalike, and shows who does each step. Your setup may differ.
Ways to detect address poisoning
Streaming flags each poisoning transfer as it lands, so your app can hide it from history before anyone copies it; the transfers API checks one destination at send time against the user’s past payments, with nothing stored on your side.
- Best for
- Many user addresses, with poisoned entries hidden as they land
- Products
- Turbo
- What you run
- The destination: your database, queue or bucket, or a Postgres database Goldsky hosts
- What you write
- Pipeline YAML and SQL; TypeScript transforms when needed
- Where your data lives
- In your own database or systems
- How results reach you
- Pushed to you
- Best for
- A check in the send screen, with nothing stored
- Products
- Feeds
- What you run
- Nothing; you call an endpoint and keep what you need
- What you write
- REST requests
- Where your data lives
- Hosted by Goldsky
- How results reach you
- Returned when you call
| Usual setupOption 1: Flag transfers as they land | Option 2: Check at send time | |
|---|---|---|
| Best for | Many user addresses, with poisoned entries hidden as they land | A check in the send screen, with nothing stored |
| Products | Turbo | Feeds |
| What you run | The destination: your database, queue or bucket, or a Postgres database Goldsky hosts | Nothing; you call an endpoint and keep what you need |
| What you write | Pipeline YAML and SQL; TypeScript transforms when needed | REST requests |
| Where your data lives | In your own database or systems | Hosted by Goldsky |
| How results reach you | Pushed to you | Returned when you call |
List each user’s real counterparties
A lookalike only stands out against the addresses a user has paid on purpose.
Take them from what the user did, not from their history: addresses saved in their address book, and recipients of payments they signed in your app. A list built from the raw history already holds the attacker’s address once a poisoning transfer arrives.
Keep the lists live
Handled by Goldsky TurboUsers pay someone new every day, and attacks follow a new payment within minutes.
The check needs your users’ addresses, each user and counterparty pair, and a short fingerprint of each counterparty’s first and last characters joined to the user’s address, so one lookup can say whether an address imitates one of theirs. A fingerprint of a few characters at each end also catches lookalikes that match more of them. A list that changes only with a release leaves every payment made since then unprotected.
With Goldsky, each list is a Turbo Pipelines dynamic table, a lookup table in a Postgres database. Your backend inserts a row and the running pipeline matches it from its next batch, with no redeploy.
Learn about dynamic tables (opens in a new tab)A user pays a counterparty
Every payment onchain is public, and each one tells an attacker whom to imitate.
Attackers watch for transfers, often of stablecoins, and generate an address whose first and last characters match the recipient’s. A study of two years of Ethereum and BNB Smart Chain transfers found that poisoning usually follows within 20 minutes of the payment it copies.
Attacker plants a lookalike transfer
The fake entry in the user’s history is what they later copy by mistake.
It takes one of three forms: a tiny amount of the same token sent from the lookalike to the user; a zero-value transfer from the user to the lookalike, which many token contracts let anyone record through
transferFrom; or a fake token with the same name and amount. The last two make it look as if the user paid the lookalike themselves.Flag poisoning transfers
Handled by Goldsky TurboNearly every transfer into a wallet is real, so only the planted ones should be flagged.
Two rules need nothing but the transfer and the lists: a zero-value transfer touching a user’s address, and a transfer between a user and an address that shares a fingerprint with one of their counterparties but isn’t it. The second rule also catches tiny and fake-token transfers, as long as the counterparty being imitated is on the user’s list.
A Turbo Pipelines SQL transform reads the chain’s
Browse Turbo SQL functions (opens in a new tab)erc20_transfersdataset and keeps a transfer whendynamic_table_check()finds a user assenderorrecipientand eitheramount = 0, or the fingerprint key built withconcatandsubstringis in the fingerprint table while the full pair isn’t in the counterparty table.Record each flagged transfer
Handled by Goldsky TurboYour history and send screens read the flags, so they have to sit where your app can query them.
Store each flagged transfer with the user, the lookalike address, the token, the amount and the transaction, so support can show a user what happened. If a reorg (the chain replacing its newest blocks) drops the transfer, its flag has to go too, or a real payment can be hidden later.
Goldsky’s Turbo Pipelines writes the flagged transfers to a Postgres table keyed on each transfer’s
See how reorgs reach your database (opens in a new tab)id, so a repeated delivery overwrites the same row and a reorg’s deletes remove a dropped transfer’s flag.Hide poisoned entries from history
A user can’t copy an address they never see.
Your history screen leaves flagged transfers out, or marks them as suspected poisoning, and keeps them in a view the user can open. People sometimes send real zero-value transfers as tests, so keep hidden entries and let a user restore one.
Stop payments to lookalikes
The moment before the user signs is the last chance to stop the payment.
When a user pastes or picks a destination, check it against the flagged addresses and compare it with the user’s counterparties by first and last characters. On a match, block the send and show the real and fake addresses side by side; for an address the user has never paid, show a first-time warning. An exchange can run the same check on a withdrawal address before it signs.
What to know about streaming poisoning transfers to your database
- The lookalike rule needs each user’s real counterparties on the list; the zero-value rule works without them.
- Each transfer is checked against the lists as they stand when it arrives, so check a newly added counterparty against the user’s recent history too.
- Dust sent in a chain’s own coin comes from a separate native transfers source, on chains that record traces.
- Flags are keyed on each transfer’s ID, so a repeated delivery overwrites its row and a reorg removes the flag of a transfer the chain dropped.
A user pays a counterparty
Every payment onchain is public, and each one tells an attacker whom to imitate.
Attackers watch for transfers, often of stablecoins, and generate an address whose first and last characters match the recipient’s. A study of two years of Ethereum and BNB Smart Chain transfers found that poisoning usually follows within 20 minutes of the payment it copies.
Attacker plants a lookalike transfer
The fake entry in the user’s history is what they later copy by mistake.
It takes one of three forms: a tiny amount of the same token sent from the lookalike to the user; a zero-value transfer from the user to the lookalike, which many token contracts let anyone record through
transferFrom; or a fake token with the same name and amount. The last two make it look as if the user paid the lookalike themselves.Catch the destination at send time
The check has to run before the user signs, while the payment can still be stopped.
When a user pastes or picks a destination in the send or withdrawal screen, your app sends it to your backend with the user’s wallet address. Checking only addresses typed by hand misses the copied ones, which are the ones poisoning targets.
Fetch the user’s past payments
Handled by Goldsky FeedsA lookalike can only be spotted against the addresses this user has paid before.
Pull the wallet’s transfers across the chains you support and keep the recipients of outgoing payments made in real tokens with a real amount. Zero-value and fake-token transfers recorded from the user’s address weren’t sent by them, and counting them as payments makes the lookalike look trusted.
Goldsky’s Feeds transfers API returns one wallet’s native and ERC-20 transfers, newest first, with
Get a wallet’s transfers (opens in a new tab)direction, the counterparty andamount_rawon each row, and leaves out tokens Goldsky has no price for unless you setinclude_unknown_price=true.Compare with past payees
The comparison decides whether the user can pay without a warning.
A destination the user has paid before passes. One that shares its first and last characters with a past payee but differs in the middle is a lookalike, especially if its only history with the user is a tiny incoming transfer. One the user has never paid gets a first-time warning.
Stop payments to lookalikes
The moment before the user signs is the last chance to stop the payment.
Block the send and show the destination beside the past payee it imitates, so the user can see where the middle differs. Let a user who has checked the full address with the recipient go ahead, and record that they did.
What to know about checking destinations at send time
- Nothing is flagged ahead of time: poisoned entries stay in any history your app shows until the user tries to pay one.
- A zero-value transfer recorded from the user’s address appears as an outgoing transfer, so drop zero-amount rows before treating an address as a past payee.
- Tokens without a price source are left out by default, and that default matters: a fake-token transfer recorded from the user’s address would otherwise make the lookalike look like a past payee.
- The history is read fresh on each send, so a transfer a reorg removed stops appearing.
What you control
- Your team
- List each user’s real counterparties
- Hide poisoned entries from history
- Stop payments to lookalikes
Questions and answers
What is address poisoning?
Address poisoning is a scam that plants a lookalike address in your transaction history, hoping you copy it the next time you send. The attacker generates an address whose first and last characters match one you’ve paid, then records a transfer between it and your wallet: a tiny amount, a zero-value transfer or a fake token. If you copy that address instead of the real one, your payment goes to the attacker and can’t be reversed.
How does an address poisoning scam work?
An address poisoning scam starts with a payment you make onchain, which anyone can see. Usually within minutes, the attacker generates an address that starts and ends like your recipient’s and records a transfer with your wallet: a few cents of the same token, a zero-value transfer from your address, which many token contracts let anyone record, or a fake token for the same amount. Your history now shows the lookalike as if you’d paid it before.
How do you prevent address poisoning?
Copy each destination from your address book or its original source, never from your transaction history, and check every character of it, including the middle. A small test payment doesn’t help on its own, because the test can trigger a new poisoning. Wallets and exchanges can hide suspected poisoning transfers, show more of each address, and block a pasted address that resembles one the user has paid but isn’t it.
Is address poisoning the same as a dusting attack?
No, though both use tiny transfers. A dusting attack sends small amounts to many addresses to trace who owns them or to advertise a scam token. Address poisoning sends tiny, zero-value or fake-token transfers from a lookalike address so that you copy it, and it causes the larger losses. Hiding unwanted tokens is spam token filtering, which doesn’t catch a poisoning transfer made in a real token.
Can you get crypto back after an address poisoning scam?
Usually not. An onchain payment can’t be reversed, so recovery depends on the attacker returning the funds or the token’s issuer freezing the attacker’s address before the money moves. The holder who sent 1,155 wrapped bitcoin to a poisoned address in May 2024 got the value back days later, after investigators published leads on the attacker. Report a theft to the token’s issuer and the authorities as soon as you notice it.
Security and deployment
- SOC 2 Type IIIndependently audited security controls.
- Dedicated infrastructureSingle-tenant options for production workloads.
- Data residencyCloud, on-premises or co-located.
More use cases that monitor transactions
- Compliance monitoringScreen wallets and transfers, watch for misuse of your assets and feed your AML and surveillance tools.
- Securities surveillanceScreen wallets and transfers, watch for misuse of your assets and feed your AML and surveillance tools.
- Crypto wallet screening and sanctions dataFlag transfers that touch sanctioned or high-risk addresses.
- Secondary-market sanctions sweeps for token issuersScreen every holder and transfer of your stablecoin, not only your direct customers.
- Data for crypto AML transaction monitoringFeed complete transfer data to AML tools with lineage from the chain to the case.
- Unauthorized tokenization monitoringFind tokens that claim to represent your security without your consent.
- Smart contract and wallet monitoringWatch your contracts and wallets for attacks and unexpected changes.
- Blockchain forensics data feedGive investigators full history and traces across chains.
- VASP and counterparty due diligence dataProfile a VASP, issuer or counterparty by its onchain exposure before onboarding it and while the relationship lasts.
- Crypto source of funds and wealth checksTrace where a client’s onchain funds came from to document legitimate wealth at onboarding.
- Token listing due diligence for exchangesCheck a token’s supply, holders, liquidity and risky links before an exchange lists it, and after.
- Crypto scam and money mule detection dataFlag payments to scam-linked wallets and customer accounts that act as money mules.
- Crypto wallet monitoringGet an alert when a watched wallet makes a large transfer, crosses a balance limit, wakes after dormancy or pays an unknown counterparty.
- Onchain supervisory monitoring for regulatorsGive examiners one view of licensed firms’ onchain activity to test against what the firms report.
Use cases built the same way
- Stablecoin wallet top-upsCredit a user’s app balance when a stablecoin transfer to their embedded wallet confirms.
- Authorize and capture stablecoin paymentsHold a buyer’s stablecoins in an escrow contract at checkout, capture them to the merchant as orders ship, void what can’t be filled and refund after capture.
- Stablecoin dollar accountsOffer dollar accounts held in stablecoins, with balances and history kept in step with the chain.
- Stablecoin deposits to business bank accountsDetect stablecoin deposits into business bank and fintech accounts and post them to the account alongside fiat.
Detect address poisoning with Goldsky
We’ll map it to your systems and show you what Goldsky runs, so your team builds the product, not the pipelines underneath it.