Arc is an EVM-compatible Layer-1 blockchain. Solidity, Foundry, Hardhat, Viem,
ethers.js, and standard Ethereum wallets work without modification, and you can
deploy existing contracts unchanged in most cases. Arc targets the Osaka
hard fork as its baseline and ships select features from Ethereum’s upcoming
Amsterdam hard fork ahead of upstream, notably
EIP-7708 (standard Transfer logs
for native value movements).
This page is the complete reference for where Arc’s protocol-level behavior
diverges from Ethereum. Comparisons below are against Ethereum at the Osaka
hard fork, Arc’s baseline. Most differences are transparent to application code,
but a few change execution semantics in ways that matter when you port a
contract. If you are porting an existing contract, start with the
Porting contracts to Arc checklist.
Tools that locally simulate the EVM (such as Foundry’s anvil) run a standard
EVM, not Arc’s, so they cannot reproduce Arc-specific behavior. Features that
depend on it (the native-coin precompiles, EIP-7708 Transfer events, and
USDC blocklist enforcement) only surface when you test against an Arc RPC
endpoint.
USDC as the native gas token
Arc uses USDC as its native token. The single most important thing to understand
is that native USDC and the ERC-20 USDC interface are the same asset, not
two separate tokens that happen to share a name.
| Interface | Decimals | Used for |
|---|
| Native | 18 | Gas accounting, native sends, and msg.value |
| ERC-20 | 6 | application-level transfers, approvals, and allowances |
The ERC-20 interface lives at the
USDC contract address and provides
familiar functions such as transferFrom, approve, and allowance management.
A native send and an ERC-20 transfer both move the same underlying balance.
Because both interfaces operate on one balance, USDC.balanceOf(addr) and
addr.balance are two views of the same value. They use different decimals (6
vs 18), so never compare or mix their raw values without converting first.
This single-asset model has consequences that do not exist on other EVM chains:
- The ERC-20 view truncates, so it is not exact. The 6-decimal
balanceOf
drops anything below 1×10⁻⁶ USDC, so a native balance of 0.0000001 USDC
reads as 0 and 100.0000001 USDC reads as 100. A balanceOf of 0 does
not imply a native balance of 0.
- 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).
For the conceptual model, including EURC and USYC support, see
Stablecoin native model. For how
balance changes surface as events, see
USDC system events.
Execution and opcode differences
| Behavior | Ethereum (Osaka) | Arc | Developer impact |
|---|
PREVRANDAO | Beacon chain RANDAO mix | Always returns 0 | No onchain randomness. Use an oracle or verifiable random function (VRF). |
SELFDESTRUCT | EIP-6780 semantics | EIP-6780 plus native value rules; emits a Transfer log on success (see SELFDESTRUCT) | Several patterns that succeed on mainnet revert on Arc. |
Non-zero-value CALL to a self-destructed account | Succeeds; value credited | Reverts (a transfer to a destructed account is a forbidden burn) | The largest semantic departure. See SELFDESTRUCT. |
parentBeaconBlockRoot / EIP-4788 | Beacon-roots contract returns the parent beacon root | Set to the parent execution block hash; the beacon-roots contract is omitted, so reads return empty (0x) | Do not treat the beacon-roots oracle as functional or as a randomness source. |
| Blob transactions (EIP-4844, type-3) | Supported | Not supported; the mempool rejects type-3 transactions | Do not submit blob transactions. BLOBHASH returns 0 and BLOBBASEFEE returns 1. |
| Withdrawals (EIP-4895) | May be present | Always empty | block.withdrawals is always empty. |
EIP-7702 set-code transactions, CREATE2 (including EIP-7610 residual-storage
behavior), and EIP-2935 historical block hashes all behave as on Ethereum. In
particular, the EIP-2935 block-hash-history contract is deployed and functional,
unlike the EIP-4788 beacon-roots contract noted above.
Value transfer rules
Because the native token is USDC, value transfers are subject to rules that do
not exist on a standard EVM chain. A native transfer can revert even when the
sender has sufficient balance.
- Transfers to the zero address are forbidden. A value-bearing transfer to
0x0 reverts with "Zero address not allowed"; a zero-value transfer to
0x0 succeeds. (Mint and burn, the only operations that involve 0x0, go
through the native-coin precompile.)
- Burning is forbidden. Self-destructing to yourself with a balance, or
transferring value to an account that has already self-destructed, reverts.
- The blocklist is enforced at runtime. A value transfer to or from a
blocklisted address reverts. An included transaction that reverts on a
blocklist check still consumes gas.
- Sending native value to a contract is not guaranteed to succeed. A call to
a contract that forwards native value can revert for any of the reasons listed
here, which breaks a common DeFi assumption.
- Sending to an address with no code (
EXTCODESIZE == 0) succeeds and emits
a Transfer log. Sending value to a precompile address reverts.
A liquidity pool that pairs native USDC against the ERC-20 USDC interface (as
if they were two assets) is meaningless on Arc, because they are one asset.
Review ported DeFi for this assumption.
SELFDESTRUCT
SELFDESTRUCT is allowed on Arc, including during contract deployment, and
follows EIP-6780 (the account is
fully deleted only if it was created in the same transaction). A self-destruct
reverts when its value transfer would violate a native value rule:
| Condition | Result |
|---|
| Beneficiary is the contract itself, with a balance | Reverts |
| Beneficiary is the zero address, with a balance | Reverts |
| Source or beneficiary is blocklisted | Reverts |
| Beneficiary has already self-destructed | Reverts |
| Balance is zero (any beneficiary) | Succeeds |
Three behaviors differ from every other EVM chain and deserve attention:
1. Self-destructing a contract that holds USDC moves that USDC out. On Arc a
contract’s USDC is its native balance, held in the account, so SELFDESTRUCT
transfers it to the beneficiary. On other chains the contract’s ERC-20 USDC
balance lives in the token contract and is unaffected by self-destruct.
2. A non-zero-value call to a self-destructed account reverts. On Ethereum,
sending value to an address that self-destructed earlier in the same transaction
succeeds. On Arc it is treated as a transfer to a destructed account, a
forbidden burn, and reverts.
// Within one transaction:
contractA.selfDestruct(payable(b)); // succeeds; emits Transfer(A, B)
// Later in the same transaction, any non-zero-value send to A:
(bool ok, ) = address(contractA).call{value: 1}(""); // reverts on Arc
3. A successful self-destruct that moves a balance emits a Transfer log.
Unlike Ethereum, the moved native value is recorded as an
EIP-7708 Transfer log from the
system emitter (18 decimals). Index it like any other native movement; see
USDC system events.
Native USDC Transfer events (EIP-7708)
On a standard EVM chain, a plain native send emits no log. Arc’s
EIP-7708 implementation emits a
standard ERC-20 Transfer log from a system address for every native USDC
movement: native sends, contract endowments, self-destruct transfers, and the
precompile-backed mint, burn, and transfer operations. This gives indexers one
universal record of balance changes.
The system emitter log uses 18 decimals and is distinct from the ERC-20 USDC
contract’s own 6-decimal Transfer. Match on the emitter address so you do not
count the same movement twice. See
USDC system events for emitter addresses,
the exact log format, and indexing guidance.
Fee market and block behavior
- The base fee is paid to the block beneficiary, not burned. Arc has no
EIP-1559 burn. Both the base fee and the priority fee are credited to the
block’s beneficiary.
- The next block’s base fee is published in the parent header’s
extra_data
(an 8-byte big-endian value). Read it there rather than re-deriving it. The
fee is computed from an exponentially smoothed view of gas usage and is
clamped to bounded minimum and maximum values, so it moves predictably. See
Stable fee design and
Gas and fees.
- Block timestamps are non-decreasing, not strictly increasing. Timestamps
come from the proposer’s wall clock at one-second granularity, so sub-second
blocks may share a timestamp. Use the block number for ordering, and do not
assume
block.timestamp strictly increases between blocks.
- Finality is deterministic and instant. Transactions finalize on inclusion;
offchain systems can act after a single confirmation. See
Deterministic finality.
Known limitation: draining an empty account
A transfer that would leave an account with a zero balance, a zero nonce, and no
code currently reverts. This is a deliberate guard against a specific edge case
and is reachable in practice only through a USDC meta-transaction that fully
drains a brand-new account. Accounts that have ever sent a transaction (non-zero
nonce) or hold code are unaffected and drain normally.
This is a known, temporary limitation. A fix is planned for a future release.