Developer insights

Sponsored Transactions on Arc with USDC as Gas

Elton Tay Headshot
Elton Tay
Developer Relations Lead APAC, Developer and Ecosystem Marketing
September 21, 2026
8
min read
September 21, 2026
8
min read

Summary

Sponsoring a transaction means paying someone else's gas. On most chains that means funding a second asset: you acquire and hold the native token purely to move the one your users actually transact in. That balance carries price exposure unrelated to your business, and your finance team reconciles two currencies to explain one cost.

On Arc, gas is USDC. USDC is the native gas token, so your sponsorship treasury is a USDC balance, and your gas costs land in your P&L in the currency you already report in. There is no second asset to acquire, hedge, or reconcile.

This article covers the three sponsorship routes, how fee accounting crosses Arc's two decimal interfaces, why the bounded fee ceiling makes sponsorship budgetable, and the Arc-specific failure paths to test before you go live.

Choose the right sponsorship model

Two questions decide this: whether you are sponsoring USDC transfers or arbitrary calls, and whether your users hold plain EOAs or smart accounts. Every route below is funded from the same USDC balance.

You want to sponsor Your users hold Use
USDC transfers only EOAs EIP-3009 relayer
Any call Smart accounts ERC-4337 paymaster
Any call EOAs EIP-7702 delegation, then a paymaster
ERC-20 (balanceOf, transfer, allowances) 6 decimals Application transfers, approvals, and pool math

EIP-3009 relayers collect a user's transferWithAuthorization signature offchain and broadcast the transfer from a funded externally owned account. There are no smart accounts, no bundler, and no additional contracts to deploy. This is the right choice when your use case is "move USDC" and nothing more.

ERC-4337 paymasters sponsor arbitrary UserOperations on behalf of smart accounts. There is more machinery involved, including an EntryPoint, a bundler, and a paymaster contract, but it sponsors any call rather than only transfers, and it composes with session keys and batched operations.

ERC-7702 delegation opens the paymaster path to users who hold plain EOAs. Arc supports it, so an existing account can delegate to smart account code and then be sponsored like any other smart account. You sponsor users at the addresses they already have, with no migration step. Once the EOA has code, sponsorship behaves exactly as it does for any smart account, so the ERC-4337 guide applies unchanged.

Handle Arc’s native and ERC-20 USDC decimal differences

Arc's native USDC uses 18 decimals. The ERC-20 interface uses 6. The conversion factor between them is 10¹². These are two interfaces over one balance, not two tokens.

The relayer and the paymaster both cross that boundary, in opposite directions.

A relayer reads gas costs in 18-decimal native units and bills in 6-decimal token units, so the value taken from the receipt must be divided by 10¹² before it is charged.

const gasCostWei: bigint = receipt.gasUsed * receipt.effectiveGasPrice;
const gasCostUsdc: bigint = gasCostWei / 10n ** 12n; // 6-decimal USDC units

Omitting the conversion overstates the charge by a factor of 10¹². The resulting figure is visibly wrong in the billed amount, so this error tends to surface quickly.

A paymaster funds its EntryPoint deposit in 18-decimal native units, so the intended USDC amount must be scaled by 10¹⁸ rather than 10⁶.

// Deposit 10 USDC in native units, 18 decimals
const depositAmount: bigint = 10n * 10n ** 18n;
await entryPoint.depositTo(PAYMASTER_ADDRESS, { value: depositAmount });

Using 10n * 10n ** 6n here — the expression that is correct in most other USDC contexts — deposits 0.00000000001 USDC instead. The call succeeds and the deposit is valid, so nothing fails at funding time. The shortfall becomes apparent later, when sponsorship stops being covered.

Both errors come from the same 10¹² factor. entryPoint.balanceOf() also returns 18-decimal units, so any monitoring that reads it and compares against a 6-decimal threshold inherits the same bug.

What stays the same and what changes about gas pricing on Arc

Most of your sponsorship stack is unchanged.

Arc's fee market is EIP-1559. eth_gasPrice, eth_feeHistory, and eth_maxPriorityFeePerGas behave as you expect. Arc supports the standard EntryPoint contracts at both v0.6 and v0.7. Pimlico works as a bundler on Arc testnet, and other account abstraction providers support Arc as well. Your paymaster can be built from the ERC-4337 reference implementation.

What differs is the shape of the fee curve.

Arc’s stable fee design makes sponsorship costs predictable

Arc replaces EIP-1559's per-block base fee recalculation with an exponentially weighted moving average of block utilization:

utilization_ewma(n) = alpha * block_utilization(n) + (1 - alpha) * utilization_ewma(n - 1)
base_fee(n)         = adjust(base_fee(n - 1), utilization_ewma(n - 1), target_utilization)

Block n's base fee is fixed before block n executes, so it is derived from the parent block's base fee and the utilization EWMA through block n-1. In practice, short traffic spikes do not propagate into fee spikes. The base fee moves gradually and is clamped to a bounded range.

Parameter Value
Minimum base fee (testnet) 20 Gwei
Maximum base fee 20,000 Gwei
Gas throughput 30M gas per block, ~0.5s blocks
Typical transferWithAuthorization ~65,000 gas

Current values and live metrics are on the gas and fees reference and the Arc Gas Tracker.

The ceiling is the important number. Worst-case cost per sponsored transaction is bounded by maxFeePerGas × gasLimit, and because the ceiling is a protocol constant, not a market outcome, you know that bound in advance. You can budget sponsorship per user, per day, with real figures.

Two consequences follow.

Set maxFeePerGas to at least 20 Gwei on whatever transaction reaches the chain. Below the floor it may remain pending indefinitely. For a relayer, that is the transfer itself. For a paymaster, it is the bundler's bundle transaction — a distinct value from the UserOperation's own maxFeePerGas, and the one the floor applies to. Pimlico configured for Arc handles this; if you run your own bundler, enforce it there.

const FLOOR_FEE: bigint = 20_000_000_000n; // 20 Gwei
const feeData = await provider.getFeeData();
const maxFeePerGas: bigint =
  feeData.maxFeePerGas !== null && feeData.maxFeePerGas > FLOOR_FEE
    ? feeData.maxFeePerGas
    : FLOOR_FEE;

A maxPriorityFeePerGas of 0 is acceptable. The base fee alone covers inclusion under normal conditions. Use 1 Gwei during sustained load.

One further difference matters for accounting: Arc does not burn the base fee. Both the base fee and the priority fee are credited to the block beneficiary. The next block's base fee is published in the parent header's extra_data as an 8-byte big-endian value, so read it there rather than re-deriving it.

Test Arc-specific transaction sponsorship failures

Sponsored flows fail in ways ordinary transactions do not, because you are paying for someone else's intent. Two Arc-specific cases deserve explicit tests.

1. Blocklisted addresses fail in two different places, and only one of them costs you gas.

A blocklisted sender is rejected by the RPC node before the transaction enters the mempool. eth_sendRawTransaction returns an error, there is no receipt, and no gas is spent. Your submit path has to catch this synchronously.

A blocklisted address hit during execution is different, and it surfaces differently depending on which route you run.

On an EIP-3009 relayer, the transaction is included, reverts with a status: 0 receipt, and consumes gas without transferring value. The relayer pays for it and recovers the cost off-chain. That mechanism is not Arc-specific; a relayer on any EVM chain absorbs the gas on a reverted transfer. What is Arc-specific is that the blocklist is one of the conditions that triggers it.

On an ERC-4337 paymaster, the revert happens inside the UserOperation execution phase, so the bundle transaction still returns a status: 1 receipt. The EntryPoint charges the paymaster's deposit either way, and the failure is reported as success: false on the UserOperationEvent. Monitoring that keys off receipt.status will read this as a success and under-count sponsored spend.

// A bundle tx can return status 1 while the UserOperation itself reverted.
// Read UserOperationEvent, not just receipt.status.
const parsed = receipt.logs
  .map((log) => entryPoint.interface.parseLog(log))
  .find((p) => p?.name === "UserOperationEvent");

if (parsed?.args.success === false) {
  // The paymaster was still charged.
  // actualGasCost is an 18-decimal native USDC amount.
  recordSponsoredFailure(parsed.args.userOpHash, parsed.args.actualGasCost);
}

Screen both message.from and message.to before submitting, or accept the cost and account for it in monitoring. For a relayer the second case is a direct operating expense, and one without an upper bound if the endpoint receives a high volume of invalid requests.

2. Native value transfers can revert with a sufficient balance.

Transfers to the zero address, transfers that would burn value, and transfers to already-destructed accounts all revert for value-bearing transfers, regardless of the sender's balance. If your paymaster or relayer forwards native value anywhere, do not assume that a funded sender guarantees a successful send.

Calculate and bill relayer gas costs end to end

The full-precision path for a relayer, end to end:

  1. Estimate with estimateGas against the actual call rather than a hardcoded constant.
  2. Read fee data and clamp to the 20 Gwei floor.
  3. Submit with an explicit gasLimit, maxFeePerGas, and maxPriorityFeePerGas.
  4. From the receipt, compute gasUsed × effectiveGasPrice to get 18-decimal wei.
  5. Divide by 10¹² only at the billing boundary.

Keep internal accounting in 18-decimal native units and convert exactly once, at the edge where you write a customer-visible number. Converting early and carrying 6-decimal values through your ledger discards sub-cent precision at every step, which matters when the margins are themselves sub-cent.

For display, quote fees in USDC rather than Gwei. Arc's premise is that users think in dollars. A sponsored-transaction interface that surfaces "21,000 gas at 20 Gwei" discards that advantage.

Pre-launch checklist for Arc transaction sponsorship

Before you go live:

  • Bill a relayed transfer end to end and assert the charged amount equals gasUsed × effectiveGasPrice ÷ 10¹²
  • Fund a paymaster deposit and assert entryPoint.balanceOf() matches the intended USDC amount in 18-decimal units
  • Deliberately fund a paymaster with a 6-decimal amount and confirm your monitoring detects the shortfall
  • Relay to and from a blocklisted address; confirm gas is consumed, no transfer occurs, and the loss is recorded
  • Revert a sponsored UserOperation and confirm your monitoring records the failure from UserOperationEvent.success, not from the bundle receipt status
  • Submit below the 20 Gwei floor and confirm your retry logic handles an indefinitely pending transaction
  • Confirm the EntryPoint address on-chain before relying on it. Arc supports both EntryPoint v0.6 and v0.7, so verify the deployed address for the version you target rather than reusing one from another chain.
  • Run all of the above against an Arc RPC endpoint rather than a local simulator. Tools such as Foundry's anvil run a standard EVM and cannot reproduce blocklist enforcement, the native-coin precompiles, or Arc's value transfer rules

Where this leaves you

Arc can simplify sponsorship operations. One asset can fund gas and application activity, and the fee model may make costs easier to estimate. A separate volatile gas asset may not be needed.

The work that remains is precision: applying the 10¹² factor correctly in both directions and screening the blocklist. Each is testable before deployment.

Start building a relayer or paymaster on Arc

Two step-by-step guides run on Arc Testnet:

To get set up: connect to Arc Testnet for RPC endpoints and chain ID, then get testnet USDC from the Circle Faucet.

For the protocol behaviour behind everything above, see the EVM differences reference and Stable fee design. For integration guidance specific to this use case, see Relayers and paymasters.

Explore open-source Arc apps built with Circle developer tools, from payments and FX to DeFi, wallets, and treasury flows.

USDC is issued by regulated affiliates of Circle. See Circle’s list of regulatory authorizations.

Arc is an open L1 blockchain launched by Arc Network Services LLC ("Arc LLC") and operated by a permissioned validator set. Arc LLC provides software services only and does not offer regulated financial or advisory services. Arc has not been reviewed or approved by the New York State Department of Financial Services or any other regulatory authority.

The Arc network is provided "as is" and "as available." Use of Arc involves inherent risks associated with blockchain technology, including smart contract vulnerabilities, network disruptions, and the absence of recourse for transaction errors or losses. The ability to transact on Arc depends on the ability to obtain and use USDC to pay gas fees. Neither Arc LLC nor any permissioned validator is responsible for the content, accuracy, legality, or functionality of third-party applications, protocols, or services built on or integrated with Arc. You are solely responsible for features or services you provide to users, including obtaining any necessary licenses or approvals and otherwise complying with applicable laws.

All Arc features may be modified, delayed, or cancelled at any time without notice. Nothing herein constitutes a commitment, warranty, guarantee or legal, regulatory, tax, or investment advice.

Contents