
Every time you swap on a DEX, list an NFT, or deposit into a lending protocol, you almost certainly signed a token approval first — a standing permission that lets a smart contract move tokens out of your wallet on your behalf. Here's the part most people miss: those permissions don't expire. The approval you granted to a protocol in 2023 is still active today, whether or not you've touched that protocol since, and whether or not that protocol's contracts are still safe.
Revoking approvals is the unglamorous maintenance task of self-custody. It's not complicated, but the mechanism is worth understanding properly, because the risk isn't the approval you remember granting. It's the one you forgot — sitting open against a contract that just got exploited.
An ERC-20 token approval is a function call — approve(spender, amount) — recorded in the token contract's own storage. You're telling the token contract: this address (the spender, usually a protocol's smart contract) may transfer up to this amount of my tokens. The approval lives inside the token contract, not inside the protocol you approved. That detail matters later.
Most interfaces historically requested unlimited approvals — technically an allowance of the maximum possible number — so you wouldn't need to pay gas for a fresh approval on every trade. Convenient, and it's why a single old approval can expose your entire balance of that token rather than the amount you once intended to trade.
NFTs use a blunter instrument: setApprovalForAll(operator, true) grants a marketplace or contract permission over every NFT in that collection that your wallet holds, current and future. One signature, the whole collection.
Now the revocation mechanism, which is simpler than the name suggests. There is no special "revoke" function. You revoke an ERC-20 approval by overwriting the allowance with zero — calling approve(spender, 0) — and you revoke an NFT operator by calling setApprovalForAll(operator, false). Both are ordinary on-chain transactions. Both cost gas. Once the zero-allowance transaction confirms, the spender contract can no longer move those tokens, full stop. The permission isn't suspended or flagged — the number it checks against is now zero.
Checking your approvals is free and requires no signature — this is worth saying explicitly, because it means there's no risk in looking. Allowances are public on-chain state. You can paste your address into a checker without connecting a wallet at all.
The standard tools: Revoke.cash (the most widely used dedicated interface, covering most major chains), Etherscan's Token Approval Checker (and its equivalents on other chains' explorers), and increasingly the wallet itself — Rabby, for instance, surfaces open approvals natively. The flow is the same everywhere:
One mechanical caution: fake "revoke" sites exist, and they invert the tool's purpose — a panicked user searching "revoke approvals" after exploit news is exactly who they're built for. The same signature discipline applies here as anywhere: a genuine revocation is an approve call setting an allowance to zero. If a revocation site asks you to sign something else — a new approval, an opaque message, anything involving a seed phrase — it's not a revocation tool.
Gas is the obvious one. Approvals are per-token, per-spender, per-chain, and each revocation is a separate transaction — cleaning up a wallet with thirty open approvals across three chains costs real money on mainnet, less on L2s. This is why most people triage rather than zero everything.
The second constraint is that revocation is forward-looking only. It stops future transfers; it does not recover anything already taken. If a drainer used an open approval an hour ago, revoking now closes the door on what's left, nothing more.
The third is subtler: off-chain permit signatures (permit, and Uniswap's Permit2 system) complicate the picture. Permit2 holds its own allowance ledger — so a full audit means checking approvals granted to Permit2 and the sub-allowances inside it. The good news is that Permit2 allowances carry expiration timestamps, which is the direction the whole system is moving. Admittedly, this is the messiest corner of the topic, and the tooling is still catching up to it.
The structural shift is from permanent-by-default to expiring-by-default. Permit2-style time-bound allowances are spreading, interfaces increasingly request exact amounts instead of unlimited ones, and wallets are absorbing approval management as a native feature rather than leaving it to third-party dashboards. Account abstraction points further down the same road — session keys with scoped, expiring permissions would make the standing unlimited approval look like a design artifact of an earlier era. That last part is directional, not deployed reality.
Expiring allowances becoming the default request pattern in major protocol interfaces. Approval dashboards shipping as standard in the top wallets. A measurable decline in exploits that route through stale approvals rather than fresh phishing signatures.
A major exploit that moves tokens without any approval or signature — that would indicate a deeper problem than permission hygiene can address. Or evidence that revocation transactions themselves can be spoofed at the wallet display layer, which would undermine the "read what you sign" defense this whole mechanism relies on.
Now: an approval audit on any wallet holding meaningful value, repeated whenever a protocol you've used reports an exploit. The check is free; only the cleanup costs gas. Next: expiring approvals and wallet-native dashboards converting this from discipline into default. Later: account abstraction reframing the permission model entirely.
This explains the approval mechanism and how revocation works. It is not a complete security model — revoking approvals does nothing against a leaked seed phrase, a malicious signature you provide tomorrow, or a compromised device. It's one specific door, and this is how it closes. Whether any particular protocol deserves your approval in the first place is a separate question, outside this scope.




