An ERC20 generator that ships nothing you didn't ask for
Five constructor arguments, one deployment transaction, an immutable fixed-supply token. The contract that lands on-chain has no owner, no mint function, no pause switch, no blacklist and no transfer hook.
The complete external surface is below. It is eleven functions, and you can read every one of them before spending anything.
~$80 platform fee, sent as msg.value.
Network gas is billed separately by the chain.
contract MyERC20 is ERC20 {
uint256 public immutable FEE;
address public immutable feeRecipient;
constructor(
string memory name_,
string memory symbol_,
uint256 initialSupply_,
uint8 decimals_,
uint256 fee_
) payable ERC20(name_, symbol_) {
// the whole supply, to the deployer
_mint(msg.sender,
initialSupply_ * 10 ** decimals_);
}
}Abridged for readability — fee handling omitted. The full source is submitted to the block explorer for verification at deployment time.
The five parameters
All fixed at construction. There is no path in the deployed bytecode to change any value in this table after the transaction confirms.
| Argument | Type | Accepts | Notes |
|---|---|---|---|
name_ | string | Free text, e.g. "My Awesome Token" | Not unique. Two contracts may share a name; only the address disambiguates. |
symbol_ | string | Conventionally 3–5 uppercase characters | Also not unique and not enforced on-chain. Check the DEX aggregators first. |
initialSupply_ | uint256 | Whole tokens, scaled by 10**decimals on mint | Minted in full to msg.sender in the constructor. Cannot be increased later. |
decimals_ | uint8 | 0–255, default 18 | A display divisor only. 18 matches ETH; 6 matches USDC. |
fee_ | uint256 | The platform fee, checked against msg.value | Set per chain by the app. Readable afterwards from the public FEE constant. |
The complete external surface
This is the entire ABI, not a highlight reel. The right-hand column is the more interesting one: a contract-level rug pull needs a function that is not there.
Present · 11 functions
name() → stringviewsymbol() → stringviewdecimals() → uint8viewtotalSupply() → uint256viewbalanceOf(address) → uint256viewallowance(address,address) → uint256viewtransfer(address,uint256) → boolnonpayabletransferFrom(address,address,uint256) → boolnonpayableapprove(address,uint256) → boolnonpayableFEE() → uint256viewfeeRecipient() → addressview
Absent by construction
mint(address,uint256)Supply is fixed at construction. Nothing can inflate it.
burn(uint256)No supply-reducing path either — totalSupply() is constant.
pause() / unpause()Transfers can never be halted, by anyone, for any reason.
owner() / transferOwnership()Not Ownable. No privileged address exists in the deployed code.
blacklist(address)No address can be prevented from sending or receiving.
setTax() / _update overrideNo transfer tax, reflection or sell-blocking hook.
upgradeTo(address)Not a proxy. The bytecode at that address is final.
What that does, and does not, guarantee
It guarantees the token contract itself cannot be used to mint against holders, freeze transfers, block an address or tax a trade — the mechanisms behind most contract-level rug pulls. It does not make any project trustworthy: the deployer still holds the entire supply and can sell it, and liquidity can still be pulled from an unlocked pool. Those are wallet and pool behaviours, not contract behaviours, and no ERC20 can prevent them.
Supply and decimals, precisely
The most common misunderstanding in ERC20 land. Decimals are a display convention — the EVM only ever stores integers.
18
The default
Matches ETH and almost every DeFi token. One token is stored as 10^18 base units, giving eighteen digits of fractional precision.
6
Stablecoin style
USDC and USDT use six. Smaller integers in call data, and fractional cents stay representable. Some tooling still assumes 18 — test before committing.
0
Indivisible
Whole units only. Sensible for tickets, credits or membership counts where half a token is meaningless.
Worked example — a supply of one million at the default eighteen decimals:
you enter 1,000,000
minted as 1000000 * 10**18
= 10^24 base units
totalSupply() returns that integer, forever
a wallet shows 1,000,000 MYT (divides by 10**18)Platform fee per network
Identical bytecode on all 15 mainnets. The amount below is sent as msg.value and targets the same ~$80 everywhere. Network gas is charged on top of every figure in this list and is set by the chain, not by us.
- L1
Ethereum
0.02 ETH · ≈$80
- L2
Base
0.02 ETH · ≈$80
- L1
Monad
2500 MON · ≈$80
- L2
MegaETH
0.02 ETH · ≈$80
- L2
Robinhood Chain
0.02 ETH · ≈$80
- sidechain
BSC
0.075 BNB · ≈$82.5
- L2
Arbitrum
0.02 ETH · ≈$80
- L2
Optimism
0.02 ETH · ≈$80
- sidechain
Polygon
400 POL · ≈$80
- L1
Avalanche
4 AVAX · ≈$80
- L1
Fantom
500 FTM · ≈$75
- sidechain
Gnosis
80 XDAI · ≈$80
- parachain
Moonbeam
450 GLMR · ≈$81
- L2
World Chain
0.02 ETH · ≈$80
- L2
Blast
0.02 ETH · ≈$80
Native amounts are retuned periodically against market prices, so the dollar column is approximate. Your wallet shows the exact total — fee plus gas — before you sign.
Against rolling your own
If you write Solidity, the honest comparison is Remix or Foundry — not an agency quote. Here is what the fee is actually buying.
| Step | EVMint | Remix / Foundry |
|---|---|---|
| Contract source | Fixed template, no admin functions | Pick a template and audit it yourself for backdoors |
| Toolchain | None | solc version pinning, optimizer runs, a deploy script |
| Deploying | One confirmation, gas estimated for you | Pay gas, debug a revert, pay gas again |
| Verification | Submitted automatically per explorer | Flatten the source, match settings, submit by hand |
| Multi-chain | Switch the network selector | Re-run and re-verify for every chain |
| Liquidity | Router calls wrapped in the Liquidity page | Call addLiquidityETH yourself and get the ordering right |
| Cost | ~$80 platform fee, plus gas | Gas only — but unpredictable, and paid per attempt |
| Prerequisite | None | Solidity, and enough Web3 to debug it |
Why the standard is worth conforming to
ERC20 — Ethereum Request for Comments 20, finalised as EIP-20 in 2015 — is an interface, not an implementation. It specifies six functions and two events and says nothing about how you implement them. That minimalism is why every wallet, DEX router, lending market and indexer in the EVM ecosystem can integrate a token it has never seen before, with no bespoke work on either side.
The corollary is that conforming to the interface says nothing about behaviour. A honeypot that reverts on sell, a token with a 30% transfer tax, and a token whose owner can mint at will are all perfectly valid ERC20s. That is precisely why the absent-functions list above is the part worth reading.
OpenZeppelin's implementation is why most of the ecosystem does not write this from scratch. It handles the allowance edge cases, zero-address checks and overflow semantics that hand-rolled ERC20s have historically got wrong, and it has been reviewed continuously for years. EVMint uses it unmodified.
Every chain listed above runs the same virtual machine, so identical bytecode behaves identically on Base, Arbitrum, Polygon or BSC; only gas, block time and surrounding liquidity differ. If you want the same deployment explained from first principles, the cryptocurrency creator page covers it, and the meme coin creator page covers launch-day mechanics.
Technical FAQ
A single contract extending OpenZeppelin's ERC20 implementation. The constructor mints the entire supply to msg.sender, forwards the platform fee, and returns. The resulting external surface is the nine ERC20 methods plus two public view constants, FEE and feeRecipient. There is no Ownable, no AccessControl, no Pausable and no upgrade proxy.
Your token is built on OpenZeppelin's ERC20 implementation — audited, and among the most widely reviewed Solidity in existence. On top of it sits a short constructor that mints your supply and forwards the platform fee, and that is the entire contract. It is source-verified on the block explorer immediately after deployment, so you can read the exact deployed code rather than take anyone's word for it.
You supply a whole-token count. The constructor scales it by 10**decimals and mints that many base units to the deployer. With the default 18 decimals, a supply of 1,000,000 becomes a totalSupply() of 1000000 * 10**18 base units. Wallets and explorers divide by 10**decimals again for display.
No. There is no mint function and no burn function in the deployed contract, so totalSupply() returns the same value forever. Holders can send tokens to a dead address to remove them from circulation, but totalSupply() will not reflect that.
A platform fee of roughly $80 equivalent, sent as msg.value on the deployment transaction in the chain's native token — 0.02 ETH on Ethereum, Base, Arbitrum and Optimism, 0.075 BNB on BSC, 400 POL on Polygon. Network gas is charged separately on top by the chain: a few cents on a Layer 2, several dollars on Ethereum mainnet under load.
The bytecode is identical everywhere, so the choice is about gas, liquidity depth and where your users already are. Ethereum mainnet has the deepest liquidity and the highest gas. Base, Arbitrum and Optimism run the same EVM for a fraction of the cost. The platform fee targets the same figure on every network.
Yes. It is a standard ERC20, so any wallet that speaks the standard — MetaMask, Rabby, Trust Wallet, Coinbase Wallet — will import it from the contract address alone and display balances using the name, symbol and decimals stored on-chain.
Five arguments, one transaction
Fill in the form without connecting a wallet. Nothing is charged until you sign the deployment.