Building with USDC on Arc: One Token, Two Interfaces

Summary
Arc unifies the gas and token layers by making USDC both the native gas asset and an ERC-20 token. Every transaction and contract call runs on USDC, while the same balance is accessible through a standard ERC-20 interface, no dual-token juggling required. A precompiled contract keeps the native and ERC-20 states perfectly synchronized, preserving consistency across app logic and gas usage. For developers, this dual-interface model simplifies user flows and accounting while maintaining full EVM compatibility. The result is a seamless “USDC as Gas” experience that removes friction between execution costs and asset utility, setting the stage for stable, dollar-denominated transactions across the Arc ecosystem.
Background
On most EVM chains, developers deal with two distinct assets:
- a native gas token (e.g. ETH, MATIC), and
- an ERC-20 token (e.g. USDC) that exists purely at the contract level.
Arc changes this pattern by making USDC both the native gas token and exposing an ERC-20 contract interface for it.
This means that when you’re building on Arc, every transaction and contract call is paid for in USDC, and that same USDC is available through an ERC-20 API for your app logic. Looking ahead, Arc plans to expand its fee payment mechanisms to accept additional stablecoins.
However, developers need to be mindful of which interface they are working with, the native balance or the ERC-20 contract interface — especially when using SDKs, libraries, or frameworks that assume a traditional EVM environment.
Overview
Arc’s design unifies the gas token and the token contract into one asset:

- USDC as the native gas token
- Lives in each account’s native balance field.
- Uses 18 decimals internally for EVM precision and gas metering.
Queried with calls like publicClient.getBalance(address).
- USDC as the ERC-20 contract
- Available at contract address
0x3600000000000000000000000000000000000000. - Exposes standard ERC-20 functions like balanceOf, transfer, and approve.
- Uses 6 decimals, consistent with USDC’s behavior on other chains.
- Queried through SDKs or libraries expecting an ERC-20 interface.
- Available at contract address
A precompiled contract handles ERC20 queries by forwarding calls (such as balanceOf) to the underlying native balance stored in the user’s EOA account. This mechanism keeps both representations, the native balance and the ERC20 state, perfectly in sync, so that USDC used for gas and token transfers reflects the same underlying value.
Understanding the Two Interfaces
Native Interface
When your SDK or library calls publicClient.getBalance() or similar RPC methods, it’s querying the native USDC balance.
This is the amount used to pay for gas, deploy contracts, or send raw transactions.
Example:
const nativeBalance = await client.getBalance({ address });
console.log(formatEther(nativeBalance)); // 18-dec precision
ERC-20 Interface
When you use an ERC-20 ABI or SDK method like balanceOf, you’re calling into the token contract interface.
This behaves just like USDC on other EVM chains and should be used for app logic — transfers, approvals, or displaying token balances.
Example:
const USDC_ADDRESS = "0x3600000000000000000000000000000000000000";
const tokenBalance = await client.readContract({
address: USDC_ADDRESS,
abi: erc20Abi,
functionName: "balanceOf",
args: [address],
});
console.log(formatUnits(tokenBalance, 6));
Why It Matters When Using SDKs
Many developer SDKs including wallets, DeFi, or bridging frameworks implicitly assume:
- Native token = ETH, 18 decimals.
- USDC = ERC-20, 6 decimals.
On Arc, both of those assumptions are partially true, but they refer to the same underlying asset.
As a result:
- When your SDK calls getBalance(), it’s referencing USDC (native).
- When it calls balanceOf(), it’s also referencing USDC (ERC-20).
- Do not mix these two reads without adjusting for decimals or you’ll double-count the same funds.
If your SDK automatically displays both “native” and “ERC-20” balances, it may show two identical USDC balances — these are not separate tokens.
You’ll want to normalize your display logic or filter out duplicates.
Best Practices for Developers
Be explicit about the interface
When writing SDK wrappers or smart contracts, decide whether you’re reading the native or ERC-20 balance and stick to it.
Normalize decimals
If you ever convert between the two:
1e18 (native units) = 1e6 (ERC-20 units)
Use the ERC-20 interface for app-level logic
For user transfers, app interactions, and UI displays, rely on the ERC-20 interface (balanceOf, transfer, etc.) — this provides compatibility with other ecosystems and tools.
You never need to manually reconcile native and ERC-20 balances — Arc’s precompile maintains that parity automatically.
Conclusion
Arc’s design merges the gas layer and the token layer into one unified USDC asset. This unlocks simpler user flows, no need to manage a separate gas token, but it also requires developers to understand which interface their SDK is using at any given time.
When building on Arc:
- Treat native USDC as your gas token.
- Treat ERC-20 USDC as your token contract.
- And remember…they’re the same token, just expressed through two different decimal systems.
This awareness will help you avoid decimal mismatches, redundant reads, and UX inconsistencies as you integrate Arc’s “USDC as Gas” model into your applications.
