Two event streams
USDC movements surface as logs from two distinct emitters. The native system emitter logs aTransfer for every USDC movement—native sends and ERC-20
transfers alike—so it is a single universal record of balance changes at
18-decimal precision. Filter by emitter address to tell the two streams apart.
Native USDC system events (EIP-7708)
Native USDC movements emit a standard ERC-20Transfer log from a designated
system address. This is Arc’s implementation of
EIP-7708, an Amsterdam-track Ethereum
proposal that Arc ships ahead of upstream. Native movements can be indexed the
same way as ERC-20 transfers. (For the legacy events that testnet emitted before
this behavior was activated, see
Historical events.)
The log covers native value transfers (CALL), contract creation with an
endowment (CREATE), SELFDESTRUCT balance transfers, and the
precompile-driven mint, burn, and transfer operations that back the ERC-20
USDC interface.
Mint and burn are expressed as transfers involving the zero address:
- Mint:
Transfer(0x0, recipient, amount) - Burn:
Transfer(from, 0x0, amount)
Transfer log:
- The native
Transferlog is emitted first, before any other logs in the transaction. - Zero-value transfers emit no log.
- Self-transfers (
from == to) emit no log. - A native value transfer (
CALL,CREATE, orSELFDESTRUCT) to or from the zero address reverts with"Zero address not allowed". Mint and burn are the only paths that produce aTransferinvolving0x0, and they go through the precompile.
ERC-20 USDC contract events
The NativeFiatToken contract at0x3600000000000000000000000000000000000000
emits its own standard ERC-20 Transfer log (6 decimals) for activity on
the ERC-20 interface. As on any ERC-20 token, mint and burn surface here as a
Transfer to and from the zero address. These events are independent of the
native system events: an ERC-20 transfer() produces a log from both emitters.
Historical events (before Zero5)
On testnet, before the Zero5 hard fork activated, native USDC movements emitted custom events from the NativeCoinAuthority precompile at0x1800000000000000000000000000000000000000 (18 decimals) instead of the
standard Transfer log. These events are no longer emitted after
activation. Mainnet has used the EIP-7708 Transfer log since genesis, so this
only affects indexers that backfill pre-activation testnet history.
If you backfill history across the hard fork boundary, read
NativeCoin* from
0x1800000000000000000000000000000000000000 for blocks before activation and
Transfer from 0xfffffffffffffffffffffffffffffffffffffffe at and after
activation. For the exact activation time and node version requirements, see the
canonical arc-node
CHANGELOG.md and
BREAKING_CHANGES.md,
and the Run an Arc node tutorial.
Out of scope: gas fees and block rewards
Gas fees and block rewards are not emitted asTransfer events and are
unaffected by EIP-7708:
- Gas fees are derived from the receipt (
gasUsed × effectiveGasPrice). - Block rewards are attributed via
block.miner.
See also
- Index Arc events—step-by-step indexing walkthrough with code
- Stablecoin native model—why USDC has native and ERC-20 interfaces
- Contract addresses—USDC and other system contract addresses
- EVM compatibility for developers—interface-level guidance and EVM differences