ERC-20 Token
Tier: Free
Component: @web3marketlabs/components
Version: 0.1.0
Fungible token with configurable mint, burn, and pause capabilities. Built on OpenZeppelin Contracts v5.1.0 with ERC20, ERC20Burnable, ERC20Permit, ERC20Pausable, and AccessControl.
w3m add tokenParameters
The following parameters are collected by the interactive wizard when you run w3m add token. All parameters can also be passed as CLI flags.
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
tokenName | string | 'My Token' | Yes | Token name (used in contract constructor and ERC-20 metadata) |
tokenSymbol | string | 'MTK' | Yes | Token symbol (used in contract constructor and file naming) |
mintable | boolean | true | No | Enable minting (adds MINTER_ROLE and mint() function) |
burnable | boolean | true | No | Enable burning (inherits ERC20Burnable) |
pausable | boolean | false | No | Enable pausing (adds PAUSER_ROLE, pause(), unpause()) |
initialSupply | string | '1000000' | No | Initial token supply (minted to deployer, multiplied by 10 ** decimals()) |
Generated Files
The module generates the following files from Handlebars templates. File paths use the tokenSymbol parameter for naming.
| Template | Output Path | Category |
|---|---|---|
Token.sol | contracts/src/{{tokenSymbol}}Token.sol | contract |
Token.t.sol | contracts/test/{{tokenSymbol}}Token.t.sol | test |
DeployToken.s.sol | contracts/script/Deploy{{tokenSymbol}}Token.s.sol | script |
useToken.ts.hbs | src/hooks/useToken.ts | hook |
TokenBalance.tsx.hbs | src/components/TokenBalance.tsx | component |
TokenTransfer.tsx.hbs | src/components/TokenTransfer.tsx | component |
TokenMint.tsx.hbs | src/components/TokenMint.tsx | component |
For example, with tokenSymbol: 'GOLD', the contract file is generated at contracts/src/GOLDToken.sol and the deploy script at contracts/script/DeployGOLDToken.s.sol.
Solidity Dependencies
| Package | Version |
|---|---|
@openzeppelin/contracts | ^5.1.0 |
Deploy Hook
The module registers a deploy hook so that w3m deploy knows how to deploy the token contract:
| Field | Value |
|---|---|
| Script | script/Deploy{{tokenSymbol}}Token.s.sol |
| Contract | {{tokenSymbol}}Token |
Generated Contract
The generated Solidity contract conditionally includes OpenZeppelin extensions based on your parameter choices:
- Always included:
ERC20,ERC20Permit,AccessControl - If
burnableis true:ERC20Burnable(adds publicburn()andburnFrom()) - If
mintableis true:MINTER_ROLE+mint(address to, uint256 amount)gated by role - If
pausableis true:ERC20Pausable+PAUSER_ROLE+pause()/unpause()gated by role
The constructor mints initialSupply * 10 ** decimals() tokens to the deployer address and grants all admin roles to the deployer.
Generated Hooks
The hook template generates typed React hooks that wrap Wagmi’s useReadContract and useWriteContract. All hooks are generated into src/hooks/useToken.ts.
Read Hooks
| Hook | Description |
|---|---|
useReadTokenName() | Read the token name |
useReadTokenSymbol() | Read the token symbol |
useReadTokenBalanceOf({ account }) | Read the balance of a given account |
useReadTokenTotalSupply() | Read the total supply |
Write Hooks
| Hook | Condition | Description |
|---|---|---|
useWriteTokenTransfer() | Always | Transfer tokens to an address |
useWriteTokenApprove() | Always | Approve a spender for a given amount |
useWriteTokenMint() | If mintable enabled | Mint tokens to an address |
useWriteTokenBurn() | If burnable enabled | Burn tokens from the caller’s balance |
All hooks accept an optional config parameter with chainId to specify which chain to interact with. Defaults to chain ID 31337 (local Anvil).
Usage Example
import { useReadTokenBalanceOf, useWriteTokenTransfer } from './hooks/useToken'
import { useAccount } from 'wagmi'
import { parseEther } from 'viem'
function TokenDashboard() {
const { address } = useAccount()
const { data: balance } = useReadTokenBalanceOf({ account: address! })
const { transfer, isPending } = useWriteTokenTransfer()
return (
<div>
<p>Balance: {balance?.toString()}</p>
<button
disabled={isPending}
onClick={() => transfer({
to: '0x1234...5678',
amount: parseEther('100'),
})}
>
Send 100 tokens
</button>
</div>
)
}Generated Components
| Component | File | Description |
|---|---|---|
TokenBalance | src/components/TokenBalance.tsx | Displays the connected wallet’s token balance |
TokenTransfer | src/components/TokenTransfer.tsx | Form for transferring tokens to an address |
TokenMint | src/components/TokenMint.tsx | Form for minting tokens (admin only) |