How to Revoke Token Approvals Safely
Learn how to revoke ERC-20 and NFT token approvals safely, verify the change on-chain, and reduce wallet risk from stale or unlimited permissions.

Introduction
Revoke Token Approvals means removing a Smart Contracts permission to move Tokens or NFTs from your wallet. This matters because approvals often outlive the moment you needed them: disconnecting a wallet from a site does not cancel the on-chain permission, and many approvals remain usable indefinitely until you change them yourself.
The basic pattern is simple. A token contract stores some record of who is allowed to spend or transfer assets on your behalf. Revocation works by updating that record so the permission becomes zero, false, or empty. The exact transaction depends on the token standard, but the idea is the same: you are not “deleting a website connection”; you are changing on-chain state.
If you have used DeFi apps, marketplaces, bridges, or minting sites, you have probably created approvals already. Some are narrow and temporary in effect. Others are broad, including unlimited ERC-20 allowances or ERC-721 operator approvals, and those are the ones worth reviewing first because they keep working long after you stop using the app.
Step 1: Identify the network and the kind of approval you want to remove
Start by opening an approval checker in a Block Explorer, wallet, or revocation tool, then switch to the same network where you originally used the app. This step exists because approvals are stored separately on each chain. If you approved a spender on Ethereum, you will not see that approval while viewing Polygon or BNB Chain.
At this stage, the important distinction is what kind of permission you are looking at. For ERC-20 tokens, the approval is usually an allowance(owner, spender): a spender is allowed to move up to some amount of your tokens. For NFTs under ERC-721, there are two different permissions: a per-token approval through approve(...), and a much broader collection-level operator approval through setApprovalForAll(...) . Revoking the wrong one will not remove the permission you care about, so read the entry carefully before signing anything.
In practice, tools often label these clearly. You may see a token symbol, the contract address, the spender or operator address, and an amount such as a finite number or a maximum uint256, which is commonly used as an infinite approval. Infinite approvals deserve extra attention because they are not gradually used up in the usual way; they must be explicitly replaced or removed.
Step 2: Review what each approval actually allows
| Approval type | Scope | Revocation call | Cleared on transfer | Blast radius |
|---|---|---|---|---|
| ERC-20 allowance | Per token contract spender | approve(spender, 0) | Not auto-cleared | Variable |
| ERC-721 per-token | Single token ID | approve(tokenId, zero address) | Cleared on transfer | Low |
| ERC-721 operator | Whole collection operator | setApprovalForAll(operator, false) | Not auto-cleared | High |
Before revoking, confirm who has permission and how broad that permission is. The reason to pause here is that token approvals are not all equivalent. An ERC-20 allowance lets a spender call transferFrom(...) to move your tokens up to the approved amount. An ERC-721 setApprovalForAll(...) lets an operator manage all NFTs you own in that collection, which is much broader than approving a single token ID.
A useful working rule is to rank approvals by blast radius. Permissions you no longer recognize, contracts tied to old or abandoned apps, and approvals set to unlimited values should usually be checked first. Several incident reports and user guides emphasize that lingering approvals to outdated or compromised contracts are a recurring source of wallet drains.
This is also where many people make a common mistake: they assume that because they withdrew funds from a protocol, or because they disconnected their wallet, the protocol can no longer act. That is false. The approval is independent of your current app session and independent of whether your funds are still deposited in that protocol. If the contract still has spending rights and your wallet later holds the token again, the approval can still matter.
Step 3: Revoke an ERC-20 token allowance
For an ERC-20 token, revocation is usually done by setting the spender’s allowance to 0. The standard mechanism is approve(spender, value), and calling it again overwrites the current allowance. So in the revoke case, the transaction is effectively approve(spender, 0).
That simple overwrite behavior is the key idea behind the whole workflow. ERC-20 does not define a special built-in revoke() function. Revocation is just approval with a zero value. After a successful call, the token contract should emit an Approval event, and the allowance(owner, spender) query should return 0.
Most users do not need to craft this transaction manually because explorers, wallets, and tools such as approval checkers present a Revoke button that builds the same call for you. Once you click revoke, your wallet will ask you to sign an on-chain transaction and pay Gas. If the network is congested, confirmation can take some time.
If the revoke transaction fails, do not assume the approval changed anyway. The ERC-20 spec explicitly warns callers not to assume token calls always succeed. Wait for confirmation, then re-check the allowance in the tool or explorer. The mechanism is only real once chain state changes.
Step 4: Revoke NFT approvals the right way
| Approval type | Revoke call | Scope affected | Cleared automatically? |
|---|---|---|---|
| Single-token approval | approve(tokenId, 0x0) | That token ID only | Yes |
| Collection operator | setApprovalForAll(operator, false) | Entire collection | No |
NFT approvals need a slightly different transaction depending on their scope. For a single ERC-721 token, revocation means setting the approved address to the zero address, which indicates that no address is approved for that token. For a collection-wide operator permission, revocation means calling setApprovalForAll(operator, false).
The difference matters because single-token approvals and operator approvals behave differently over time. A per-token ERC-721 approval is automatically cleared when that NFT is transferred. An operator approval is not tied to one token; it remains active for the collection until you explicitly disable it. So if your goal is to remove marketplace access across an entire collection, revoking one token’s approval will not solve the larger problem.
Approval tools usually separate these entries, but if you are using a Block explorer directly, double-check whether the wallet is preparing a zero-address approve(...) call for a specific token ID or a setApprovalForAll(..., false) call for the whole collection.
Step 5: Confirm the revocation on-chain
After the transaction confirms, verify that the permission is gone. This step matters because interfaces can lag, indexers can cache old data, and some token implementations differ in small ways that make tooling imperfect.
For ERC-20, the direct check is the allowance: allowance(owner, spender) should now be 0 or the new reduced amount if you chose to lower rather than fully remove it. For ERC-721, getApproved(tokenId) should return the zero address for a cleared single-token approval, and isApprovedForAll(owner, operator) should return false for a revoked operator approval.
A good revoke tool or explorer will refresh automatically, but if it does not, reload and verify again. The state query is the source of truth, not the button label.
Step 6: If you still need the app later, re-approve with narrower permissions
| Pattern | Convenience | Risk | When to use | Mitigation |
|---|---|---|---|---|
| Unlimited approval | Most convenient | High | Frequent dapp use | Revoke when idle |
| Finite allowance | Moderate convenience | Lower | Single purchase or cap | Set exact amount |
| Permit (ERC-2612) | Gasless UX | Same allowance risks | Gasless flows | Use short deadlines |
| Zero-then-set | Less convenient | Prevents race bug | Changing allowances safely | Wait for confirmations |
Revocation removes convenience as well as risk. The next time you use that app, it may ask for approval again. That is normal. The better pattern is not “never approve anything,” because many dapps cannot function without approvals. The better pattern is to grant the smallest permission that still lets the transaction work.
For ERC-20 tokens, that often means approving only the amount you plan to use rather than an unlimited maximum. If you later need a different nonzero allowance, there is an important caveat from the ERC-20 standard and OpenZeppelin guidance: changing an existing nonzero allowance directly can create a race condition in which the spender may use both the old and new allowance under unlucky transaction ordering. The recommended client-side pattern is to first set the allowance to 0, wait for that to succeed, and only then set the new nonzero amount.
Some tokens support permit under ERC-2612, which lets allowances be changed with a signed message instead of a traditional approve transaction from msg.sender. That can improve UX, but it does not remove the underlying approval risk. Permit-based allowances are still allowances, and the same race-condition concerns still apply.
Step 7: Build revocation into regular wallet hygiene
The most effective use of revocation is not only after a scare. It is as periodic maintenance. If you stop using a protocol, if a project looks abandoned, if a marketplace approval is no longer needed, or if an exploit is announced, review and remove those permissions.
This is especially important after suspicious activity. If you think you approved a malicious contract, revoking quickly can prevent further unauthorized transfers. But revocation is preventative, not restorative: it can stop future use of that approval, yet it cannot recover tokens that were already moved.
It also helps to keep the threat model straight. Hardware wallets protect private keys, but an approval exploit does not require an attacker to steal your key if you already authorized a contract to spend assets. And disconnecting your wallet from a website only ends the front-end session; it does not alter the contract’s standing permission.
Conclusion
Revoking token approvals is just the act of updating on-chain permissions so a spender or operator no longer has access. For ERC-20, that usually means approve(spender, 0). For ERC-721, it means clearing a token approval to the zero address or disabling an operator with setApprovalForAll(..., false). Review broad approvals first, confirm the state changed after each transaction, and re-approve later only with the narrowest permission you actually need.
Frequently Asked Questions
- If I disconnect my wallet from a dapp, does that cancel its approval to spend my tokens? +
- No — disconnecting a wallet from a site only ends the front‑end session; it does not change on‑chain permissions. Approvals remain active until you submit an on‑chain transaction to update them (e.g., approve(spender, 0) for ERC‑20).
- How exactly do I revoke an ERC‑20 token allowance? +
- For ERC‑20 tokens you revoke by overwriting the allowance with approve(spender, 0); the ERC‑20 allowance storage is updated by approve calls and a successful approve(...,0) should make allowance(owner, spender) return 0. Many explorers and wallets provide a “Revoke” button that builds this transaction for you, but you must sign and pay gas and verify the on‑chain state after confirmation.
- What is an "infinite" approval and why is it riskier than a finite allowance? +
- An “infinite” approval is typically the uint256 maximum used as an allowance and it remains usable until you explicitly change or remove it, so infinite approvals have a larger blast radius and should be reviewed first. The guide recommends granting only the smallest amount you need rather than an unlimited allowance.
- What's the difference between revoking a single NFT approval and revoking marketplace access for an entire collection? +
- ERC‑721 has two separate permission types: per‑token approvals (approve(tokenId, addr)) that are cleared on transfer and collection‑wide operator approvals (setApprovalForAll(operator, true)) that remain active until you call setApprovalForAll(operator, false). If you want to remove marketplace access across a whole collection you must revoke the operator approval, not just clear a single token’s approval.
- Do I have to pay gas to revoke approvals and how do I confirm the revoke actually took effect? +
- Yes — every revocation is an on‑chain transaction that requires gas and may take minutes under congestion. After it confirms, verify the change with on‑chain queries like allowance(owner, spender) for ERC‑20, getApproved(tokenId) for ERC‑721 single approvals, or isApprovedForAll(owner, operator) for operator revocations.
- If my tokens were stolen because of an approval, will revoking the approval get them back? +
- No — revoking prevents future use of a permission but it cannot undo transfers that already happened; it is preventative, not restorative. If funds were already moved by an approved spender, revocation cannot recover those tokens.
- I used a signed permit (ERC‑2612) with a long deadline — can I revoke or invalidate that permit afterward? +
- Signed permits (ERC‑2612) replace an on‑chain approve call with an off‑chain signature, but they do not eliminate the underlying allowance risk and a long‑lived permit can be hard to invalidate once submitted. The EIP and guidance therefore recommend careful deadline selection and treat permit signatures as allowances that still require cautious handling.
- How can I safely change an existing nonzero ERC‑20 allowance without opening a race window? +
- To avoid the well‑known approve race condition, the recommended client pattern is to first set the allowance to 0 and wait for that transaction to confirm before setting the new nonzero allowance; many libraries and security notes (OpenZeppelin, EIP guidance) document this as the safe approach.
- Given recurring gas costs, how should I prioritize which approvals to revoke first? +
- Prioritize revoking approvals that have the largest blast radius: unknown or unrecognized spenders, abandoned or compromised projects, and unlimited allowances or collection‑wide operator approvals. Exact gas‑budget thresholds are not specified by the guide, so use that ranking to decide which revocations to pay for first rather than attempting to remove every small, low‑risk allowance immediately.