Overview
The WERC20 precompile provides a standard ERC20 interface to native Cosmos tokens through Cosmos EVM’s Single Token Representation architecture. Unlike traditional wrapped tokens that are functionally two separate tokens with unique individual properties and behaviors, Cosmos EVM’s WERC20 logic gives smart contracts direct access to native bank module balances through familiar ERC20 methods. Key Concept: TEST and WTEST are not separate tokens—they are two different interfaces to the same token stored in the bank module. Native Cosmos tokens (including TEST and all IBC tokens) exist in both wrapped and unwrapped states at all times, allowing developers to choose the interaction method that best fits their use case:- Use it normally through Cosmos bank send (unwrapped state)
- Use it like you would normally use ether or ‘wei’ on the EVM (native value transfers)
- Use it as ERC20 WTEST with the contract address below (wrapped state)
0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
Precompile Type: Dynamic (unique address per wrapped token)
Related Module: x/bank (via ERC20 module integration)
Gas Costs
Gas costs are approximated and may vary based on token complexity and chain settings.
Method | Gas Cost |
---|---|
name() | ~3,000 gas |
symbol() | ~3,000 gas |
decimals() | ~2,000 gas |
totalSupply() | ~2,500 gas |
balanceOf(address) | ~2,900 gas |
allowance(address,address) | ~3,000 gas |
transfer(address,uint256) | ~35,000 gas |
transferFrom(address,address,uint256) | ~40,000 gas |
approve(address,uint256) | ~30,000 gas |
deposit() | ~23,000 gas (no-op) |
withdraw(uint256) | ~9,000 gas (no-op) |
For a comprehensive understanding of how single token representation works and its benefits over traditional wrapping, see the Single Token Representation documentation.
Technical Implementation
Architecture Deep Dive
The ERC20 module creates a unified token representation that bridges native Cosmos tokens with ERC20 interfaces:Deposit/Withdraw Implementation Details
Since TEST and WTEST provide different interfaces to the same bank module token, deposit/withdraw functions exist for WETH interface compatibility:Understanding the Deposit/Withdraw PatternUnlike traditional WETH implementations where the contract holds wrapped tokens:
- Traditional WETH: Contract receives ETH and mints WETH tokens that it holds
- WERC20: Contract never holds tokens - all balances remain in the bank module
- Result: The precompile contract address has no balance; tokens stay with users
deposit()
and withdraw()
are no-ops - there’s no separate wrapped token state to manage.Real-World Example
Methods
Standard ERC20 Interface
All standard ERC20 methods are available and operate on the underlying bank balance:balanceOf
Returns the native token balance for a specific account (same as bank module balance).
transfer
Transfers tokens using the bank module (identical to native Cosmos transfer).
totalSupply
Returns the total supply from the bank module.
approve
/ allowance
/ transferFrom
Standard ERC20 approval mechanisms for delegated transfers.
name
/ symbol
/ decimals
Token metadata (e.g., “Wrapped Test”, “WTEST”, 18).
WETH Compatibility Methods
These methods exist for WETH interface compatibility:deposit
WETH compatibility function - Handles payable deposits for interface compatibility.
This function receives msg.value and immediately sends the coins back to the caller via the bank module, then emits a Deposit event. Since WTEST and TEST are the same underlying bank module token, no actual wrapping occurs - your balance is simply accessible through both native and ERC20 interfaces.
withdraw
No-op function - Included for interface compatibility with WETH contracts.
This function only emits a Withdrawal event but performs no actual token movement. Since WTEST and TEST are the same underlying bank module token, your native token balance is always directly accessible without any unwrapping process.
Usage Examples
DeFi Integration Example
Cross-Interface Balance Verification
Working with IBC Tokens
Solidity Interface & ABI
WERC20 Solidity Interface
WERC20 ABI