Before you start
- Connect your tooling to Arc Testnet. See Connect to Arc.
- Have your contract source and its test suite ready.
- Get testnet USDC from the Circle Faucet to pay for gas and fund test transfers.
Steps
1
Audit balance and decimal assumptions
Search your contract for places that read
balanceOf or address.balance
and for any logic that compares or combines the two.- Convert before comparing: the ERC-20 view uses 6 decimals and the native view uses 18 for the same balance.
- Treat the ERC-20
balanceOfas inexact. It truncates anything below 1×10⁻⁶ USDC, so0.0000001USDC reads as0and100.0000001USDC reads as100. AbalanceOfof0does not mean the native balance is0.
2
Audit value transfers
Find every native send and every path that forwards value.
- Handle reverts: a native transfer can revert even with a sufficient balance, for example a transfer to the zero address, a transfer to or from a blocklisted address, or any transfer that would burn value.
- Don’t assume a call to a contract that forwards native value will succeed.
- Don’t transfer to
address(0); the transfer reverts with"Zero address not allowed".
3
Audit approvals and sweeps
Review allowances and any “sweep” logic.
- If a contract is meant to hold USDC only as an ERC-20 token and not to act on native value, don’t let it sweep its native balance. Native USDC and the ERC-20 USDC interface are the same asset, so a native sweep also moves the users’ ERC-20 USDC balance.
- Don’t pair “native” against the ERC-20 USDC interface in a liquidity pool. Both legs are the same asset, so the pairing is meaningless.
4
Audit DEX, AMM, and router contracts
If you are porting a DEX, AMM, or router (for example, Uniswap V2, Uniswap
V3, or a fork), there is no wrapped native token on Arc and no
WUSDC/WETH equivalent is needed.- Use the ERC-20 USDC contract directly as the pair token. Arc’s ERC-20
USDC interface at
0x3600000000000000000000000000000000000000is the canonical token. Treat it like any other ERC-20 in your pool, pair, and router code. - Do not deploy a
WUSDCwrapper contract. Wrapping the native asset on Arc fragments liquidity and can create user confusion. The ERC-20 interface already exposestransfer,approve, andtransferFromover the same underlying native balance. - Replace
WETH-style code paths. Removedeposit()/withdraw()wrap-and-unwrap calls, and replace anyWETHaddress constant in your router or periphery contracts with the ERC-20 USDC address above. Routes that accepted raw native value viamsg.valuecan either keep accepting native USDC, or be simplified to ERC-20-only flows since both interfaces move the same balance. Mind the decimals when you mix paths:msg.valueis denominated in 18-decimal native USDC, while the ERC-20 USDC interface uses 6 decimals, so convert between them explicitly (1 ERC-20 unit = 1012 wei) instead of assuming a 1:1 numeric value. - Do not bridge or deploy
USDC.e/wUSDCvariants. All USDC on Arc arrives via CCTP as the native asset. See Bridges for the bridging rules.
5
Audit SELFDESTRUCT usage
If your contract uses
SELFDESTRUCT, confirm it doesn’t depend on burning,
on sending value to a destructed account, or on retaining USDC afterward.- A contract’s USDC is its native balance, so self-destructing transfers that USDC to the beneficiary. On other chains the ERC-20 USDC balance would remain in the token contract.
- Self-destructing to yourself with a balance, to the zero address with a balance, to a blocklisted address, or to an already self-destructed account all revert.
- A non-zero-value call to a contract after it self-destructs reverts on Arc, even though it succeeds on Ethereum.
6
Test against an Arc RPC endpoint
Run your test suite against Arc Testnet, not a local EVM simulator. Tools
like Foundry’s
anvil run a standard EVM and cannot reproduce Arc’s
precompiles, EIP-7708 Transfer events, or USDC blocklist enforcement.7
Exercise the revert paths
Confirm your contract handles a blocklist revert gracefully using the seeded
blocklisted test address on the contract
addresses
page. A value transfer to or from it reverts at runtime, including when it is
the beneficiary of a
SELFDESTRUCT.