Skip to main content
For a step-by-step indexing walkthrough, see Index Arc events. For the conceptual model behind USDC’s native and ERC-20 interfaces, see Stablecoin native model.

Two event streams

USDC movements surface as logs from two distinct emitters. The native system emitter logs a Transfer 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.
SourceEmitter addressEventsDecimals
Native USDC (system, EIP-7708)0xfffffffffffffffffffffffffffffffffffffffeTransfer18
ERC-20 USDC (NativeFiatToken)0x3600000000000000000000000000000000000000Transfer6
A single ERC-20 transfer() emits two logs: the ERC-20 contract’s own Transfer (6 decimals, from 0x3600000000000000000000000000000000000000) and the native system Transfer (18 decimals, from 0xfffffffffffffffffffffffffffffffffffffffe). A plain native send emits only the system log. Match on the emitter address so you do not count the same movement twice, and never mix the 6-decimal and 18-decimal values.

Native USDC system events (EIP-7708)

Native USDC movements emit a standard ERC-20 Transfer 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.
PropertyValue
Emitter0xfffffffffffffffffffffffffffffffffffffffe
EventTransfer(address indexed from, address indexed to, uint256 value)
topic00xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
Decimals18
Mint and burn are expressed as transfers involving the zero address:
  • Mint: Transfer(0x0, recipient, amount)
  • Burn: Transfer(from, 0x0, amount)
The following rules apply to the system Transfer log:
  • The native Transfer log 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, or SELFDESTRUCT) to or from the zero address reverts with "Zero address not allowed". Mint and burn are the only paths that produce a Transfer involving 0x0, and they go through the precompile.

ERC-20 USDC contract events

The NativeFiatToken contract at 0x3600000000000000000000000000000000000000 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.
PropertyValue
Emitter0x3600000000000000000000000000000000000000
EventTransfer(address indexed from, address indexed to, uint256 value)
topic00xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef
Decimals6

Historical events (before Zero5)

On testnet, before the Zero5 hard fork activated, native USDC movements emitted custom events from the NativeCoinAuthority precompile at 0x1800000000000000000000000000000000000000 (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.
Eventtopic0
NativeCoinTransferred(address indexed from, address indexed to, uint256 amount)0x62f084c00a442dcf51cdbb51beed2839bf42a268da8474b0e98f38edb7db5a22
NativeCoinMinted(address indexed recipient, uint256 amount)0xb049859d09b3a7d0189a07db4d4becee1a2aa269023205478b1360ab6fc12114
NativeCoinBurned(address indexed from, uint256 amount)0xaaf1ef013644e67c5cea90217acdf0accd334f8437fc9a89a53cfc9b25fb5c25
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 as Transfer 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