Track 5 · Tokens · lesson 3
Approvals and allowances
12 min
A token contract only lets you move your own balance. So how does Uniswap swap your tokens?
You give it permission first. That two-step dance is behind every swap, every deposit and every NFT listing you have ever made.
The dance
- You call
approve(uniswap, 100)on the token contract. - Uniswap calls
transferFrom(you, pool, 100)on the same contract.
The token contract checks that step 1 happened before allowing step 2. Two transactions, two gas fees, one swap — and now you know why every dApp makes you click twice the first time.
The permission lives in the token contract, not in Uniswap. allowance is a
nested mapping: owner → spender → amount.
That is why revoking means calling the token, not the dApp. Disconnecting your wallet from a site does nothing, because the site was never holding the permission in the first place.
Nudge
Show me the approach
Show me the code
Explain the solution
Why the missing line matters so much
An allowance is a budget. Failing to decrement it turns a one-time permission into a standing one — and the holder can drain up to that amount repeatedly, forever.
Predict
Approvals live in the token contract. What does that mean for a dApp that gets hacked?
The race condition in the standard
ERC-20 has a known flaw. Suppose you approved a spender for 100 and want to
reduce it to 50. You send approve(spender, 50).
A watchful spender sees that pending transaction, front-runs it by spending the original 100, and then spends the new 50 as well. They got 150 from two approvals you intended as one.
The workarounds: approve to 0 first, then to the new amount. Or use
increaseAllowance / decreaseAllowance, which OpenZeppelin provides for
exactly this reason.
Check
Where is your approval to a DEX actually stored?
Worth remembering
- Spending someone else's tokens takes two steps: approve, then transferFrom.
- The allowance lives in the token contract as allowance[owner][spender].
- transferFrom must decrement the allowance, or one approval becomes unlimited.
- A compromised contract can use every approval ever granted to it.
- Changing a non-zero approval is front-runnable — set it to zero first, or use increase/decreaseAllowance.