Glossary

ERC-20 (Token Standard)

ERC-20 is the Ethereum token standard defining a common interface for fungible tokens, enabling interoperability across DeFi.

Key Takeaways

  • ERC-20 is the dominant token standard on Ethereum: it defines six functions and two events that every compliant fungible token must implement, enabling any token to work with any compatible wallet, DEX, or lending protocol without custom integration.
  • Major stablecoins and DeFi tokens are ERC-20: USDC, USDT, UNI, LINK, DAI, and over two million other token contracts on Ethereum follow this standard.
  • ERC-20 has known limitations: the approve/transferFrom race condition, tokens permanently lost when sent to incompatible contracts, and no callback mechanism. Newer standards like ERC-721, ERC-1155, and ERC-4626 address specific gaps.

What Is ERC-20?

ERC-20 (Ethereum Request for Comments 20) is a technical standard for creating fungible tokens on the Ethereum blockchain. Proposed by Fabian Vogelsteller and Vitalik Buterin in November 2015 as EIP-20, it reached "Final" status in 2017. The number 20 comes from it being issue #20 on the Ethereum Improvement Proposals GitHub repository.

Before ERC-20, every token contract defined its own interface. Wallets and exchanges needed custom code to support each new token. ERC-20 solved this by establishing a common API: any smart contract implementing the standard's six required functions automatically works with every ERC-20-compatible wallet, DEX, and lending protocol. This composability became the foundation of DeFi.

How It Works

An ERC-20 token is a smart contract deployed on Ethereum that maintains a mapping of addresses to balances. The standard defines a minimal interface that all compliant tokens must expose, ensuring any external contract or application can interact with the token predictably.

The Six Required Functions

Every ERC-20 contract must implement these six functions:

// Returns the total token supply
function totalSupply() public view returns (uint256)

// Returns the balance of a specific address
function balanceOf(address _owner) public view returns (uint256 balance)

// Transfers tokens from the caller to another address
function transfer(address _to, uint256 _value) public returns (bool success)

// Transfers tokens from one address to another (requires prior approval)
function transferFrom(address _from, address _to, uint256 _value)
    public returns (bool success)

// Grants a spender permission to withdraw up to a specified amount
function approve(address _spender, uint256 _value)
    public returns (bool success)

// Returns the remaining amount a spender is allowed to withdraw
function allowance(address _owner, address _spender)
    public view returns (uint256 remaining)

The standard also defines three optional functions: name(), symbol(), and decimals(). In practice, nearly all tokens implement these since wallets and block explorers rely on them for display.

Events

Two events must be emitted so off-chain applications can track token activity:

// Emitted on any token transfer, including zero-value transfers
event Transfer(address indexed _from, address indexed _to, uint256 _value)

// Emitted whenever approve() is called
event Approval(address indexed _owner, address indexed _spender, uint256 _value)

Token creation should emit a Transfer event with the _from address set to 0x0. These events are indexed on-chain, allowing block explorers and analytics tools to track all token movements without polling contract state.

The Approve/TransferFrom Pattern

Direct transfers use transfer(), but interactions with third-party contracts (DEXs, lending protocols, vaults) require a two-step process:

  1. The token holder calls approve(spenderAddress, amount) to grant the contract a token approval
  2. The contract calls transferFrom(holder, recipient, amount) to move tokens on the holder's behalf

This pattern is fundamental to how DeFi works. When you "approve USDC" on a DEX, you're calling the USDC contract's approve() function to let the DEX contract spend your tokens.

Major ERC-20 Tokens

Over two million ERC-20 token contracts exist on Ethereum, though only a few thousand have meaningful market activity. The largest by market capitalization include:

TokenCategoryPurpose
USDT (Tether)StablecoinLargest stablecoin by market cap
USDC (Circle)StablecoinSecond-largest stablecoin, widely used in DeFi
LINK (Chainlink)UtilityPowers the Chainlink oracle network
UNI (Uniswap)GovernanceGovernance token for the largest DEX
DAI (MakerDAO)StablecoinDecentralized, overcollateralized stablecoin
WBTCWrapped assetWrapped Bitcoin on Ethereum
stETH (Lido)Liquid stakingLiquid staking derivative for staked ETH

Stablecoins dominate ERC-20 token rankings. For a deeper look at how stablecoins operate on different chains, see the research article on the Ethereum stablecoin market.

Why It Matters

ERC-20's standardization created a network effect that bootstrapped the entire DeFi ecosystem. Because every compliant token shares the same interface, developers can build protocols that work with any token automatically:

  • A DEX like Uniswap can list any ERC-20 token without permission or custom integration
  • A lending protocol like Aave can add new collateral types by simply whitelisting the token address
  • Wallets display any ERC-20 token balance by querying the same balanceOf() function
  • Liquidity pools, yield aggregators, and bridges all compose on the same standard

This composability is often called "money legos": each protocol is a building block that snaps together with others. Without ERC-20, every integration would require bespoke development, and DeFi's rapid growth would not have been possible.

The model also influenced token standards on other chains. BNB Chain's BEP-20 uses an identical Solidity interface (the same contract code deploys to both chains), and TRON's TRC-20 follows the same function signatures. Meanwhile, platforms like Spark take a different approach to token support, building on Bitcoin's UTXO model rather than account-based smart contracts.

Use Cases

Stablecoins

The largest use case for ERC-20 tokens is stablecoins. USDT and USDC alone account for over $250 billion in combined market cap. Their ERC-20 implementations allow them to plug into every DeFi protocol on Ethereum, enabling lending, automated market making, and stablecoin payment rails that compete with traditional finance.

DeFi Protocol Tokens

Governance tokens like UNI (Uniswap) and AAVE give holders voting rights over protocol parameters. Liquid staking tokens like stETH represent staked ETH while remaining tradeable and composable across DeFi.

Tokenized Assets

ERC-20 serves as the foundation for real-world asset tokenization: treasury bills, equities, commodities, and other financial instruments wrapped as fungible tokens. The standard interface means these tokenized assets can immediately trade on existing DEXs and integrate with lending markets.

Fundraising and Distribution

The 2017 ICO boom was built almost entirely on ERC-20. Projects could launch a token with a simple smart contract deployment, and investors could trade it on any supporting exchange. While regulatory scrutiny has changed the landscape, ERC-20 remains the default for token launches and airdrops.

Known Limitations

Approve Race Condition

The approve() function overwrites the previous allowance rather than adjusting it atomically. This creates a front-running vulnerability:

  1. Alice approves Bob for 1,000 tokens
  2. Alice submits a new approval reducing Bob's allowance to 500
  3. Bob sees the pending transaction and front-runs it by calling transferFrom() for the full 1,000 tokens
  4. Alice's new approval mines, setting the allowance to 500
  5. Bob calls transferFrom() again for 500 more

Result: Bob extracts 1,500 tokens instead of Alice's intended 500. The standard mitigation is the "approve to zero" pattern: set the allowance to 0 before setting a new value. USDT enforces this at the contract level. ERC-2612 (Permit) sidesteps the issue entirely with off-chain signatures.

Token Loss from Incompatible Contracts

ERC-20's transfer() function provides no notification to the receiving address. When tokens are sent to a contract that lacks token-handling logic, they become permanently stuck with no recovery mechanism. Documented losses exceed tens of millions of dollars across contracts like the BNB, SHIB, and HEX token addresses. Unlike ERC-721, which includes a safeTransferFrom() with a receiver callback, ERC-20 has no equivalent safety mechanism.

No Callback Mechanism

ERC-20 lacks hooks that notify contracts of incoming tokens. This means contracts cannot execute custom logic upon receiving tokens, cannot reject unwanted deposits, and every interaction with a third-party contract requires the two-step approve/transferFrom pattern (costing two transactions and double the gas fees).

Missing Return Value Bug

The specification requires transfer(), transferFrom(), and approve() to return a boolean. However, at least 130 deployed tokens (including USDT and BNB) return void instead. Contracts that check return values will revert when interacting with these tokens. OpenZeppelin's SafeERC20 library addresses this by accepting either empty returns or decoded true.

Standards That Build on ERC-20

ERC-20's limitations inspired several successor standards, each targeting specific gaps:

StandardPurposeKey Improvement
ERC-721Non-fungible tokensUnique token IDs, safeTransferFrom() with receiver callback
ERC-1155Multi-token standardSingle contract manages fungible and non-fungible tokens with batch transfers
ERC-4626Tokenized vaultsStandardized interface for yield-bearing vaults (vault shares are ERC-20 tokens)
ERC-2612Gasless approvalsOff-chain signatures replace on-chain approve() calls, saving gas and eliminating the race condition
ERC-223Token loss preventionReverts transfers to contracts that lack a token handler function

ERC-777 attempted to add hooks and operator authorization while remaining backward-compatible with ERC-20, but reentrancy vulnerabilities led to exploits (including the dForce/Lendf.Me attack in 2020), and the standard is now widely considered deprecated. For a broader look at how smart contract security is evaluated, see the glossary entry on smart contract audits.

ERC-20 Across Chains

The ERC-20 interface has become a de facto standard beyond Ethereum. Any EVM-compatible chain (BNB Chain, Polygon, Arbitrum, Avalanche) runs the same Solidity contracts with the same function signatures. BNB Chain calls its variant BEP-20, but the interface is identical: the same contract code deploys without modification.

Non-EVM chains use different token models entirely. Solana's SPL tokens are written in Rust, and Bitcoin-based systems like Taproot Assets and Runes operate on the UTXO model. Moving tokens between chains requires bridges, which introduce their own trust assumptions and security considerations.

This glossary entry is for informational purposes only and does not constitute financial or investment advice. Always do your own research before using any protocol or technology.