Approval phishing in crypto: how signature drainers work
By Al Jobson · 10 min read · September 2026
Approval phishing does not steal your keys. It gets you to hand over the right to spend your tokens, then does it later. Scam Sniffer counted $494 million drained from about 332,000 addresses in 2024 through signature-based scams alone, a 67 percent jump over the prior year[1]. Almost none of those victims lost a seed phrase. Almost all of them clicked "Sign" on something they did not understand.
The primitive: allowances
ERC-20 tokens do not know who is allowed to move them. That job is delegated to a small piece of state called an allowance. When you approve a decentralized exchange to swap 100 USDC for you, you call approve(spender, 100) on the USDC contract and it records that the exchange contract can move up to 100 USDC out of your address. When the trade fires, the exchange calls transferFrom(you, buyer, 100) and the allowance is spent[2].
It saved gas and made composable DeFi possible. It also left behind a persistent grant that survives long after the transaction that created it. If the spender turns hostile, or if the approved amount was type(uint256).max (an infinity approval, still the default in many wallets and dApps), the whole balance sits exposed until someone revokes it[3].
Every attack in this article ends the same way: some contract you signed something for calls transferFrom and empties the token.
Four flavours of the attack
| Signature type | On-chain? | Grants | Wallet UI shows |
|---|---|---|---|
| approve() | Yes, tx | Per-token allowance to one spender | "Set allowance" prompt[2] |
| permit() (EIP-2612) | No, off-chain sig | Same as approve, but redeemable by anyone | "Sign message" prompt, no gas[4] |
| Permit2 | No, off-chain sig | Multiple tokens, one spender, expiry | "Sign message", opaque struct[5] |
| setApprovalForAll (ERC-721 / ERC-1155) | Yes, tx | Every NFT in the collection to one operator | "Approve collection" prompt[6] |
Each step moved from cheap and visible (approve) to gasless and opaque (permit, Permit2). The honest UX got faster; the phishing UX got worse. A permit signature costs $0 to produce, never appears on-chain until the attacker submits it, and stays invisible to block explorers until the drain fires. That is why 2023 and 2024 signature-phishing losses kept climbing even as fake-token airdrops fell off.
The playbook
A modern drainer kit sold on Telegram runs the same sequence every time[7]:
- Lookalike site. A clone of a well-known dApp, staking dashboard, airdrop claim page, or NFT mint. Usually served from a homoglyph domain (paraded as
uniswap-io.com,opeensea.io) or promoted through a compromised X account. - Wallet connect. The site prompts for a wallet connection. This step reveals your address and token holdings to the attacker's backend. Nothing has been signed yet.
- Scan and pick the fattest target. The backend enumerates your token balances. The drainer chooses the token or NFT with the highest USD value that matches its list of drainable assets.
- Craft the ask. A signature request. If the target is a fungible token with EIP-2612 support (USDC, DAI, most modern tokens), it is a
permit. If the wallet supports Permit2 for the chain, it is a Permit2 batch. If it is an NFT collection, it issetApprovalForAll. Rarely, it is a straighttransferFromthat requires an existing infinite approval, which many wallets already have. - Cash out. An attacker address submits the signature and pays the gas. Funds move into a laundering path, usually Tornado Cash or a chain of freshly created addresses, within one block of the drain.
The whole sequence takes under two minutes from connect to drain. The victim gets one signature prompt. Everything else happens off-screen.
Scale, 2023 to 2025
| Period | Losses | Victims | Source |
|---|---|---|---|
| 2023 full year | $295M | ~324,000 addresses | Scam Sniffer[1] |
| 2024 full year | $494M | ~332,000 addresses | Scam Sniffer[1] |
| Aug 2024, single victim | $69M | 1 | PeckShield alert[8] |
| Q1 2025 | $187M | ~78,000 addresses | Chainalysis update[9] |
Chainalysis and Elliptic both flag approval phishing as the fastest-growing crypto-theft category, ahead of exchange hacks and DeFi exploits in 2024 by loss volume[9][10]. The FBI's IC3 attributed the majority of retail crypto losses to signed-transaction fraud in its 2023 and 2024 annual reports[11].
Why the wallet UI keeps losing
A drainer's signature prompt looks legitimate because the wallet UI has no idea what the signature means. Every wallet shows the same generic text ("Sign this message from example.com") for any EIP-712 typed payload it does not recognize. Faced with an opaque struct, the user either signs or gives up and misses the airdrop. Most sign.
Three specific UI failures compound:
- No default simulation. Only a handful of wallets ship transaction simulation by default. Most require an extension (Wallet Guard, Blockaid, Fire) or a manual toggle. If the wallet does not compute the state change before signing, the user cannot see that the drainer is about to move 10,000 USDC.
- Infinite approvals as default. Uniswap, PancakeSwap, and most first-generation DEXes default to
type(uint256).maxapprovals to save gas on future trades. This leaves an open door for years after the trade is done[3]. - Permit and Permit2 shown as "Sign message". A
permitis not a message. It is an off-chain authorization that becomes an on-chain drain when the attacker submits it. The wallet's "Sign message" label is technically true and practically dangerous.
Defenses that work in 2026
| Defense | What it stops | Where |
|---|---|---|
| Transaction simulation | Any drain that changes state you did not expect | Blockaid, Wallet Guard, Fire, Rabby, Pocket Universe[12] |
| Human-readable permit parsing | Permit and Permit2 disguised as generic messages | MetaMask 11+, Rabby, Coinbase Wallet, VEYRNOX |
| Bounded approvals by default | Infinite-allowance drain years later | Rabby, Coinbase Wallet, VEYRNOX default to exact amount[13] |
| Drainer domain blocklist | Known phishing sites at the wallet-connect step | Blockaid + Scam Sniffer feed, ~2M domains blocked[14] |
| Approval audit tool | Historic infinite approvals still open | Revoke.cash, Etherscan Token Approvals[15] |
| Hardware-wallet clear signing | Blind sign on Ledger and Trezor | Ledger Clear Signing initiative[16] |
| Session keys with limits | Wide-scope approvals altogether | ERC-4337 account abstraction[17] |
Wallet-by-wallet, in one table
| Wallet | Default simulation | Permit parsing | Bounded approval default |
|---|---|---|---|
| MetaMask | Yes (Blockaid, 2024)[18] | Yes | No, follows dApp |
| Rabby | Yes | Yes | Yes, exact amount |
| Trust Wallet | Yes (Blockaid) | Partial | No |
| Phantom | Yes (Solana transaction preview) | N/A on Solana | N/A on Solana |
| Ledger Live | Partial (Clear Signing on select apps) | Partial | Follows dApp |
| Coinbase Wallet | Yes | Yes | Yes |
| VEYRNOX | Yes, on by default | Yes, human-readable spender + amount | Yes, exact amount + explicit "unlimited" opt-in |
Practical guidance
- Audit approvals monthly. Go to revoke.cash, connect the wallet in read-only mode first, and revoke anything you do not actively use. Aim for zero infinite approvals older than 30 days.
- Refuse infinite approvals on new tokens. When a dApp asks for
type(uint256).max, either edit the amount to the exact trade size or use a wallet that does it for you. - Never sign a "message" you cannot read. If the payload is a struct of hex, treat it as hostile. Copy the domain and check it against Blockaid or Scam Sniffer's public feed before doing anything else.
- Separate hot and cold. The wallet you connect to random dApps should hold spending money only. A drainer that hits a $200 hot wallet is annoying; one that hits your holdings is life-changing.
- Use a wallet with default simulation. The list above narrows it. If your current wallet does not, install an extension that does or switch.
- Watch for the specific tell. The dApp prompts a "gasless" signature to "verify your wallet" before letting you claim an airdrop, mint an NFT, or restake. There is no legitimate need for that signature. It is the drainer.
What the industry still needs to fix
ERC-20 approvals are a 10-year-old design that assumed the honest case would dominate. That stopped being true around the time DeFi crossed $50B TVL. Fixes exist. They ship slowly.
- Time-bounded approvals as a token standard. Permit2 has this per-token but requires opt-in at the spender side. A token-level default would help.
- Session keys via ERC-4337. Grant a dApp a scoped, time-limited signing key rather than a persistent allowance. Uniswap V4 and Safe are moving in this direction[17].
- Wallet-level clear signing for every EIP-712 struct. Ledger's Clear Signing initiative is the right idea; making it mandatory across all mobile and hardware wallets closes the "opaque message" gap[16].
- Public infrastructure for drainer detection. Blockaid and Scam Sniffer maintain useful feeds; a shared, open feed would compound faster[14].
Bottom line
Approval phishing is now the single largest loss vector in retail self-custody. It works because ERC-20 allowances are opaque, because permit and Permit2 look like harmless messages, and because most wallets ship a UI that cannot tell users what they are signing. The fixes are all client-side: default simulation, bounded approvals, human-readable permit parsing, and a monthly approval audit. Every one of those is available in production wallets today. Use them.
Approval safety in VEYRNOX
VEYRNOX simulates every transaction and every EIP-712 signature before the sign screen appears, parses permit and Permit2 into "grant spender X the right to move Y USDC until Z", and defaults approvals to the exact trade amount. Unlimited approvals require an explicit second confirmation. Download or read the security model.
Sources
- Scam Sniffer, "2024 Wallet Drainers Report." drainer.io
- ERC-20 Token Standard, EIP-20. eips.ethereum.org
- OpenZeppelin, "Infinite approvals and their risk." blog.openzeppelin.com
- EIP-2612, "permit, ERC-20 Approval via secp256k1 signatures." eips.ethereum.org
- Uniswap Labs, "Permit2 documentation." docs.uniswap.org
- EIP-721, "Non-Fungible Token Standard." eips.ethereum.org
- SlowMist, "Anatomy of a wallet drainer kit." slowmist.medium.com
- PeckShield alert stream, Aug 2024 $69M drain. x.com/peckshieldalert
- Chainalysis, "2025 Crypto Crime Report." chainalysis.com
- Elliptic, "Signature phishing analysis." elliptic.co
- FBI IC3, "Cryptocurrency Fraud Report 2023." ic3.gov
- Blockaid, transaction simulation. blockaid.io
- Rabby wallet, security features. rabby.io
- Scam Sniffer, drainer feed. scamsniffer.io
- Revoke.cash, allowance dashboard. revoke.cash
- Ledger, "Clear Signing initiative." ledger.com
- EIP-4337, "Account Abstraction using entry point." eips.ethereum.org
- MetaMask, "Blockaid integration announcement." consensys.io
- Trail of Bits, "Permit and Permit2 threat model." blog.trailofbits.com
- CertiK, "Approval phishing case studies." certik.com
- TRM Labs, "2025 Crypto Crime Mid-Year." trmlabs.com
- Wallet Guard, phishing signature detection. walletguard.app
- Etherscan Token Approvals. etherscan.io
- Safe, session keys documentation. docs.safe.global
Al Socrates Jobson, Co-Founder and CTO, Veyrnox LTD · ← Back to Blog