Learning Objectives – after this chapter you will be able to:
  • Explain fungibility and the purpose of the ERC-20 standard.
  • List the six required functions and two events of ERC-20.
  • Explain the approve → transferFrom flow and the role of decimals.
  • Read a minimal ERC-20 implementation in Solidity.
ERC-20
  • ERC-20 introduces a standard for fungible tokens: every unit of a token is exactly the same (in type and value) as every other unit. Just like ETH, 1 token is and will always be equal to any other 1 token of the same contract.
  • ERC-20 (Ethereum Request for Comments 20) was proposed by Fabian Vogelsteller in November 2015 (published as EIP-20, co-authored with Vitalik Buterin). It is a token standard that defines an API for tokens implemented in smart contracts.
  • Because all ERC-20 tokens share the same interface, any wallet, exchange or dApp that supports the standard can work with any ERC-20 token without custom code.
  • Well-known ERC-20 tokens include stablecoins such as USDC and DAI, wrapped Ether (WETH) and many governance tokens.
Example functionalities ERC-20 provides
  • Transfer tokens from one account to another.
  • Get the current token balance of an account.
  • Get the total supply of the token available on the network.
  • Approve whether an amount of tokens from an account can be spent by a third-party account.

If a smart contract implements the following methods and events, it can be called an ERC-20 token contract. Once deployed, it is responsible for keeping track of the created tokens on Ethereum.

ERC-20 Methods and Events
Function / EventPurpose
totalSupply() → uint256Total number of tokens in existence.
balanceOf(address owner) → uint256Token balance of an account.
transfer(address to, uint256 value) → boolSend tokens from the caller to to.
approve(address spender, uint256 value) → boolAllow spender to withdraw up to value from the caller.
allowance(address owner, address spender) → uint256Remaining amount spender may still withdraw from owner.
transferFrom(address from, address to, uint256 value) → boolMove tokens from from to to using an approved allowance.
event Transfer(from, to, value)Emitted on every transfer (including minting from the zero address).
event Approval(owner, spender, value)Emitted whenever an allowance is set.
Optional: name(), symbol(), decimals()Human-readable name, ticker and number of decimal places (commonly 18).
Understanding decimals and approve/transferFrom
  • Decimals: the EVM has no fractions, so balances are stored as whole numbers. With decimals = 18, a balance of 1,500,000,000,000,000,000 is displayed as 1.5 tokens.
  • Two-step spending: to let a dApp (e.g. an exchange contract) take tokens, the owner first calls approve(exchange, amount); later the exchange calls transferFrom(owner, exchange, amount). This is how contracts “pull” tokens.
  • Security tip: approve only the amount you need. Unlimited approvals to an untrusted or compromised contract can let it drain your tokens.
  • Tokens sent directly to a contract that was not designed to handle them can be lost forever – ERC-20 has no built-in way for receiving contracts to reject transfers.
Minimal ERC-20 Implementation (for learning)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

contract MyToken {
    string public name = "My Token";
    string public symbol = "MYT";
    uint8  public decimals = 18;
    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    constructor(uint256 initialSupply) {
        totalSupply = initialSupply * 10 ** decimals;
        balanceOf[msg.sender] = totalSupply;
        emit Transfer(address(0), msg.sender, totalSupply);       // minting
    }

    function transfer(address to, uint256 value) external returns (bool) {
        require(balanceOf[msg.sender] >= value, "insufficient balance");
        balanceOf[msg.sender] -= value;
        balanceOf[to] += value;
        emit Transfer(msg.sender, to, value);
        return true;
    }

    function approve(address spender, uint256 value) external returns (bool) {
        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }

    function transferFrom(address from, address to, uint256 value) external returns (bool) {
        require(balanceOf[from] >= value, "insufficient balance");
        require(allowance[from][msg.sender] >= value, "allowance exceeded");
        allowance[from][msg.sender] -= value;
        balanceOf[from] -= value;
        balanceOf[to] += value;
        emit Transfer(from, to, value);
        return true;
    }
}

For production, use a well-audited library implementation rather than writing a token from scratch.

Key Takeaways
  • ERC-20 = the common interface for fungible tokens on Ethereum.
  • Six functions (totalSupply, balanceOf, transfer, approve, allowance, transferFrom) and two events (Transfer, Approval).
  • approve + transferFrom lets contracts spend tokens on a user’s behalf; approve carefully.
Question / Answer (15 questions)

Answer : ERC-20 is the Ethereum standard interface for fungible tokens. It defines a common set of functions and events that a token contract must implement so that wallets, exchanges and dApps can interact with any compliant token in the same way.

Answer : Fungible means every unit is identical and interchangeable with any other unit of the same kind – one token is always worth exactly the same as another token of that contract, like one rupee coin and another.

Answer : Fabian Vogelsteller proposed it in November 2015; it was published as EIP-20 with Vitalik Buterin as co-author.

Answer : totalSupply(), balanceOf(owner), transfer(to, value), approve(spender, value), allowance(owner, spender) and transferFrom(from, to, value).

Answer : Transfer(from, to, value), emitted on every token transfer, and Approval(owner, spender, value), emitted whenever an allowance is set.

Answer : Because the EVM does not support fractions, balances are stored as integers. decimals tells user interfaces where to place the decimal point; with 18 decimals, 10^18 base units display as 1 token.

Answer : The token owner calls approve(spender, amount) to authorise a spender. Later the spender (often a contract) calls transferFrom(owner, recipient, amount), which moves the tokens and reduces the allowance. This allows contracts to pull tokens on behalf of users.

Answer : It returns the remaining number of tokens that the spender is still permitted to transfer from the owner’s balance using transferFrom.

Answer : By convention, newly created tokens are shown as a Transfer event from the zero address (address(0)) to the receiving account.

Answer : If a user approves an unlimited amount to a contract that is malicious, buggy or later compromised, that contract can transfer all of the user’s tokens without further permission.

Answer : The tokens may become permanently stuck, because the standard has no mechanism for the receiving contract to reject them, and the contract may have no function to send them out.

Answer : No, ETH is the native currency and does not implement the ERC-20 interface. dApps often use Wrapped Ether (WETH), an ERC-20 token backed 1:1 by ETH, to treat ETH like any other token.

Answer : USDC and DAI (stablecoins) and Wrapped Ether (WETH). Many governance tokens are also ERC-20 tokens.

Answer : Wallets, exchanges and other contracts can integrate any compliant token automatically without writing custom code for each one, which encourages interoperability and composability.

Answer : Token contracts often hold large value and cannot easily be changed after deployment. Audited, widely used implementations reduce the risk of subtle bugs such as incorrect allowance handling or overflow errors.
MCQ Test : Check Your Understanding (5 questions)

Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.

Q1. ERC-20 is a standard for:

Show Answer

Correct Answer : B. Fungible tokens
ERC-20 tokens are interchangeable (fungible); NFTs use ERC-721/1155.

Q2. Which function lets a third party move tokens after approval?

Show Answer

Correct Answer : D. transferFrom
transferFrom uses an allowance set by approve.

Q3. With decimals = 18, a stored balance of 2 × 10^18 displays as:

Show Answer

Correct Answer : A. 2 tokens
2 × 10^18 base units ÷ 10^18 = 2 tokens.

Q4. Minting new tokens is conventionally shown as a Transfer event from:

Show Answer

Correct Answer : C. The zero address
Transfer(address(0), recipient, amount) indicates newly created tokens.

Q5. Which of these is an OPTIONAL ERC-20 function?

Show Answer

Correct Answer : B. symbol
name, symbol and decimals are optional metadata functions.

Bibliography/References

The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.

  1. Vogelsteller, F., & Buterin, V. (2015). ERC-20: Token Standard. Ethereum Improvement Proposals, no. 20. https://eips.ethereum.org/EIPS/eip-20
  2. ethereum.org. (n.d.). ERC-20 Token Standard. Ethereum Developer Documentation. https://ethereum.org/en/developers/docs/standards/tokens/erc-20/
  3. Solidity Team. (n.d.). Solidity Documentation. https://docs.soliditylang.org/
  4. Solidity Team. (n.d.). Security Considerations. Solidity Documentation. https://docs.soliditylang.org/en/latest/security-considerations.html
  5. Antonopoulos, A. M., & Wood, G. (2018). Mastering Ethereum: Building Smart Contracts and DApps. O’Reilly Media.