EVAL Engine

Bridging an ERC-20 between Base and Chromia, step by step

Moving an ERC-20 between an EVM chain and Chromia takes several steps across two toolchains: Hardhat on the EVM side and the chr CLI on the Chromia side. eval-token-bridge is our written walkthrough of that process, using a test token we deployed for the purpose. There is a Base Sepolia (testnet) version and a Base mainnet version.

The test token

The repo includes EvalTestToken.sol, a minimal OpenZeppelin ERC-20 named "Eval Test" with symbol EVAL. The deployer gets the admin and minter roles and an initial supply of one million tokens, and a mint function is restricted to MINTER_ROLE. A Hardhat task, deploy:eval_test, deploys it with optional Etherscan verification. Both files are meant to be dropped into Chromia's postchain-eif contracts project, which provides the bridge tasks used in the rest of the guide.

The steps

The guide walks through the full sequence:

  1. Deploy the ERC-20 on Base Sepolia (chain id 84532). In our run the token landed at 0xcB06F1D0d10b69eD7760bfe2299f5D5df0e764E5.
  2. Reference or deploy the bridge validator and bridge contract on Base Sepolia.
  3. Allow the token on the bridge with allowToken:bridge, and point the bridge at the Chromia token chain with setBlockchainRid:bridge.
  4. Query the token chain's constants with chr query as a sanity check.
  5. Propose the token on Chromia with propose_token, authenticating with an EVM wallet through --evm-auth, then look up the proposal to get the assigned asset_id.
  6. Propose the token-bridge mapping with propose_token_bridge, linking the asset id to the network id, bridge contract, token contract and a starting block height.

Once the proposal is approved under the chain's governance rules, the token is bridge-aware between Chromia and Base.

Inspecting and undoing

The guide also covers the parts that are easy to get stuck on. It shows how to find the directory chain and the EVM transaction submitter chain, and how to list every known bridge, which helps when debugging a mapping. It documents how to revoke a pending proposal and how to remove an active mapping with remove_token_bridge, including the network_bridge struct that call expects:

1struct network_bridge {
2 network_id: integer;
3 bridge_contract: byte_array;
4}

The mainnet version adds a section on querying ERC-20 deposits observed by the bridge and checking the resulting FT4 balance from the CLI, plus a troubleshooting section and a recap of the variables to replace.

Why we wrote it down

Each step produces an identifier (a token address, an asset id, a proposal id, a chain RID) that the next step needs. Writing the commands down in order, with real sample output and explorer links, means the next person bridging a token does not have to rediscover which value goes where.