Launch an ERC-20 Token with Foundry


0) Requirements

  • Foundry v1.3.1+

    curl -L https://foundry.paradigm.xyz | bash
    foundryup
    

    (Foundry v1.3.1+ is required for Etherscan V2 verification.)


1) Create the project

mkdir launch-mha-token && cd launch-mha-token
forge init

This creates the standard Foundry project scaffold.


2) Install OpenZeppelin + set remappings

forge install OpenZeppelin/openzeppelin-contracts
echo 'remappings = ["@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/"]' >> foundry.toml

This ensures your IDE resolves OpenZeppelin imports correctly.


3) Write the ERC-20 contract

Rename the default file:

mv src/Counter.sol src/MagnetToken.sol

src/MagnetToken.sol:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MagnetToken is ERC20 {
    constructor(
        string memory name_,
        string memory symbol_,
        uint256 initialSupply
    ) ERC20(name_, symbol_) {
        _mint(msg.sender, initialSupply);
    }
}

Compile to confirm:

forge compile

4) Create a deploy script

Rename the sample script and update it:

mv script/Counter.s.sol script/DeployMagnetToken.s.sol

script/DeployMagnetToken.s.sol:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import {Script, console2} from "forge-std/Script.sol";
import {MagnetToken} from "../src/MagnetToken.sol";

contract DeployMagnetToken is Script {
    function run() public {
        vm.startBroadcast();
        // Example: 1,000,000 tokens (18 decimals)
        MagnetToken token = new MagnetToken("MAGNE Token", "MHA", 1_000_000 ether);
        vm.stopBroadcast();

        console2.log("address:", address(token));
        console2.log("totalSupply:", token.totalSupply());
    }
}


5) (Optional) Adjust tests

mv test/Counter.t.sol test/MagnetToken.t.sol

You can keep it empty or add your own token tests.


6) Create a Foundry keystore wallet

cast wallet import MyMagneAccount --interactive
# paste private key, set password

This account will be used for deployment.


7) Local dry-run (optional)

anvil
# new terminal:
forge script script/DeployMagnetToken.s.sol \
  --account MyMagneAccount \
  --fork-url https://rpc.testnet.magicalhash.com \
  --broadcast

You’ll see the deployed address and total supply logs.


8) Deploy to MAGNE L1 Testnet

Make sure the wallet has MAGNE L1 testnet tokens for gas.

forge script script/DeployMagnetToken.s.sol \
  --account MyMagneAccount \
  --rpc-url https://rpc.testnet.magicalhash.com \
  --broadcast

The output will include the transaction hash and your deployed contract address.

💡 You can adapt this for mainnet by switching to your mainnet RPC (e.g. https://rpc.magicalhash.com).


9) Verify the contract on MAGNE L1 explorer

MAGNE.AI uses Etherscan-compatible verification. You’ll need an API key:

forge verify-contract \
  --watch \
  --chain magne-ai-testnet \
  <0xYOUR_DEPLOYED_CONTRACT_ADDRESS> \
  src/MagnetToken.sol:MagnetToken \
  --verifier etherscan \
  --etherscan-api-key <YOUR_API_KEY>

Once verified, the contract page will be visible on MAGNE L1 explorer.


10) Quick Checklist

  • ✅ Token name / symbol ("MAGNE Token", "MHA")
  • ✅ Initial supply with ether (18 decimals)
  • ✅ RPC: https://rpc.testnet.magicalhash.com/
  • ✅ Wallet: MyMagneAccount
  • ✅ API key for verification
  • ✅ Testnet MAGNE balance for gas