Specie
Arc
Before you trade

Bringing USDC in

Specie settles in USDC and Arc charges gas in it, so the first thing a new wallet needs here is USDC. The Bring USDC page moves it from a chain you already hold it on, through Circle's own Cross-Chain Transfer Protocol.

What actually happens

No bridge holds your money and nothing is wrapped. The USDC is burned on the chain it is on, Circle attests to that burn, and the same amount is issued on Arc by Circle's own contract. What arrives is ordinary USDC, indistinguishable from any other.

  1. You approve exactly the amount you are moving. Nothing is left approved afterwards.
  2. You sign the burn on the source chain.
  3. Circle attests once that chain is final. Fast transfers are attested sooner, for a fee it quotes.
  4. You sign the mint on Arc, and the USDC appears at the same address.
Three signatures, all yours. Specie takes no fee for this, never holds the money, and cannot finish the transfer for you: an attestation is worthless without your signature on Arc. If you close the page between the burn and the mint, the transfer waits; the page remembers it in your browser and offers the last step when you come back.

Where it can come from

Ethereum (domain 0), Base (domain 6), Arbitrum (domain 3), OP Mainnet (domain 2), Polygon (domain 7), Unichain (domain 10), Linea (domain 11), Avalanche (domain 1). Arc is domain 26.

Standard or fast

ChoiceFeeWait
Standardnoneuntil the source chain is final, often 15 minutes or more
FastCircle's quote, a fraction of a basis point on most routesseconds to a couple of minutes

The fee is Circle's, not ours, and it is taken out of the amount that arrives. The panel quotes it live before you sign and shows what lands on Arc.

The contracts

CCTP v2 uses the same two addresses on every chain it covers, Arc included: the TokenMessenger that burns, and the MessageTransmitter that mints.

0x28b5a0e9C621a5BadaA536219b3a228C8168cf5d0x81D40F21F12A8F0E3252Bccb954D722d4c464B64

Checked on Arc and on every source chain before this went live: bytecode present, and each TokenMessenger reporting that MessageTransmitter as its own.

What can go wrong