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

Which Token Standard Should You Use on 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 the token standards you already know compile and behave exactly as they do on Ethereum. The interesting decisions are about fit rather than syntax: a chain whose native gas asset is USDC at 18 decimals, and whose design centres on a dollar that earns, pushes you toward ERC-4626 far earlier than a general-purpose L1 would. This page covers which standard to pick and the Arc-specific integration hazards — not writing, compiling or deploying the contract, which belongs to [deploying a smart contract on Arc](/arc/deploy-smart-contract).

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.

Do the standard ERCs work unchanged on Arc?

Yes. Arc is EVM-compatible, so ERC-20, ERC-721, ERC-1155 and ERC-4626 are ordinary Solidity contracts that compile with the same compiler and behave identically once deployed. Token standards are application-layer conventions — interfaces plus expected event emissions — and nothing in them touches consensus. Arc's differences from Ethereum live below your contract: Malachite consensus, deterministic sub-second finality of roughly 780ms, and gas paid in USDC rather than a volatile native coin.

So OpenZeppelin, Solady and Solmate implementations are usable as-is, and audits of standard token code transfer over. What does not transfer automatically is your integration code — anything that assumed the native asset is 18-decimal ETH, or that a chain's stablecoin is a 6-decimal ERC-20. For the broader compatibility picture, see Arc's EVM compatibility.

ERC-20: the default, and its three sharp edges

ERC-20 is the right choice for any token where one unit is interchangeable with any other — project tokens, points, LP receipts, wrapped assets, stablecoins. It is the most widely integrated standard on Arc and everywhere else: wallets, indexers, DEX routers and lockers all assume it. An ERC-20 on Arc is the same job as one on Ethereum.

interface IERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address spender, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

Three details still bite. First, decimals() is not part of the core interface — it lives in the optional metadata extension and a token can legitimately omit it, so read it from IERC20Metadata and handle the revert rather than assuming 18. Second, some deployed tokens return no boolean from transfer, which is why SafeERC20 exists; use it in any contract touching tokens you did not write. Third, add ERC-2612 permit if you want signature-based approvals — it is the cheapest path to a one-transaction deposit flow and composes with the sponsorship patterns in gasless UX on Arc.

interface IERC20Permit {
    function permit(
        address owner, address spender, uint256 value,
        uint256 deadline, uint8 v, bytes32 r, bytes32 s
    ) external;
    function nonces(address owner) external view returns (uint256);
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

The EIP-712 domain separator includes the chain ID, so a separator cached at construction must be recomputed when the chain ID differs. On Arc that has a practical edge: the same bytecode deployed to testnet at chain ID 5042002 and then to mainnet produces different valid signatures, and a permit signed for one will not verify on the other. Arc's mainnet chain ID appears on this page as MAINNET-TBD — substitute the value Circle publishes in its official Arc documentation, and never guess it. OpenZeppelin's EIP712 base caches the separator against the chain ID it was built on and rebuilds when block.chainid differs; if you write your own, do the same.

What is the decimals hazard on Arc?

On Arc, USDC is the native gas asset and carries 18 decimals at protocol level, while ERC-20 USDC on other chains carries 6. Any code that moves a USDC amount between Arc and another chain, or between an Arc contract and an off-chain accounting system, must scale by 10^12 in the right direction. Getting the direction wrong is a million-fold error, not a rounding error.

The full treatment — how the native balance is represented, which wallets mislabel it, how to normalise across chains — is in USDC's 18 decimals on Arc. For your own contracts the rule is simpler: never hardcode a divisor, always read decimals() from the token, and normalise at the boundary.

/// @notice Normalise an arbitrary-decimal amount to 18-decimal fixed point.
function toWad(uint256 amount, uint8 tokenDecimals) internal pure returns (uint256) {
    if (tokenDecimals == 18) return amount;
    return tokenDecimals < 18
        ? amount * (10 ** (18 - tokenDecimals))
        : amount / (10 ** (tokenDecimals - 18));
}

One open question here shapes contract design, and we are not going to invent an answer to it. Every EVM chain whose native asset is also useful as an ERC-20 eventually grows a canonical wrapper — WETH is the archetype — or exposes the balance through a precompile at a fixed address. Whether Arc has either for native USDC, and at what address, is not something we can state three weeks into mainnet, and a wrong address here loses funds rather than reverting. Circle's Arc developer documentation is where that address appears if it exists; treat anything from a forum post or a third-party chain list as unverified.

Design so the answer does not block you: accept the gas asset via payable and msg.value, use a normal IERC20 address for everything else, and if your contract must treat the native balance as a token, put the wrapper behind a settable interface rather than an immutable constant.

ERC-721 and ERC-1155: unique items and mixed inventories

ERC-721 gives every token a unique tokenId with exactly one owner; ERC-1155 gives you many token IDs in one contract, each with a fungible balance per holder. Choose ERC-721 when each item genuinely differs and per-item provenance matters — a deed, a membership, a position NFT. Choose ERC-1155 when you are issuing many classes of semi-fungible items and want batch transfers and one deployment instead of dozens.

The ERC-1155 case gets stronger in an RWA context: if you issue 400 series of an instrument differing only by maturity, 400 ERC-721 contracts is an operational mistake and one ERC-1155 with 400 IDs is not.

interface IERC1155 {
    function balanceOf(address account, uint256 id) external view returns (uint256);
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external view returns (uint256[] memory);
    function setApprovalForAll(address operator, bool approved) external;
    function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external;
    function safeBatchTransferFrom(
        address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data
    ) external;
}

Both call back into recipient contracts (onERC721Received, onERC1155Received), which is a reentrancy surface: follow checks-effects-interactions and treat the receiver hook as hostile code. Both advertise support through ERC-165 supportsInterface, which is how a marketplace or locking contract decides what it is holding.

When should you reach for ERC-4626?

ERC-4626 standardises a tokenised vault: you deposit an underlying ERC-20 asset, you receive shares, and the share price rises as the vault accrues. It matters more on Arc than on a general-purpose chain because the asset most Arc vaults hold is a dollar already expected to earn — so "how many dollars is one share worth" becomes the ecosystem's central accounting question, and one interface for it saves every integrator a bespoke adapter.

interface IERC4626 is IERC20 {
    function asset() external view returns (address);
    function totalAssets() external view returns (uint256);
    function convertToShares(uint256 assets) external view returns (uint256);
    function convertToAssets(uint256 shares) external view returns (uint256);
    function previewDeposit(uint256 assets) external view returns (uint256);
    function previewRedeem(uint256 shares) external view returns (uint256);
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);
    function mint(uint256 shares, address receiver) external returns (uint256 assets);
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);
}

Two traps produce most vault incidents. The first is the inflation or "donation" attack: a first depositor mints one wei of shares, transfers a large amount of the underlying directly to the vault, and subsequent depositors round to zero shares. The mitigations are virtual shares and offset decimals — OpenZeppelin's implementation ships them, and you should not write your own vault maths without them. The second is confusing preview* with convertTo*: the preview functions include fees and are what a UI should quote, while convertTo is an idealised rate that excludes them. Quoting the wrong one is how a deposit screen shows a number the transaction does not honour.

Circle named Aave and Morpho among Arc's day-one apps, and vault shares are the natural interface for lending-style yield. We are deliberately not publishing a list of which Arc vaults expose ERC-4626 and at which addresses: it would be wrong within a week, and a stale vault address in a developer guide ends with someone's deposit in the wrong contract. Read addresses from each protocol's own documentation or app, and confirm what you are pointing at by calling asset() and totalAssets() before you integrate — a real 4626 vault answers both.

BlackRock is deploying BUIDL on Arc, and it is worth saying plainly that BUIDL is not an ERC-4626 vault share and should not be integrated as one. It is a permissioned instrument with transfer restrictions and an allowlist, which is a different problem: your contract has to be an approved holder, and a transfer that would succeed for an ordinary ERC-20 reverts. The specifics of that model on Arc are BlackRock's and Circle's to publish and had not settled as of this writing. If your design assumes free transferability, check whether the token is permissioned before you build on it.

A short decision rule

Fungible units, no yield accrual: ERC-20. Unique items with individual provenance: ERC-721. Many classes of semi-fungible items in one contract: ERC-1155. Deposit-and-accrue against a single underlying: ERC-4626, which is also an ERC-20, so vault shares stay transferable, lockable and quotable everywhere an ERC-20 is. If you are launching a token rather than integrating one, issuance and supply mechanics are in minting tokens on Arc.

Whichever you pick, the explorer is how you confirm a deployed contract is what you think it is. Open the address on Arcscan, go to the Read Contract tab, and call the identifying functions: name, symbol and decimals on an ERC-20; asset, totalAssets and convertToAssets on a vault; supportsInterface with the relevant ERC-165 selector on an ERC-721 or ERC-1155. A contract that reverts on decimals is an ERC-20 without the metadata extension — legal, and exactly the case your integration code has to handle.

FAQ

Does an ERC-20 on Arc need 18 decimals?

No. Your own ERC-20 can use any precision, and 18 remains the default wallets and DEX front-ends handle best. The 18-decimal fact that matters on Arc concerns the native USDC gas asset, which is 18 decimals at protocol level while ERC-20 USDC elsewhere is 6. That affects cross-chain accounting, not the design of a new token.

Can I use OpenZeppelin contracts on Arc?

Yes. Arc is EVM-compatible, so standard OpenZeppelin, Solady and Solmate libraries compile and deploy without modification. Check the Solidity version and EVM target your framework is set to, and avoid contracts that cache chain-ID-dependent values such as an EIP-712 domain separator computed at construction — those break when you redeploy the same bytecode from testnet (chain ID 5042002) to mainnet, whose chain ID appears here as MAINNET-TBD until you substitute the value published in Circle's official Arc documentation.

Is ERC-4626 required for a yield-bearing token on Arc?

No, but it is the interface integrators expect. A rebasing token that changes balances rather than share price is a legitimate alternative, at the cost of breaking accounting in any contract that stored a balance. ERC-4626 keeps balances constant and moves value into the exchange rate, which composes better with lending markets, lockers and aggregators.

Which standard should a locking or vesting contract expect?

Most locking infrastructure targets ERC-20 for liquidity and team allocations, with separate handling for ERC-721 because a position NFT — a Uniswap v3-style LP position — is a single non-fungible object rather than a balance. Check which standards a locker accepts before choosing your token type: an ERC-1155 issuance can be awkward to lock with tooling built for the other two.

Launching a standard ERC-20 on Arc without writing the contract yourself? Team Finance handles token creation, liquidity locks, team locks and vesting on 26 chains, with flat USDC-quoted fees and no percentage of your supply or liquidity.Open Team Finance →

Sources: Circle's Arc documentation and launch announcements for the day-one app list, gas model and finality figures; the EIP specifications for ERC-20, ERC-165, ERC-721, EIP-712, ERC-1155, ERC-2612 and ERC-4626 at eips.ethereum.org; OpenZeppelin Contracts documentation for the ERC-4626 inflation-attack mitigations and the EIP-712 domain-separator caching behaviour.

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