ERC20 Module Reference
The ERC20 module (x/erc20
) implements Single Token Representation v2 (STRv2), ensuring seamless interoperability between Cosmos coins and EVM ERC-20 tokens. It automatically creates ERC-20 representations for IBC tokens and maintains bidirectional conversion.
Module Overview
Purpose: Provide unified token representation across Cosmos and EVM environments Key Functionality:- Automatic ERC-20 wrapper creation for Cosmos coins and IBC tokens
- Bidirectional token conversion (Cosmos ↔ EVM)
- Native token precompiles at deterministic addresses
- Dynamic precompile generation for IBC tokens
- ERC-20 allowance tracking for cross-environment compatibility
- Single token representation prevents fragmentation
Single Token Representation v2 (STRv2)
Problem Solved
Without STRv2, tokens exist in separate “worlds”:- Cosmos side: Bank module tracks
ibc/ABC...
denominations - EVM side: Separate ERC-20 contracts with different addresses
- Result: Token fragmentation, broken liquidity, complex accounting
STRv2 Solution
STRv2 ensures a single token representation:- IBC token arrives → Automatically gets ERC-20 wrapper at deterministic address
- User wants EVM access → Convert bank balance to ERC-20 (same total supply)
- User wants Cosmos access → Convert ERC-20 back to bank balance
- Result: Same token, accessible from both environments, unified liquidity
Configuration Methods
The ERC20 module is configured through genesis.json before chain launch.Method 1: Direct JSON Editing
Edit~/.evmd/config/genesis.json
directly:
Method 2: Using jq Command-Line Tool
From local_node.sh:247-248:Parameters
enable_erc20
What It Does: Master switch to enable/disable the entire ERC20 module functionality. Type:bool
Valid Values:
true
- Enable ERC-20 conversions and token pairs (recommended)false
- Disable all ERC-20 functionality
true
(params.go:26)
Configuration:
- When
true
: Users can convert between Cosmos and ERC-20 representations - When
false
: All conversions disabled, tokens stay in their native format - Cannot be changed after genesis without governance proposal
true
- Standard for EVM-compatible chainsfalse
- Pure Cosmos chain without EVM token bridging
permissionless_registration
What It Does: Controls who can register new token pairs (create ERC-20 wrappers for Cosmos tokens). Type:bool
Valid Values:
true
- Anyone can register token pairs (recommended for public chains)false
- Only governance can register token pairs (permissioned)
true
(params.go:27)
Configuration:
true
(permissionless):
- Any user can call
RegisterCoin
orRegisterERC20
messages - IBC tokens automatically get ERC-20 wrappers
- Fastest UX for new tokens
- Standard Ethereum-like behavior
false
(permissioned):
- Only governance proposals can create token pairs
- More control over which tokens get ERC-20 representations
- Slower onboarding for new tokens
- Useful for curated token lists
true
for public chains to match Ethereum UX
Genesis State
token_pairs
What It Does: Defines the mappings between Cosmos denominations and ERC-20 contract addresses. Type: Array ofTokenPair
objects
Structure: (token_pair.go:32-39)
OWNER_MODULE = 1
- Owned by erc20 module (native Cosmos token)OWNER_EXTERNAL = 2
- Owned by external EOA (native ERC-20 token)
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
- Standard address for native token (matches Ethereum convention)
Validation: (genesis.go:30-46)
- No duplicate ERC-20 addresses
- No duplicate denominations
- Valid Cosmos denom format
- Valid Ethereum address format
native_precompiles
What It Does: List of ERC-20 contract addresses that should be accessible as stateful precompiles for native Cosmos tokens. Type: Array of hex addresses (strings) Purpose: Enable EVM smart contracts to interact with native Cosmos tokens at deterministic addresses Configuration:- Each precompile address MUST have a corresponding enabled token pair (genesis.go:54-56)
- Precompile provides ERC-20 interface backed by bank module
IERC20(0xEeee...).transfer()
for native token
dynamic_precompiles
What It Does: Similar to native_precompiles but for IBC tokens that arrive dynamically after genesis. Type: Array of hex addresses (strings) Default:[]
(empty at genesis, populated automatically during IBC transfers)
Configuration:
- IBC token arrives via
ibc/transfer
module - ERC20 module automatically creates token pair with deterministic address
- Address is derived from IBC denom hash (token_pair.go:18-29)
- Dynamic precompile address added to list
- EVM contracts can now interact with IBC token
utils.GetIBCDenomAddress(denom)
to compute deterministic address from IBC denom
Example:
- IBC denom:
ibc/27394FB092D2ECCD56123C74F36E4C1F926001CEADA9CA97EA622B25F41E5EB2
- Derived ERC-20 address:
0x...
(deterministic from denom hash)
allowances
What It Does: Stores ERC-20 allowances (approve/transferFrom) that need to persist across Cosmos-EVM conversions. Type: Array ofAllowance
objects
Structure:
[]
(empty at genesis)
Configuration:
- No duplicate allowances
- Allowance must reference existing token pair
- Valid addresses and amounts
Complete Configuration Example
Based on local_node.sh:247-248:Runtime Operations
Query Token Pairs
Convert Tokens
Register New Token Pair
EVM Integration
Using Native Token in Solidity
Using IBC Token in Solidity
Common Issues and Solutions
Issue: Token Pair Not Found
Symptom:error: token pair not found for denom X
Cause: No ERC-20 wrapper exists for the Cosmos token
Solution:
Issue: Conversion Disabled
Symptom:error: token pair is not enabled
Cause: Token pair exists but enabled=false
Solution: Submit governance proposal to enable token pair
Issue: Precompile Not Accessible
Symptom: EVM calls to precompile address fail or return no code Cause: Address not innative_precompiles
or dynamic_precompiles
Solution:
- For native tokens: Add to
native_precompiles
in genesis - For IBC tokens: Ensure token pair exists and is enabled
Issue: IBC Token No ERC-20 Address
Symptom: IBC token arrives but no ERC-20 wrapper created Cause:enable_erc20=false
or module not properly initialized
Solution:
- Check
enable_erc20
parameter istrue
- Check module is in app.go and BeginBlockers/EndBlockers
Related Documentation
- Building Your Chain Guide - Main configuration walkthrough
- VM Module - EVM configuration
- Token Configuration Guide - Token economics setup
- IBC Module - IBC token handling
Source Code References
- Module Implementation: x/erc20
- Parameter Types: x/erc20/types/params.go
- Genesis State: x/erc20/types/genesis.go
- Token Pair Logic: x/erc20/types/token_pair.go
- IBC Callbacks: x/erc20/keeper/ibc_callbacks.go
- Precompile Management: x/erc20/keeper/precompiles.go
- Genesis Setup: local_node.sh:247-248
- ERC-20 Bytecode: x/erc20/types/constants.go:8