How to Approve and Revoke an ERC-20 Token Allowance
Every DEX swap, bridge and staking deposit starts with an approval. Here is what approve() actually does, how to check what you have already granted, and how to revoke it — directly from the token contract.
What an Approval Really Grants
ERC-20 tokens cannot be "sent to" a contract by the contract itself. Instead you call approve(spender, amount) on the token contract, which records an allowance. The spender can then call transferFrom(you, anywhere, amount) at any time, until the allowance is used up or you reduce it.
allowance(owner, spender) -> uint256 approve(spender, amount) // sets the allowance (does not add to it) transferFrom(from, to, amount) // spender pulls tokens
An allowance is a standing permission, not a one-off. A router you approved for an unlimited amount two years ago can still move those tokens today — which is why revoking matters after a contract is deprecated or compromised.
Step 1 — Check the Current Allowance
- Build a page for the token address using the standard ERC-20 ABI.
- On the Read tab, call
decimals()and note the value (18 for most, 6 for USDC/USDT). - Call
allowance(owner, spender)with your address and the contract you want to check. The result is a raw integer: divide by 10decimals to read it in tokens.
A result of 115792089237316195423570985008687907853269984665640564039457584007913129639935 is 2^256 - 1 — an infinite approval.
Step 2 — Approve the Exact Amount
On the Write tab, call approve(spender, amount). The amount is in the token's smallest unit:
100 USDC (6 decimals) -> 100000000 1.5 DAI (18 decimals) -> 1500000000000000000 unlimited -> 115792089237316195423570985008687907853269984665640564039457584007913129639935
Exact approvals cost one extra transaction per interaction but cap your exposure to what that single action needs. Infinite approvals save gas and are fine for protocols you trust and use constantly — the trade-off is yours to make deliberately, not by accident because a UI defaulted to it.
Step 3 — Revoke
Revoking is just approve(spender, 0). It costs gas, it is irreversible only in the sense that you can re-approve later, and it takes effect the moment the transaction confirms. Do this for any protocol you no longer use, and immediately for any contract involved in an exploit.
Common Mistakes
- Approving on the wrong contract — approve() is called on the token, with the protocol as the spender argument. Never the other way round.
- Forgetting decimals: approving "100" on an 18-decimal token grants 0.0000000000000001 tokens, and the swap then fails with an opaque revert.
- USDT and a few older tokens require setting the allowance to 0 before setting a new non-zero value; a direct change reverts.
- Some tokens (notably USDT) do not return a bool from approve(), which breaks strict clients — the raw call still works.
- Approving does not move tokens. If your balance did not change after approve(), that is correct behaviour.
👉 Want to manage allowances on a token contract?
Build a contract page