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

  1. You call approve(uniswap, 100) on the token contract.
  2. 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.

Token.solComplete
Loading editor…
transferFrom moves the tokens but never spends the allowance. Fix it.
Run the code to see what happens.
Nudge
The first test passes. The allowance is checked — but is it ever changed?
Show me the approach
An allowance is a budget. Spending from a budget should reduce it.
Show me the code
Add `allowance[from][msg.sender] -= value;` before moving the balances.
Explain the solution
Without that line an approval for 100 tokens lets the spender move 100 tokens over and over, forever. This is not hypothetical — it is the shape of the approval exploit you will run in track 7.

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?

Choose one answer

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?

Choose one answer

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.