In a previous post, I gave a quick overview of ERC-20 — the fungible token standard used across EVM-compatible chains. Like how one dollar bill is interchangeable with another, ERC-20 tokens are designed to be equal in value and function.
Today, I want to dig deeper into one function in this standard that often goes unnoticed - but is critical for interacting with dApps and smart contracts: approve()
.
What approve()
does?
The approve(address spender, uint256 amount)
function lets the token holder (caller) authorize another address (the spender) to spend tokens on their behalf — up to a defined limit.
This is essential when interacting with DeFi protocols, DEXes like Uniswap, or any smart contract that requires moving tokens from your wallet. Instead of transferring tokens directly, you first give the smart contract permission to pull tokens from your balance when needed.
IERC20(token).approve(spender, amount);
Why You Should Care: Security Implications
The naive implementation of approve() can be risky.
Let's say you initially approve 100 tokens, then later decide to reduce it to 50. If you call approve(spender, 50)
, there is a chance that the spender sees both approvals before the new one takes effect — and spends both amounts.
This race condition is well-documented and can be exploited. See the issue on GitHub.
The best practice is to first set the allowance to 0 and only then set it to the desired value.
token.approve(spender, 0);
token.approve(spender, newAmount);
You can also use the OpenZeppelin's SafeERC20
library with methods like safeApprove()
, safeIncreaseAllowance()
, and safeDecreaseAllowance()
instead of manually calling approve()
. Looking at this library is outside the scope of this blog post.
TL;DR
The approve()
function of the ERC-20 standard permits a smart contract (or another address) to spend your tokens. It is a key part of token transfers in DeFi applications. Be careful and always reset to 0 before updating allowances to avoid race conditions.
The ERC-20 standard may seem simple, but subtle details like this one can expose users to a real risk of losing money.