Skip to main content
Send USDC withdrawals from an exchange hot wallet on Arc by validating addresses, estimating gas, building EIP-1559 transactions, and confirming with deterministic finality. Send withdrawals as native USDC transfers—the recommended path for exchanges: cheaper gas (~21,000 vs ~65,000 units) and receivable by any address. The Memo contract lets you attach compliance metadata to the same transaction.

Prerequisites

Before you begin, ensure you have:
  • An Arc Testnet RPC endpoint (https://rpc.testnet.arc.io)
  • A funded hot wallet with USDC for both transfer amounts and gas fees
  • The USDC ERC-20 contract address: 0x3600000000000000000000000000000000000000
  • viem installed (npm install viem)

Steps

Step 1. Validate the destination address

Verify that the withdrawal address is a valid EIP-55 checksum-validated Ethereum address before building the transaction. This prevents sending funds to malformed addresses.
The address must be:
  • 20 bytes (40 hex characters) with a 0x prefix
  • Valid per EIP-55 checksum rules

Step 2. Check the blocklist

Arc enforces a blocklist at the protocol level. If the destination address is blocklisted, the transaction reverts at runtime. Check before sending to avoid wasted gas.

Step 3. Estimate gas units

Call eth_estimateGas to determine the gas units required for the native USDC send. The value field is denominated in 18-decimal native wei.
eth_estimateGas returns gas units, not a cost in USDC. To calculate the cost, multiply by the effective gas price. A native USDC send uses approximately 21,000 gas units, while an ERC-20 transfer() call uses approximately 65,000.

Step 4. Calculate gas cost

Use eth_gasPrice to get the current suggested gas price, then compute the total fee.
Gas cost formula:
For example, a native USDC send using 21,000 gas at 20 Gwei:

Step 5. Build the EIP-1559 transaction

Construct a type-2 (EIP-1559) transaction with maxFeePerGas set to at least 20 Gwei. The fee fields and the value field are all denominated in USDC wei (18 decimals).
Transactions with maxFeePerGas below 20 Gwei may remain pending or fail to execute.
Send withdrawals as native USDC (a plain value transfer). It is cheaper than an ERC-20 transfer() and any address can receive it. Native sends still emit a Transfer log from the system emitter (0xffff…fffe), so indexers and block explorers still capture them. Reach for the ERC-20 transfer() only when you need 6-decimal exactness or ERC-20 call semantics.

Step 6. Confirm inclusion

Arc provides deterministic finality. Once a transaction is included in a block, it is final—no reorgs, no need to wait for additional confirmations.
Unlike other blockchains, you do not need to wait for multiple block confirmations. A single block inclusion is final on Arc.

Step 7. Handle failures

Common failure scenarios and how to address them:

Attach memos for compliance

Use the Memo contract to attach metadata (such as internal withdrawal IDs or compliance references) to transfers. The Memo contract wraps the encoded USDC transfer call, routes it through CallFrom so the USDC transfer still sees your hot wallet as msg.sender, and emits a Memo event for reconciliation. Memo contract address: 0x5294E9927c3306DcBaDb03fe70b92e01cCede505 For the full viem, ethers, Python, and cURL flow, see Send USDC with a transaction memo.
Store a deterministic memoId or encoded memo value that links the onchain transfer to your internal withdrawal record.

See also