Ethereum & Smart Contracts

ERC Standards

ERC Standards

Module 4 of Ethereum & Smart Contracts


What Are ERCs?

ERC = Ethereum Request for Comments

ERCs are standards that define common interfaces, enabling:

  • Interoperability between contracts
  • Composability (DeFi legos)
  • Wallet support
  • Exchange listings

If everyone follows the same interface, everything works together.


ERC-20: Fungible Tokens

The most important standard. Enables tokens like USDC, UNI, LINK.

The Interface

interface IERC20 {
    // Total supply of tokens
    function totalSupply() external view returns (uint256);

    // Balance of an address
    function balanceOf(address account) external view returns (uint256);

    // Transfer tokens
    function transfer(address to, uint256 amount) external returns (bool);

    // Allowance: how much spender can spend from owner
    function allowance(address owner, address spender) external view returns (uint256);

    // Approve spender to spend tokens
    function approve(address spender, uint256 amount) external returns (bool);

    // Spend approved tokens
    function transferFrom(address from, address to, uint256 amount) external returns (bool);

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

The Approve/TransferFrom Pattern

Why two-step transfers?

Direct transfer: User → Recipient
  - User calls transfer()

DeFi interaction: User → Protocol → Action
  1. User approves protocol (approve)
  2. Protocol pulls tokens (transferFrom)
  3. Protocol does something

This lets protocols operate on your behalf.

Common Extensions

ExtensionPurpose
ERC-20PermitGasless approvals via signatures
ERC-20BurnableTokens can be destroyed
ERC-20PausableEmergency pause functionality
ERC-20SnapshotHistorical balance queries

ERC-721: Non-Fungible Tokens (NFTs)

Each token is unique. Used for digital art, collectibles, gaming.

Key Difference from ERC-20

ERC-20:  "You have 100 tokens"
ERC-721: "You own token #42, token #108, and token #3256"

The Interface

interface IERC721 {
    // Number of tokens owned
    function balanceOf(address owner) external view returns (uint256);

    // Owner of a specific token
    function ownerOf(uint256 tokenId) external view returns (address);

    // Transfer (requires approval)
    function transferFrom(address from, address to, uint256 tokenId) external;

    // Safe transfer (checks receiver can handle NFTs)
    function safeTransferFrom(address from, address to, uint256 tokenId) external;

    // Approve one token
    function approve(address to, uint256 tokenId) external;

    // Approve all tokens
    function setApprovalForAll(address operator, bool approved) external;

    // Events
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
}

Metadata Extension

interface IERC721Metadata {
    function name() external view returns (string memory);
    function symbol() external view returns (string memory);
    function tokenURI(uint256 tokenId) external view returns (string memory);
}

The tokenURI returns a link to JSON metadata:

{
  "name": "CryptoPunk #7804",
  "description": "An alien punk",
  "image": "ipfs://...",
  "attributes": [
    { "trait_type": "Type", "value": "Alien" }
  ]
}

ERC-1155: Multi-Token Standard

Combines fungible and non-fungible in one contract.

Use Cases

  • Gaming: Swords (NFT) + Gold (fungible) in one contract
  • Batch transfers: Move multiple token types atomically
  • Gas efficiency: Shared contract logic

The Interface

interface IERC1155 {
    // Balance of specific token ID for an owner
    function balanceOf(address account, uint256 id) external view returns (uint256);

    // Batch balance check
    function balanceOfBatch(
        address[] calldata accounts,
        uint256[] calldata ids
    ) external view returns (uint256[] memory);

    // Transfer single token type
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    // Transfer multiple token types
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

Comparison

FeatureERC-20ERC-721ERC-1155
Token types1Many (each unique)Many (fungible or not)
Batch transfersNoNoYes
Multiple tokens/contractNoYesYes
Gas efficiencyGoodPoorBest

ERC-4626: Tokenized Vaults

Standard for yield-bearing tokens (staking, lending, etc.)

The Problem Before

Every yield product had different interfaces:

  • aTokens (Aave)
  • cTokens (Compound)
  • yTokens (Yearn)

Wallets and aggregators had to integrate each separately.

The Solution

Standard vault interface:

interface IERC4626 is IERC20 {
    // Underlying asset (e.g., USDC)
    function asset() external view returns (address);

    // Total assets under management
    function totalAssets() external view returns (uint256);

    // Deposit assets, receive shares
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);

    // Withdraw assets by burning shares
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);

    // How many shares for X assets?
    function convertToShares(uint256 assets) external view returns (uint256);

    // How many assets for X shares?
    function convertToAssets(uint256 shares) external view returns (uint256);
}

Benefits

  • Universal vault interface
  • Easy DeFi aggregation
  • Standardized accounting

Other Important ERCs

ERC-2612: Permit (Gasless Approvals)

Approve via signature instead of transaction:

function permit(
    address owner,
    address spender,
    uint256 value,
    uint256 deadline,
    uint8 v, bytes32 r, bytes32 s
) external;

User signs message, protocol submits it → saves gas for user.

ERC-4337: Account Abstraction

Smart contract wallets with:

  • Social recovery
  • Gas sponsorship
  • Batch transactions
  • Any signature scheme

ERC-6551: Token Bound Accounts

NFTs that own assets:

NFT #42 owns:
  - 100 USDC
  - NFT #101
  - 0.5 ETH

Transfer NFT #42 → Transfer everything it owns

ERC-7201: Namespaced Storage

Safe storage layout for upgradeable contracts.


Creating an ERC-20 Token

Using OpenZeppelin:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken is ERC20 {
    constructor() ERC20("My Token", "MTK") {
        _mint(msg.sender, 1000000 * 10**18);  // 1M tokens
    }
}

That's it! Full ERC-20 implementation in 10 lines.


Why Standards Matter

Interoperability

Any ERC-20 token works with:
  - Every DEX (Uniswap, Curve, etc.)
  - Every wallet (MetaMask, Rainbow, etc.)
  - Every lending protocol (Aave, Compound, etc.)
  - Every bridge
  - Every aggregator

Composability

DeFi "money legos":

1. Deposit USDC into Aave → get aUSDC (ERC-20)
2. Deposit aUSDC into Yearn → get yvUSDC (ERC-4626)
3. Use yvUSDC as collateral on Maker → get DAI (ERC-20)

All possible because of standards.

Key Takeaways

  1. ERC-20 is foundational — fungible tokens
  2. ERC-721 powers NFTs — unique tokens
  3. ERC-1155 is versatile — multiple token types
  4. ERC-4626 standardizes yield — vaults
  5. Standards enable composability — the DeFi magic
  6. Use OpenZeppelin — don't reinvent the wheel

Questions to Consider

  1. Why does ERC-20 need approve + transferFrom?
  2. When would you use ERC-1155 vs ERC-721?
  3. How does ERC-4626 simplify DeFi integrations?
  4. What new standards are emerging?