How to Send USDC on the Base Network
To send USDC on Base, select the Base network in your wallet, choose USDC (contract 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913), paste the recipient address, and confirm. You need a little ETH on Base for gas unless your wallet sponsors fees. In code, call the token's ERC-20 transfer function with the amount in 6 decimals, then confirm on Basescan.
What a USDC send actually is
USDC on Base is an ERC-20 token. Your balance is an entry in the token contract's storage, not something held in your account directly. Sending USDC means submitting a transaction to the USDC contract that calls transfer(recipient, amount). The contract debits you, credits the recipient, and emits a Transfer event.
Two consequences follow. First, the transaction is paid for in ETH, Base's gas asset, because you are the one submitting it. Second, the token you are moving is defined by its contract address. Circle's native USDC on Base is 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913. An older bridged token, USDbC, has a different contract, and anyone can deploy a token called USDC.
Sending from a wallet
- Select Base. In the wallet's network menu, choose Base mainnet (chain ID 8453). Many wallets include it by default; if not, add it from Base's official documentation.
- Pick the right USDC. Open the token and check its contract address matches the one above. If the wallet shows two USDC-like balances, one may be USDbC.
- Check gas. Hold a small amount of ETH on Base. Without it the send fails before broadcasting, unless your wallet sponsors gas or lets you pay fees in USDC.
- Paste the recipient. Copy the address from the source of truth (the recipient's own wallet, an exchange's Base deposit screen), not from your transaction history. Compare the full string.
- Send a test amount first to any new address, especially an exchange. Confirm it arrives, then send the rest.
- Confirm and record the transaction hash.
If the recipient is an exchange, confirm it lists Base as a supported deposit network for USDC. Sending on Base to an exchange that only watches Ethereum for that address can mean a slow support recovery or none.
Confirming on Basescan
Paste the transaction hash into Basescan. Check that the status is Success, that the token transferred is USDC with the contract address above, that the recipient and amount match, and that the network shown is Base mainnet. Base docs describe a Flashblock preconfirmation in about 200ms and an L2 block in about 2 seconds; Ethereum-anchored finality follows in roughly 20 minutes. For most payments the block confirmation is enough.
Sending programmatically
In code, the same transfer is one contract call. This example uses viem; ethers and other libraries are equivalent.
import { createWalletClient, createPublicClient, http, parseUnits, erc20Abi } from "viem";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
const USDC = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"; // native USDC on Base
const account = privateKeyToAccount(process.env.SENDER_KEY as `0x${string}`);
const wallet = createWalletClient({ account, chain: base, transport: http() });
const reader = createPublicClient({ chain: base, transport: http() });
const hash = await wallet.writeContract({
address: USDC,
abi: erc20Abi,
functionName: "transfer",
args: [recipient, parseUnits("5", 6)], // 5 USDC, 6 decimals
});
const receipt = await reader.waitForTransactionReceipt({ hash });
if (receipt.status !== "success") throw new Error("transfer reverted");
Points that matter more than the syntax:
Decimals. USDC has 6 decimals. parseUnits("5", 6) is five dollars. Using 18 decimals, as for ETH, asks for a trillion times more and reverts on balance. The reverse mistake, passing an unscaled 5, sends five millionths of a dollar and succeeds silently.
Receipt status. A transaction hash means submitted, not succeeded. Wait for the receipt and check status. For accounting, also decode the Transfer event to confirm amount and recipient.
Nonces and retries. If you retry after a timeout, check whether the first transaction landed before sending again, or you will pay twice. Track sends by an idempotency key in your own system.
Keys. The example reads a private key from the environment because it is a script. Do not run an agent this way.
Transfers without the sender paying gas
USDC also implements EIP-3009, transferWithAuthorization: the holder signs an authorisation offchain and someone else submits it and pays the gas. This is how x402-style pay-per-call flows usually settle, with a facilitator submitting the payer's signed authorisation. The payer still needs to verify amount, recipient, and validity window before signing, because the signature is the payment.
Mistakes that strand or lose funds
Wrong network. The recipient address is identical on every EVM chain, so a send on Ethereum or another network succeeds and lands there instead. Recoverability depends on who controls that address on that chain.
Sending to the token contract. Pasting the USDC contract address as the recipient usually locks the funds permanently.
USDbC instead of USDC. Some recipients only credit native USDC. Swap first if needed.
Poisoned addresses. Lookalike addresses planted in history match the first and last characters. Copy from the recipient, not from history.
No ETH for gas. The send cannot be submitted. Fund ETH on Base or use a wallet that sponsors gas.
Agent with a raw key. An agent sending USDC should use a session key scoped by cap, asset, recipients, and expiry, so a manipulated agent cannot send everything to anyone. CryptoCadet's rail works this way: a non-custodial, session-key-bounded USDC float on Base, with the key held in the OS keychain.
Frequently asked questions
- How do I send USDC on the Base network?
- Switch your wallet to Base, select USDC and confirm its contract is 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913, paste the recipient address, enter the amount, and confirm. Keep a small ETH balance on Base for gas. Send a test amount to any new address first, then check the transaction on Basescan before sending the rest.
- Do I need ETH to send USDC on Base?
- Usually yes. Gas on Base is paid in ETH, and an ERC-20 transfer is a transaction you submit. Exceptions exist: some smart wallets sponsor gas through a paymaster or let you pay fees in USDC, and EIP-3009 authorisations let a third party submit the transfer and pay the gas for you.
- How long does a USDC transfer on Base take?
- Base documents a Flashblock preconfirmation in about 200 milliseconds and inclusion in an L2 block in about 2 seconds, which is what most wallets show as confirmed. The batch is posted to Ethereum in about 2 minutes and reaches Ethereum finality in about 20. Fees and timing vary with network load.
- Why did my USDC transfer on Base fail?
- The common causes are no ETH on Base for gas, an amount above your balance (often a decimals error in code, since USDC uses 6), selecting a different token such as USDbC, or a recipient contract that rejects the transfer. Check the transaction on Basescan; a reverted transaction still consumes some gas but moves no USDC.
- Can I cancel a USDC transfer on Base?
- Not after it is included in a block. Onchain transfers are final, and nobody, including Circle or Base, reverses a normal transfer to the wrong address. Before inclusion, some wallets let you replace a pending transaction with a higher-fee one, but Base confirms so quickly that this window is rarely useful in practice.