Skip to content
Arc Mainnet6 min readJohn Davis

Arc USDC Gas Token Explained: 18 Decimals, 6 Decimals and One Balance

Arc USDC gas token explained: one balance, two interfaces. Native USDC at 18 decimals pays gas; the ERC-20 at 6 decimals does pool math. Never mix them.

Diagram of a single USDC balance on Arc Mainnet splitting into two interfaces. Native USDC at 18 decimals pays gas and carries msg.value; the ERC-20 interface at 0x3600000000000000000000000000000000000000 exposes the same money at 6 decimals for pool math. The example row shows 1.000000 USDC as 1,000,000,000,000,000,000 native wei and 1,000,000 ERC-20 units, with a warning not to pair the two interfaces or add msg.value to a balanceOf result.
One balance, two decimal conventions: divide the native figure by 10¹² to get the ERC-20 figure, and never mix the two in one sum.

The Arc USDC gas token is USDC itself — the asset you already hold — and Arc exposes it through two interfaces over one balance: a native balance at 18 decimals that pays for gas and moves through msg.value, and an ERC-20 interface at 6 decimals at 0x3600000000000000000000000000000000000000 for contracts that expect a token. There is no wrapped USDC on Arc, because there is nothing to wrap — and a pool pairing one representation against the other is not a market, it is a way to lose money to the first arbitrageur.

If you only take one thing from this page: 18 decimals for gas, 6 decimals for pool math, one balance behind both, never mix the two in the same calculation.

The two interfaces over one balance

Native USDC ERC-20 USDC
Address Not a contract — it is the chain's native asset 0x3600000000000000000000000000000000000000
Decimals 18 6
Used for Gas, msg.value, address.balance, payable transfer, transferFrom, approvals, pool math
Unit 1 USDC = 10^18 wei 1 USDC = 10^6 units
How you get it You already have it if you have USDC on Arc Same balance, read through the token interface

Both views report the same underlying holdings. If your wallet shows 250 USDC, a native balance read returns 250000000000000000000 wei and an ERC-20 balanceOf returns 250000000. Neither number is "the real one" — they are the same amount written at different scales, a factor of 10^12 apart.

Why the native asset is 18 decimals

Every EVM tool in existence assumes the native asset has 18 decimals. Block explorers, gas estimators, msg.value accounting, Solidity's 1 ether literal, viem's parseEther — all of them are hardcoded around 18. Keeping the native balance at 18 decimals means none of that tooling needs an Arc-specific fork, and a contract that does require(msg.value == 1 ether) behaves exactly as it does on Ethereum.

Why the ERC-20 interface is 6 decimals

USDC is a 6-decimal asset everywhere else, and every integration that consumes it — Uniswap pair math, lending markets, payment processors, accounting spreadsheets — assumes 6. Keeping the ERC-20 view at 6 decimals means those integrations do not need to be rewritten either.

Arc's design choice is therefore: make each interface look like the world expects it to look, and accept that the two views differ by 10^12. That is the entire trade-off, and it is the source of essentially every Arc integration bug.

Why there is no wrapped USDC on Arc

On Ethereum, "gas token" and "stablecoin" are different assets, so you need WETH to put ETH into a pool. On Arc they are the same asset, so wrapping would add a step that does nothing: you would deposit USDC and receive a claim on USDC, with a contract in the middle that can only ever hold the thing you already had.

So there is no WUSDC, no canonical bridge wrapper and no "unwrapped" variant to track. Anything advertising a wrapped USDC on Arc Mainnet is either a rebranded third-party receipt token or something you should inspect before touching. Addresses you can rely on are listed in Arc's contract addresses reference.

Why a USDC/USDC pool is meaningless

This is the practical trap. Suppose a tool treats the native 18-decimal balance as a token — by wrapping it, or by deploying a contract that echoes it — and then pairs that against the real 6-decimal ERC-20 USDC. You now have what looks like a USDC/USDC pair.

Three reasons it is not a market:

  1. Both sides are the same asset. A swap buys USDC with USDC. After the fee, the only possible outcome is a loss.
  2. The "price" is a decimal artifact. A pool with 18-decimal units on one side and 6-decimal units on the other presents a nominal ratio of 10^12 that has nothing to do with value.
  3. It is free money for arbitrageurs. Any mispricing created by the scaling mismatch is extractable, and whoever seeded the pool funds the extraction.

The corollary for launch teams: a legitimate USDC pair on Arc is your token against the 6-decimal ERC-20 USDC. That is what Arc Liquidity Pool Creator creates and what V2 pair math on Arc expects. If you see a pair whose both sides are USDC, treat it as broken tooling rather than an opportunity.

The Arc USDC gas token in practice: paying, pooling, transferring

Paying gas. Gas is charged in native USDC at 18 decimals, and Arc's fee market enforces a minimum maxFeePerGas of 20 Gwei. Transactions below the floor are dropped by the mempool with no error and no receipt — the most confusing failure mode on the chain. At the floor, 1,000 gas costs 0.00000002 USDC, so a 1,000,000-gas transaction costs 0.02 USDC. Arctools spreads the correct floor into every write, and the mechanics are documented in Arc's gas and fees reference.

Adding liquidity. Pool math uses the ERC-20 view. When you supply 5,000 USDC to a pair you are approving and transferring 5,000 × 10^6 units; the pool's reserves are stored at 6 decimals; and the LP tokens you receive are priced against that. Reading a pool's TVL while treating reserves as 18-decimal values makes every Arc pool look 10^12 times smaller than it is.

Transferring. transfer(recipient, amount) on the ERC-20 interface takes 6-decimal units. Sending 1000000000000000000 because you were thinking in wei sends one trillion USDC, which you do not have, and the transaction reverts.

Burning. Burning a native USDC balance is forbidden — value transfers to address(0) revert, and transfers to precompiles or self-destructed accounts revert too. The ERC-20 burn() path is unaffected, and SELFDESTRUCT moves the contract's native USDC balance to the beneficiary rather than destroying it. This is one of the entries in Arc's EVM differences reference.

A decimals checklist for developers

import { parseUnits, formatUnits } from "viem";

// Gas, msg.value, wallet balance: 18 decimals.
const gasFloor = parseUnits("0.5", 18); // native USDC budget for gas

// ERC-20 USDC at 0x3600…0000: 6 decimals.
const poolSide = parseUnits("5000", 6); // 5000000000 units

// Never convert between them by truncating or padding.
// Read the balance in the unit you are about to spend.
const nativeBalance = await client.getBalance({ address });   // 18 dp
const erc20Balance = await client.readContract({              // 6 dp
  address: "0x3600000000000000000000000000000000000000",
  abi: erc20Abi,
  functionName: "balanceOf",
  args: [address],
});

Rules that prevent almost every Arc decimal bug:

  1. Decide the unit at the boundary of your code, and name variables usdc6 or usdc18 so the compiler is not the only thing you are relying on.
  2. Use parseUnits(value, 6) for anything the ERC-20 interface will see and parseUnits(value, 18) for anything the chain's native accounting will see.
  3. Never send a native balance to address(0), and never treat address(0) as a burn address for gas-token funds.
  4. When displaying a number, check whether it came from getBalance or balanceOf before formatting it.

Common errors and what they mean

Symptom Likely cause
Pool TVL looks 10^12 too small Reserves read at 6 decimals but formatted as 18
Swap reverts immediately Amount passed in 18-decimal units to a 6-decimal interface
Transaction never confirms, no error maxFeePerGas below the 20 Gwei floor; the mempool dropped it
"Transfer to zero address" revert Someone tried to burn the native balance
Balance looks right in the wallet, wrong in your app Wallet is showing native (18 dp); app is reading ERC-20 (6 dp), or vice versa

Where this shows up in the Arctools flow

Every Arctools tool handles the conversion for you: you type amounts in USDC, and the tool applies the correct scale to the interface it is about to call — 18 decimals for the gas budget, 6 for the pool side. The places it matters most are creating a pool, adding liquidity, and airdropping native USDC, which distributes the native 18-decimal balance directly.

Read this alongside Uniswap on Arc Mainnet for how pools are structured on Arc, and the Arc vs Ethereum launch comparison for what a stable gas token changes about launch economics.

Arctools is not affiliated with Circle or the Arc Foundation. Arc Mainnet is chain id 5042, RPC https://rpc.mainnet.arc.io, explorer https://explorer.arc.io; connection details are in Arc's connect reference.

Covered in this post

Arc USDC gas tokenUSDC as gas tokenArc Mainnet USDC gasArc USDC decimalswrapped USDC ArcArc Mainnet EVMArc stablecoin L1USDC ERC-20 Arc MainnetArc gas fees USDC

Read next

Arc Mainnet

Launch Token Arc vs Ethereum: Cost, Gas Token, Finality and DEX Liquidity

Launch token Arc vs Ethereum: compare fees, gas token, finality, tooling and Uniswap availability before you choose which chain to deploy it on in 2026.

Read it
Arc Mainnet

Uniswap on Arc Mainnet: V2, V3, V4 and How Pools Are Created

Uniswap Arc Mainnet guide: V2, V3 and V4 are deployed, V2 carries 300+ pairs, and here is how Arctools uses V2 pairs for launches and liquidity. Plus the risks.

Read it
Liquidity

Impermanent Loss Explained for Launch Teams (With the Math)

Impermanent loss explained for launch teams: what it costs, how to estimate it with pool math before you commit, and why it matters more for new tokens.

Read it