Across for Stablecoins

Native USDC, USDT0, and USDH transfers using CCTP V2, OFT, and sponsored settlement mechanisms.

Across supports three independent settlement mechanisms for stablecoins: intents (relayer network), CCTP V2 (native USDC), and OFT (native USDT0). Each is a first-class pathway — the Swap API selects the optimal mechanism based on token, amount, and route.

Settlement Comparison

PropertyIntentsCCTP V2 / CCTPFastOFT
TokenAny supportedUSDCUSDT0
Speed~2 secondsVaries (attestation dependent)Varies (message dependent)
Max amountRelayer capacity$10MVaries
Relayer capital?YesNoNo
SettlementRelayer fills, bundled repaymentCircle mint-and-burnLayerZero mint-and-burn

CCTP V2 — Native USDC Settlement

Circle's Crosschain Transfer Protocol V2 enables native USDC mint-and-burn across chains. When the Swap API routes through CCTP V2, Circle burns USDC on the origin chain and mints fresh native USDC on the destination.

CCTPFast is available on select routes, offering faster attestation times compared to standard CCTP V2. The Swap API automatically uses CCTPFast where available.

Key properties:

  • Transfers up to $10 million per transaction
  • No relayer capital required — Circle handles minting
  • Native USDC on the destination (not bridged/wrapped)
  • CCTPFast provides faster attestation where available
  • Slightly longer settlement than intent-based fills

Initiate Transfer

The user calls the Swap API with USDC as both input and output token. For amounts under the relayer network's instant fill capacity, the intent pathway is used. For larger amounts, CCTP V2 activates automatically.

Origin Burn

USDC is burned on the origin chain via Circle's TokenMessenger contract. An attestation is generated by Circle's off-chain service. With CCTPFast, this attestation arrives faster.

Destination Mint

Once the attestation is available, native USDC is minted on the destination chain and delivered to the recipient.

OFT — Native USDT0 Settlement

For USDT0 transfers, Across uses the LayerZero Omnichain Fungible Token (OFT) standard. This burns USDT0 on the origin chain and mints it natively on the destination — no wrapped tokens or liquidity pools involved.

USDT0 only. OFT settlement currently supports only USDT0. More OFT-enabled tokens are coming soon.

Initiate Transfer

The user calls the Swap API with USDT0 as the input token. The API determines whether to use the relayer network or OFT mint-and-burn based on the amount and route.

Origin Burn

USDT0 is burned on the origin chain using the OFT adapter contract. LayerZero's messaging layer transmits the burn proof crosschain.

Destination Mint

USDT0 is minted natively on the destination chain and sent to the recipient address.

Certain stablecoin routes are zero-fee — the protocol or partners subsidize the entire transfer cost. Users pay nothing to bridge on these routes.

Currently sponsored:

  • USDC → USDH on Hyperliquid — zero bridge fee

To check if a route is sponsored, inspect the fees object in the /swap/approval response. Sponsored routes show 0 total fees.

check-sponsored.ts
const params = new URLSearchParams({
  tradeType: "minOutput",
  originChainId: "42161",        // Arbitrum
  destinationChainId: "1337",    // HyperEVM
  inputToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",  // USDC on Arbitrum
  outputToken: "0x...",          // USDH on HyperEVM
  amount: "1000000000",
  depositor: "0xYourWalletAddress",
});

const response = await fetch(
  `https://app.across.to/api/swap/approval?${params}`,
  {
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
    },
  }
);
const quote = await response.json();

console.log("Total fees:", quote.fees?.total);
// Sponsored routes: "0"

Stablecoin Contract Addresses

Always verify addresses via the /swap/tokens endpoint. Token addresses can change as new deployments roll out.

ChainAddress
Ethereum0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arbitrum0xaf88d065e77c8cC2239327C5EDb3A432268e5831
Base0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Optimism0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85
Polygon0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359

Use /swap/tokens?chainId=<id> for the complete list across all 23+ chains.

ChainAddress
Ethereum0xdAC17F958D2ee523a2206206994597C13D831ec7
Arbitrum0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9
Optimism0x94b008aA00579c1307B0EF2c499aD98a8ce58e58

Use /swap/tokens?chainId=<id> for the complete list.

ChainAddress
HyperEVM (1337)Check /swap/tokens?chainId=1337

USDH is Hyperliquid's native stablecoin. Use the Hypercore guide for bridging details.

Supported Chains per Stablecoin

ChainUSDCUSDT0USDH
EthereumYesYes
ArbitrumYesYes
BaseYes
OptimismYesYes
PolygonYes
HyperliquidYes
SolanaYes

This is a subset of supported chains. Query /swap/tokens for the full matrix of stablecoins and chains.

Example: Large USDC Transfer

This example sends $5M USDC from Ethereum to Arbitrum. The Swap API automatically selects CCTP V2 for this amount.

large-usdc-transfer.ts
import { createWalletClient, createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY");
const walletClient = createWalletClient({
  account,
  chain: mainnet,
  transport: http(),
});
const publicClient = createPublicClient({
  chain: mainnet,
  transport: http(),
});

// 5,000,000 USDC (6 decimals)
const amount = "5000000000000";

const params = new URLSearchParams({
  tradeType: "minOutput",
  originChainId: "1",
  destinationChainId: "42161",
  inputToken: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",   // USDC on Ethereum
  outputToken: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",   // USDC on Arbitrum
  amount,
  depositor: account.address,
});

const response = await fetch(
  `https://app.across.to/api/swap/approval?${params}`,
  {
    headers: {
      Authorization: "Bearer YOUR_API_KEY",
    },
  }
);
const quote = await response.json();

// Check which settlement mechanism the API selected
console.log("Cross-swap type:", quote.crossSwapType);
console.log("Expected fill time:", quote.expectedFillTime, "seconds");

// Execute approvals
if (quote.approvalTxns?.length) {
  for (const approvalTx of quote.approvalTxns) {
    const hash = await walletClient.sendTransaction({
      to: approvalTx.to,
      data: approvalTx.data,
    });
    await publicClient.waitForTransactionReceipt({ hash });
  }
}

// Execute the swap
const hash = await walletClient.sendTransaction({
  to: quote.swapTx.to,
  data: quote.swapTx.data,
  value: quote.swapTx.value ? BigInt(quote.swapTx.value) : 0n,
});

console.log("Transfer tx:", hash);

The Swap API handles all mechanism selection internally. Whether your transfer uses the relayer network, CCTP V2, or OFT, the integration code is identical — call /swap/approval, execute approvals, then send the swap transaction.

On this page