This repo contains two implementations of ERC-20 tokens built with Foundry and a full Foundry workflow (unit, forked, and staging tests), broadcast scripts, and optional zkSync deployment via Makefile.
This project ships two ERC-20 tokens:
OurToken.sol– OpenZeppelin-based ERC-20 (audited reference implementation).ManualToken.sol– Hand-crafted ERC-20 focused on clarity and gas efficiency.
-
ManualToken:
- Uses custom errors instead of revert strings (smaller bytecode).
- Includes
burnandburnFrom(and emitsTransfer(to=0)). - Provides
approveAndCall(approve + callback) with checks (spender != 0,spender.code.length > 0). - Infinite allowance fast-path: if
allowance == type(uint256).max,transferFrom/burnFromskip the SSTORE. decimals()returns a compile-time constant (18).- Constructor expects whole tokens and multiplies internally by
10**decimals.
-
OurToken:
- Inherits from OpenZeppelin ERC-20 library directly.
- git
- Foundry (forge, cast, anvil)
Install or update:
curl -L https://foundry.paradigm.xyz | bash
foundryup# Clone
git clone https://github.com/web3pavlou/foundry-erc20-f23
cd foundry-erc20-f23
# Build
forge build
# Run all tests
forge test -vvManualToken:
# Terminal 1
anvil
# Terminal 2 (new shell)
forge script script/DeployManualToken.s.sol \
--rpc-url http://127.0.0.1:8545 \
--broadcast \
-vvOurToken:
# Terminal 1
anvil
# Terminal 2 (new shell)
forge script script/DeployOurToken.s.sol \
--rpc-url http://127.0.0.1:8545 \
--broadcast \
-vvThis project includes Make targets for zkSync. Minimal commonly used targets:
Run:
make deploy-zk
# or
make deploy-zk-manualTokenThe repo also contains examples for zkSync Sepolia targets; use them if you have the required env vars (see Environment).
Includes three categories of tests:
- Unit tests – run entirely on a local Anvil VM.
forge test --match-contract ManualTokenTest -vv- Forked tests – run against a live network state via RPC.
forge test --rpc-url $SEPOLIA_RPC_URL --match-contract <YourForkTest> -vv- Staging tests – execute the actual deploy scripts inside a fork and assert post-deploy state (e.g., initial mint, allowances,
approveAndCallbehavior).
forge test --rpc-url $SEPOLIA_RPC_URL --match-contract ManualTokenStagingTest -vvforge coverage
# For staging coverage, run with a fork URL:
forge coverage --rpc-url $SEPOLIA_RPC_URL --match-contract ManualTokenStagingTest forge fmtCreate a .env file in the project root:
dotenv
DEFAULT_ZKSYNC_LOCAL_KEY=0xabc123...deadbeef
ZKSYNC_SEPOLIA_RPC_URL=https://sepolia.era.zksync.dev
ZKSYNC_VERIFIER_URL=https://api-sepolia-era.zksync.network/api
ACCOUNT=your_foundry_account_name # if using account abstraction in scripts
SENDER=0xYourEOA
This project is licensed under the MIT License.
- Cyfrin Updraft – Thanks to @patrickalphaC for the educational material
- Foundry – For the dev tools