Smart Contract Approval Exploit: How to Revoke Unlimited Token Allowances Before You Get Drained

Smart Contract Approval Exploit: How to Revoke Unlimited Token Allowances Before You Get Drained

By Fatima Al-Hassan · April 19, 2026 · 18 min read

Quick Answer

Every time you use Uniswap, OpenSea, or any DeFi dApp, you grant the contract permission to move your tokens — usually unlimited. Those approvals persist forever unless you revoke them. If the approved contract is ever compromised, phished, or maliciously upgraded, every approved token in your wallet becomes drainable. Audit your approvals on [revoke.cash](https://revoke.cash) or Etherscan at least quarterly, revoke anything you no longer use, and enable Permit2 signature awareness on your wallet.

Key Insight

Every time you use Uniswap, OpenSea, or any DeFi dApp, you grant the contract permission to move your tokens — usually unlimited. Those approvals persist forever unless you revoke them. If the approved contract is ever compromised, phished, or maliciously upgraded, every approved token in your wallet becomes drainable. Audit your approvals on [revoke.cash](https://revoke.cash) or Etherscan at least quarterly, revoke anything you no longer use, and enable Permit2 signature awareness on your wallet.

The Most Common Way Wallets Get Drained in 2026

Every week, someone posts a thread on X describing how they lost their entire portfolio in a single transaction they did not sign. They blame the hardware wallet, the browser extension, the RPC provider. The actual cause, nine times out of ten, is a token approval they granted months earlier and forgot about.

Approval exploits are the leading cause of self-custody losses in 2026. The mechanism is almost embarrassingly simple: you grant a contract unlimited permission to move your tokens once, that permission persists forever, and when the contract is later compromised or phished, every token you approved is free to take.

This guide covers how approvals work at the protocol level, why infinite approvals are the default despite the risk, exactly how attackers weaponize them, and the ten-minute routine that shuts the whole class of attacks down. Every wallet owner should run this audit at least quarterly.

If you want a broader security framing, see our crypto security best practices for 2026 first.

How ERC-20 Approvals Actually Work

The ERC-20 token standard deliberately separates ownership from spending authority. Your wallet owns the tokens. But for any other contract (a DEX, a lender, a bridge) to move them, you must first authorize it.

The authorization mechanism is two functions:

solidity
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);

When you "approve Uniswap to spend USDC", your wallet submits a transaction calling USDC.approve(UniswapRouter, amount). The USDC contract records that the router is allowed to move up to that much USDC from your address. When you then perform a swap, the router calls USDC.transferFrom(you, pool, swapAmount), and the USDC contract checks the allowance, decrements it, and transfers the tokens.

The protocol works well. The problem is the default value of amount.

Why unlimited approvals became standard

Every time you approve exactly the amount you need for one swap, you pay gas for the approval plus gas for the swap. Two transactions. On mainnet that is $10-30 of gas per trade in busy conditions.

To avoid this, every major dApp in DeFi history defaulted to requesting uint256 max (approximately 1.15 x 10^77, a number larger than all tokens that will ever exist). One approval covers every future trade on that dApp.

It is a reasonable UX decision in isolation. In aggregate, it means every active wallet holds dozens of unlimited approvals to contracts the user interacted with once and forgot about. Each one is a persistent attack surface.

The Real Attack Vectors

Vector 1: Protocol exploit or malicious upgrade

If an approved protocol is hacked, or upgraded to a new implementation by a compromised admin key, the attacker inherits every outstanding allowance. They call transferFrom against every approved wallet and drain them.

This has happened repeatedly: Multichain (July 2023, $230M drained via custodian compromise), PolyNetwork, BadgerDAO. In each case, users who had long since stopped using the protocol lost funds because they never revoked.

Vector 2: Phishing with a fake approval

The classic wallet drainer. Fake airdrop site, cloned DEX UI, Twitter impersonator posting a limited-time link. User connects their wallet and is prompted to approve a token for an innocuous-looking contract address. That contract is the attacker's drainer. Approval granted. Tokens drained minutes later.

Wallet warnings have improved, but users still click through, especially when hurried or excited (mint day, new airdrop, "last chance" framing).

Vector 3: Permit and Permit2 signatures

This is the dominant vector in 2026 and the one most users do not understand.

The Permit extension to ERC-20 (and Uniswap's Permit2) let users authorize token movement with an off-chain signed message instead of an on-chain transaction. You sign an EIP-712 structured message; the recipient submits the signature to the token contract when they want to move the funds.

From the user perspective, they signed a message, not a transaction. There is no pending tx in MetaMask history, no gas paid, nothing to see on Etherscan. Many users do not even realize they just granted an approval.

From the attacker perspective, a single malicious signature request can grant unlimited allowance for any duration to any spender. Drainers love Permit2 because one signature can authorize the movement of multiple tokens in a single batch.

Vector 4: Setapprovalforall on NFTs

NFT approvals use a different function, setApprovalForAll(operator, true), which grants the operator permission to transfer any token of that collection from your wallet. Used legitimately by OpenSea, Blur, and other marketplaces. Used maliciously by fake marketplaces, it hands over your entire NFT collection.

The Ten-Minute Audit: Finding and Revoking Approvals

Step 1: Visit revoke.cash

Open revoke.cash. It is a free open-source tool maintained by Rosco Kalis and widely trusted in the security community.

You can connect your wallet (write access, needed to actually revoke) or paste your address for read-only inspection. Select the network (it supports Ethereum, Arbitrum, Optimism, Base, Polygon, BNB Chain, Avalanche, and ~50 others).

Step 2: Review the list

For each approval, revoke.cash shows:

  • Token: which ERC-20 or NFT collection you approved.
  • Spender: the contract address and often a name (Uniswap V3 Router, OpenSea Seaport, etc.). Unknown spenders show as the raw address — red flag if you do not recognize it.
  • Allowance: the amount. "Unlimited" means uint256 max; specific numbers are explicit caps.
  • Last updated: when the approval was granted.

Step 3: Revoke anything you do not use

Click Revoke on any approval you do not actively use. You can batch multiple revokes in one transaction to save gas. Confirm in your wallet; the approval becomes 0.

Conservative defaults:

  • Revoke anything approved more than 6 months ago that you are not using today.
  • Revoke anything with "Unknown" or unfamiliar spenders.
  • Revoke setApprovalForAll for any NFT collection you are not actively trading.
  • Keep approvals only for the 3-5 dApps you actively use (Uniswap, Aave, a DEX aggregator, etc.).

Step 4: Check for signatures (Permit approvals)

Permit-based approvals do not always show in on-chain revoke.cash lists because they are off-chain signatures. To protect against them:

  • Review your wallet's recent signature history (MetaMask: Settings > Security & Privacy).
  • Revoke any allowance stored in Permit2 via the Permit2 UI on revoke.cash (there is a dedicated tab).
  • When signing any EIP-712 message, read the domain, message type, and spender carefully.

Step 5: Enable real-time monitoring

Services like Blockaid, Wallet Guard, and Harpie watch your wallet for new approvals and flag dangerous ones before or after signing. Harpie can auto-revoke if it detects a drain in progress. These are worth the minor setup friction for any wallet holding more than trivial value.

Using Etherscan Directly

If you prefer not to trust a third party, Etherscan has a built-in approval checker.

  1. Go to etherscan.io/tokenapprovalchecker.
  2. Paste your address or connect your wallet.
  3. Review the list of active approvals.
  4. Click Revoke on any row you want to remove. Etherscan will construct the approve(spender, 0) transaction for you.

The UX is less polished than revoke.cash but the data comes directly from the canonical indexer. Worth using as a cross-check.

For multi-chain wallets, every major explorer has an equivalent: Arbiscan, Optimistic Etherscan, Basescan, PolygonScan all support the same /tokenapprovalchecker path.

Real Drain Case Studies

Case A: The dormant-year approval

Victim granted unlimited USDC approval to a DEX aggregator in 2023 as part of a single swap. Never used that aggregator again. In 2025 the aggregator's admin multisig was phished. Attacker pushed an upgrade that added a drain function. Approved wallets lost $40M in aggregate. The victim would have been fine if they had ever revoked.

Case B: The fake airdrop page

Victim saw a tweet claiming a well-known L2 project was airdropping to early users. Clicked through to a typo-squat domain (lowercase L instead of I). Connected wallet. Site prompted "approve to verify eligibility". Approved USDC. Five minutes later, $8,400 of USDC was drained via transferFrom.

The approve transaction was legitimate ERC-20 behavior. The wallet had no way to know the spender was malicious. Only user vigilance (verify domain, verify contract address, ask "why does a claim need my approval?") prevents this.

Case C: The Permit2 signature

Victim using a DEX aggregator. Prompt to sign a Permit2 message to enable "gasless approval". User clicked sign without reading the structure. The signature actually authorized transfer of their entire USDT and DAI balance to an attacker-controlled address with a 1-hour deadline. Forty minutes later, tokens gone.

No approve transaction ever happened. Revoke.cash did not show anything because there was no on-chain approval. The wallet's own history showed only "Signature request", with no dollar amount. This is why signature hygiene matters as much as approval hygiene.

Prevention Playbook

Wallet separation

Use at least three wallets:

  • Cold wallet: hardware-only, never connects to any dApp, holds long-term assets. See what is a crypto wallet for the basics.
  • Main wallet: active DeFi wallet with modest balances, only connected to 3-5 trusted dApps with audited approvals.
  • Burner wallet: for new, unaudited, or suspicious dApps. Funded per-transaction. Never holds meaningful value.

Signature hygiene

  • Read every EIP-712 signature prompt. Look at the domain, the message type, and the fields. If it says PermitSingle, PermitBatch, SignatureTransfer, or mentions owner, spender, and value, you are authorizing token movement.
  • Reject any signature you cannot read or do not understand.
  • Prefer wallets that show a simulation of what the signature would do (Rabby, Frame, Coinbase Wallet all have this).

Approval hygiene

  • Request "exact amount" approvals when the dApp supports it (Uniswap and many others expose a toggle).
  • Set a calendar reminder to run the revoke.cash audit every 90 days.
  • Treat each approval like a persistent security grant, because that is exactly what it is.

Hardware wallet specifics

  • Disable "blind signing" wherever possible (Ledger: Settings > Developer Mode off).
  • Verify the destination address on the device screen, not just the browser.
  • Use an air-gapped device (Keystone, GridPlus, Cobo Vault) for large balances if you want no USB or Bluetooth attack surface.

Advanced: Monitoring Approvals at Scale

For teams managing many wallets (DAOs, funds, treasuries), use on-chain monitoring tooling:

These setups cost more but eliminate the human-reminder failure mode. For context on the underlying smart contract mechanics see our explainer on what smart contracts are.

The One-Minute Summary

  1. Open revoke.cash, connect your wallet.
  2. Revoke every approval older than 6 months that you do not recognize or no longer use.
  3. Check the Permit2 tab for off-chain approvals.
  4. Enable Blockaid or Wallet Guard for ongoing monitoring.
  5. Set a 90-day calendar reminder.

Do this quarterly and you eliminate the single largest attack surface in modern self-custody.

External references:


This post is part of our Web3 security coverage. For a broader self-custody framework, see our [crypto security best practices guide](/blog/crypto-security-best-practices-2026).

Key Takeaways

  • ERC-20 approve grants a spender contract permission to move your tokens — the default amount most dApps request is 2^256 - 1 (effectively infinite)
  • Revoking an approval is a normal on-chain transaction costing gas, but skipping it leaves a persistent attack surface on every exploited protocol
  • [Revoke.cash](https://revoke.cash), Etherscan Token Approval Checker, and DeBank all surface your current approvals — use at least one monthly
  • Permit and Permit2 signature-based approvals bypass the on-chain approve step entirely, so a single malicious signature can drain assets without an obvious "approve" in your wallet history
  • Hardware wallets do not prevent approval exploits — they sign whatever you approve, including infinite allowances to malicious contracts
  • Automated wallet monitoring services like Blockaid, Wallet Guard, and Harpie can flag dangerous approvals in real time
  • The safest operational pattern: use a "burner" wallet for new dApps, a primary wallet with minimal approvals, and a cold wallet for long-term holdings

Frequently Asked Questions

What is a token approval and why is mine unlimited?

ERC-20 tokens require explicit permission before any contract can move them from your wallet. When you call approve(spender, amount) you grant the spender that allowance. Most dApps (Uniswap, 1inch, OpenSea, Aave) default to requesting the maximum possible amount — uint256 max, roughly 2^256 - 1 — so the user never has to approve again for future trades. This is a deliberate UX choice to avoid repeated gas fees, and it is the single largest source of wallet drain risk.

How do attackers exploit unlimited approvals?

Three main paths. First, the approved protocol itself is exploited or upgraded by a malicious admin (a "rug"), and the attacker uses your existing allowance to transferFrom your tokens. Second, you get phished into signing an approval for a malicious contract disguised as a legitimate one. Third, you sign a Permit or Permit2 off-chain signature that grants allowance without any on-chain approve transaction visible in your history — this is the dominant drainer vector in 2026.

How do I check what approvals my wallet has granted?

Easiest: visit [revoke.cash](https://revoke.cash), connect your wallet (or paste the address for read-only), and review the list. It shows every outstanding approval, the allowance amount, and a one-click revoke button. Alternatives: [Etherscan's Token Approvals tool](https://etherscan.io/tokenapprovalchecker), DeBank's Approvals tab, and Zerion. For a full multi-chain view, revoke.cash supports 50+ chains including Arbitrum, Optimism, Base, Polygon, and BNB Chain.

Does revoking cost gas?

Yes. Each revocation is an on-chain transaction: approve(spender, 0). On Ethereum mainnet that costs roughly $1-5 in gas in 2026 depending on network conditions; on L2s it costs cents. Revoke.cash and similar tools let you batch revocations in one transaction to save gas. If you have many old approvals, consolidate the revokes into one or two transactions during a low-fee window.

What is Permit2 and why is it different from a normal approval?

Permit2 is a signature-based approval standard developed by Uniswap that replaces the on-chain approve call with an EIP-712 signature. You sign a message off-chain; the dApp submits the signature on-chain when it wants to move your tokens. The problem: malicious signatures can steal funds without any "approve" transaction ever appearing in your wallet history. If you see a signature request with SignatureTransfer, PermitSingle, PermitBatch, or EIP-712 structures, read it carefully — it can drain specific tokens, all tokens, or grant unlimited future allowance.

Does a hardware wallet protect me from approval exploits?

Only partially. A hardware wallet protects your private key from malware — attackers cannot steal the key itself. But it still signs whatever transaction or message you approve on the device. If you authorize an infinite approval to a malicious contract, the hardware wallet signs that approval and the attacker can drain the tokens later. Hardware wallets with "blind signing" disabled help because they force you to see the destination and amount, but many dApps still require blind signing for complex calls.

Should I use a different wallet for new dApps?

Yes. This is the single highest-impact operational security practice. Keep a "hot" wallet with modest balances for active DeFi use, a "burner" wallet that you fund per-transaction for new or unaudited dApps, and a "cold" wallet (hardware, ideally offline) for long-term holdings that you never connect to any dApp. See our [crypto security best practices guide](/blog/crypto-security-best-practices-2026) for a full walk-through of this separation.

How often should I audit my approvals?

At minimum every 90 days, and immediately after any of: a dApp you used was exploited or rugged, you signed a signature request you are not sure about, you connected to a new dApp you do not trust, or you moved significant funds into the wallet. Set a calendar reminder or use a monitoring service like Harpie or Wallet Guard that alerts on new approvals automatically.

About the Author

F

Fatima Al-Hassan

Cybersecurity Expert & Privacy Researcher

MS Cybersecurity, Georgia Tech | CISSP, CEH | Former Head of Security at Chainguard Labs

Fatima Al-Hassan is a cybersecurity expert and privacy researcher with nine years of experience in information security, blockchain security, and zero-knowledge cryptography. She holds an MS in Cybersecurity from Georgia Tech and is a Certified Information Systems Security Professional (CISSP) and Certified Ethical Hacker (CEH). Before joining Web3AIBlog, Fatima was the Head of Security at a leading blockchain infrastructure company, where she led red team exercises and designed security architectures for Layer-1 protocols handling billions in transaction volume. She has disclosed responsible vulnerabilities in multiple DeFi protocols and contributed to security standards published by the Blockchain Security Alliance. Fatima writes about smart contract vulnerabilities, privacy-preserving technologies, zero-knowledge proofs, and best practices for securing digital assets.