Live on Robinhood Chain — launch tokens with locked liquidity via MintPlus →Arc is coming — Circle’s stablecoin L1, mainnet Sept 16 · Get ready →T-16
Arc

Setting Up Hardhat and Foundry for Arc

Last verified: August 2026By the TrustSwap Team
Today on Arc: mainnet countdown, ARC token news, and every launch — covered daily. → Read today’s briefing

Arc is EVM-compatible, so Hardhat and Foundry work the way they always have — you add a network entry, point it at an RPC, and deploy. The two things that differ are the gas token and the decimals: fees on Arc are paid in USDC, and the native balance carries 18 decimals at the protocol level rather than the 6 you see on ERC-20 USDC elsewhere. This guide covers both toolchains end to end, with the mainnet parameters left as placeholders you must fill in before you touch production.

This page covers Arc in its first weeks of mainnet. Where something is still settling we say so rather than guess, and we revise this page as the ecosystem fills in. Last reviewed: September 2026.

What you need before you configure anything

Arc's public mainnet went live on September 16, 2026, and its public testnet has run since October 28, 2025. Testnet parameters are published and stable: chain ID 5042002, RPC endpoint rpc.testnet.arc.io, block explorer testnet.arcscan.app, and a faucet at faucet.circle.com. Mainnet chain ID, RPC URL and explorer URL are not published in this document — every mainnet value below appears as MAINNET-TBD, and you must substitute the real value from Circle's official documentation before deploying.

Do not guess a mainnet chain ID. A wrong chain ID does not fail loudly; it either refuses to broadcast or, worse, signs a transaction whose replay-protection domain does not match the chain you think you are on. Copy it from the source of record.

You also need testnet USDC to pay for gas. There is no ETH on Arc. Paste your deployer's 0x… address into the address field at faucet.circle.com, select the Arc testnet network, and confirm the drip landed with cast balance $DEPLOYER --rpc-url https://rpc.testnet.arc.io — a non-zero result means you are funded. A deploy from an unfunded account is the most common first-run error, and the RPC reports it as a bare insufficient funds for gas string rather than anything more helpful. If you have not used the testnet before, the Arc testnet guide walks through faucet access and network basics.

How do you configure Hardhat for Arc?

Hardhat needs a network entry with the RPC URL, the chain ID, and an accounts source. Nothing about Arc requires a custom Hardhat plugin for deployment itself; the standard hardhat-toolbox stack is sufficient. Below is a hardhat.config.ts with both networks defined.

// hardhat.config.ts
import type { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import * as dotenv from "dotenv";
dotenv.config();

const config: HardhatUserConfig = {
  solidity: {
    version: "0.8.26",
    settings: {
      optimizer: { enabled: true, runs: 200 },
      // Pin evmVersion explicitly rather than relying on the
      // compiler default, so verification metadata is reproducible.
      // Confirm the highest fork Arc accepts against Circle's docs.
      evmVersion: "cancun",
    },
  },
  networks: {
    arcTestnet: {
      url: process.env.ARC_TESTNET_RPC ?? "https://rpc.testnet.arc.io",
      chainId: 5042002,
      accounts: process.env.DEPLOYER_KEY ? [process.env.DEPLOYER_KEY] : [],
    },
    arc: {
      // MAINNET-TBD — substitute the published mainnet RPC URL.
      url: process.env.ARC_MAINNET_RPC ?? "MAINNET-TBD",
      // MAINNET-TBD — substitute the published mainnet chain ID.
      // Do not guess this value.
      chainId: Number(process.env.ARC_MAINNET_CHAIN_ID), // MAINNET-TBD
      accounts: process.env.DEPLOYER_KEY ? [process.env.DEPLOYER_KEY] : [],
    },
  },
};

export default config;

Pin evmVersion rather than inheriting it, for two reasons. A compiler default that emits an opcode the chain has not enabled produces a deploy that reverts with no useful message. And the default moves: Solidity's 0.8.30 release in May 2025 changed it from cancun to prague in step with Ethereum's Pectra upgrade, per the Solidity team's release announcement, so a routine compiler bump can silently change the bytecode you ship.

Which fork Arc mainnet accepts is worth checking directly rather than taking from a guide — the chain launched on September 16, 2026 and this is exactly the kind of detail that gets clarified in the first months. Circle's Arc developer documentation is the source of record; cancun above is a conservative starting point, not a verified ceiling. If a contract that deploys on Ethereum reverts on Arc with no revert reason, step the evmVersion down one and recompile before looking anywhere else.

A minimal deploy script and the commands to run it:

// scripts/deploy.ts
import { ethers } from "hardhat";

async function main() {
  const [deployer] = await ethers.getSigners();
  const balance = await ethers.provider.getBalance(deployer.address);

  // Native balance is USDC with 18 decimals at the protocol level.
  // formatEther is correct here; formatUnits(balance, 6) is not.
  console.log("deployer:", deployer.address);
  console.log("gas balance (USDC):", ethers.formatEther(balance));

  const factory = await ethers.getContractFactory("MyToken");
  const contract = await factory.deploy("MyToken", "MTK", 18);
  await contract.waitForDeployment();

  console.log("deployed to:", await contract.getAddress());
}

main().catch((e) => {
  console.error(e);
  process.exitCode = 1;
});
npx hardhat compile
npx hardhat run scripts/deploy.ts --network arcTestnet

# Mainnet — only after substituting the real chain ID and RPC.
npx hardhat run scripts/deploy.ts --network arc

A successful run prints Compiled N Solidity files successfully, then the script's deployer: and gas balance (USDC): lines, then deployed to: 0x…. If the gas balance prints as 0.0, stop — the deploy that follows will fail.

How do you configure Foundry for Arc?

Foundry keeps network configuration in foundry.toml under [rpc_endpoints], with chain selection handled per-command by the --rpc-url flag. Foundry reads the chain ID from the node rather than from config for most operations, which removes one class of mistake — but --chain still matters for verification and for cheatcodes that fork.

# foundry.toml
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc = "0.8.26"
optimizer = true
optimizer_runs = 200
evm_version = "cancun" # pin explicitly; confirm Arc's accepted fork

[rpc_endpoints]
arc_testnet = "https://rpc.testnet.arc.io"
arc = "${ARC_MAINNET_RPC}" # MAINNET-TBD — substitute the published mainnet RPC

[etherscan]
# Explorer verification config. testnet.arcscan.app is the known testnet
# explorer. Substitute Circle's published mainnet explorer URL for the
# mainnet entry, and see the note below on verifier compatibility.
arc_testnet = { key = "${ARCSCAN_API_KEY}", chain = 5042002, url = "https://testnet.arcscan.app/api" }
# arc = { key = "${ARCSCAN_API_KEY}", chain = "${ARC_MAINNET_CHAIN_ID}", url = "${ARC_MAINNET_EXPLORER_API}" }  # MAINNET-TBD

That [etherscan] block assumes Arcscan speaks the Etherscan verification API, because that is what Foundry's --etherscan-api-key path expects. Whether it does on mainnet is not something we will assert three weeks into a chain's life. Explorers split roughly two ways here: an Etherscan-compatible /api endpoint, which the config above targets, or a Blockscout backend, where you pass --verifier blockscout with a different URL path and no API key. Try Etherscan first; a rejection naming an unrecognised request, rather than a bytecode mismatch, means you want the other one.

# Environment
export ARC_TESTNET_RPC=https://rpc.testnet.arc.io
export DEPLOYER_KEY=0x...   # use a throwaway key on testnet

# Build and test
forge build
forge test -vvv

# Simulate against the live chain before broadcasting
forge script script/Deploy.s.sol:Deploy \
  --rpc-url arc_testnet

# Broadcast
forge script script/Deploy.s.sol:Deploy \
  --rpc-url arc_testnet \
  --private-key $DEPLOYER_KEY \
  --broadcast

# One-off deploy without a script
forge create src/MyToken.sol:MyToken \
  --rpc-url arc_testnet \
  --private-key $DEPLOYER_KEY \
  --constructor-args "MyToken" "MTK" 18

# Read the chain back
cast chain-id --rpc-url arc_testnet          # expect 5042002
cast balance $DEPLOYER --rpc-url arc_testnet  # native USDC, 18 decimals
cast gas-price --rpc-url arc_testnet

cast chain-id is worth running as a habit on mainnet, because it is the cheapest possible check that the RPC you configured is the chain you believe it is.

What actually differs from an Ethereum or Base setup?

Three things, and only three, matter in practice.

Gas is denominated in USDC. Fee estimation, msg.value, and every balance check still speak in the native unit — that unit is simply USDC rather than ether. On testnet, the average fee has run around $0.004 per transaction as of August 2026, so gas budgeting stops being a design constraint for most contracts. It does not stop being a correctness constraint: an unfunded deployer still fails.

The native token carries 18 decimals. This is the trap. ERC-20 USDC on Ethereum, Base and elsewhere is a 6-decimal token, so developers arriving from those chains reach for parseUnits(x, 6). On Arc's native gas balance that is wrong by twelve orders of magnitude. Use parseEther / formatEther for native amounts, and reserve 6-decimal handling for bridged ERC-20 USDC contracts if and when you interact with them. The 18-decimals explainer covers the full story, including why some wallets still label the native balance "ETH".

Finality is deterministic and sub-second. Arc uses Malachite consensus with roughly 780ms finality, so a transaction that is included is final — there is no probabilistic reorg window to wait out. In practice you can drop confirmation-count heuristics like waitForTransaction(hash, 12) down to a single confirmation for application code. Custodial and exchange-grade integrations are a different question: those desks set deposit-crediting policy from an issuer's published guidance rather than from the consensus property alone, and Circle has not published a recommended confirmation depth for Arc as of this writing. If you are crediting customer balances rather than updating a UI, take that number from Circle's documentation when it appears.

Everything else — opcodes, ABI encoding, CREATE2 address derivation, standard libraries — behaves as on any EVM chain. Arc's EVM compatibility page covers the equivalence claim in detail.

How should you structure testnet-to-mainnet promotion?

Treat the mainnet placeholders as a hard gate. The safest pattern is to keep mainnet values out of the config file entirely and require them from the environment, so a missing value fails at startup rather than silently deploying to the wrong place.

# .env.example — commit this, never commit .env
ARC_TESTNET_RPC=https://rpc.testnet.arc.io
ARC_MAINNET_RPC=            # MAINNET-TBD
ARC_MAINNET_CHAIN_ID=       # MAINNET-TBD — do not guess
DEPLOYER_KEY=
ARCSCAN_API_KEY=
# Preflight check before any mainnet broadcast
: "${ARC_MAINNET_RPC:?set ARC_MAINNET_RPC before deploying}"
: "${ARC_MAINNET_CHAIN_ID:?set ARC_MAINNET_CHAIN_ID before deploying}"
test "$(cast chain-id --rpc-url "$ARC_MAINNET_RPC")" = "$ARC_MAINNET_CHAIN_ID" \
  || { echo "chain id mismatch — refusing to deploy"; exit 1; }

Deploy to testnet, verify the bytecode, exercise the contract with real calls, then promote. Once the contract is live, verifying the source is the next step — see how to verify a contract on Arcscan for the flag-by-flag commands for both toolchains. If you are building the front end against the same contracts, viem and wagmi on Arc covers the client-side chain definition that has to match this config exactly.

FAQ

What is Arc's chain ID?

Arc's public testnet uses chain ID 5042002, with RPC endpoint rpc.testnet.arc.io. The mainnet chain ID is not stated in this guide — substitute the published value from Circle's official documentation and verify it with cast chain-id against the mainnet RPC before broadcasting anything.

Do I need a special Hardhat or Foundry plugin for Arc?

No. Arc is EVM-compatible, so standard hardhat-toolbox and stock Foundry handle compilation, deployment and testing with only a network entry added. Source verification is the one area that depends on explorer-side support rather than your toolchain: @nomicfoundation/hardhat-verify reaches Arcscan through a customChains entry you write yourself, and whether Arcscan answers the Etherscan-shaped request it sends is a property of the explorer, not the plugin. Arc mainnet is weeks old and that support is still settling, so budget for the explorer's manual upload form as a fallback on your first mainnet verification.

How do I get gas to deploy on Arc testnet?

Request testnet USDC from faucet.circle.com against your deployer address, then confirm the balance on testnet.arcscan.app. Gas on Arc is paid in USDC, not ETH; testnet transactions averaged roughly $0.004 as of August 2026, so a small faucet drip covers many deploys.

Why does my balance look 12 orders of magnitude off?

Because you formatted it with 6 decimals. Arc's native gas balance uses 18 decimals at the protocol level, unlike the 6-decimal ERC-20 USDC deployed on other chains. Use formatEther / parseEther for native amounts on Arc.

Can I fork Arc mainnet in tests?

Yes, using the standard --fork-url flag in Foundry or hardhat_reset forking config, pointed at an Arc RPC endpoint. Forking testnet works today against rpc.testnet.arc.io. Mainnet forking requires the MAINNET-TBD RPC URL — substitute Circle's published endpoint — and a node that serves state at the block you pin. Whether Arc's public mainnet RPC serves archive-depth state or prunes to a recent window is not yet documented, and the practical answer changes as providers stand up infrastructure. Test it: fork at a block a few thousand deep and read a historical balance. A missing-trie-node or unsupported-block error means you need an archive provider rather than the public endpoint.

Deploying a token on Arc? Team Finance handles minting, liquidity locks and vesting with audited contracts and flat USDC-quoted fees — see /arc/deploy-smart-contract for the deployment path, or /arc for the full Arc builder hub.Open Team Finance →

Sources: Circle documentation and Arc developer docs (arc.io, developers.circle.com) for chain parameters, testnet endpoints and consensus design; Hardhat documentation (hardhat.org) and Foundry Book (book.getfoundry.sh) for toolchain configuration syntax; the Solidity 0.8.30 release announcement (soliditylang.org, May 2025) for the change of default EVM version from cancun to prague; Solidity compiler documentation (docs.soliditylang.org) for evmVersion behaviour; Arc testnet explorer testnet.arcscan.app for network status.

Last verified: August 2026

Mainnet opens September 16. Be ready before it does.

Team Finance has secured $2.7B+ across 40,000+ projects since 2020. Mint the token, lock the liquidity, vest the team and run distribution — on a chain where the fees are quoted in dollars.

Launch a token on ArcLock your liquidityGet The Crypto App