AgentCap

← Blog

USDC has 6 decimals: the unit bugs that break agent spend numbers

GetAgentCap team · published 10/2/2026

A USDC Transfer event stores an integer, not dollars. If you read that integer with the wrong number of decimals, every total you build on it is wrong by a power of ten.

What the chain actually stores

ERC-20 Transfer events on Base carry the value as an unsigned integer in the token's smallest unit. USDC's decimals() function returns 6, so one dollar of USDC is stored as 1,000,000 units.

On Solana, the USDC mint also has 6 decimals. SPL transfer instructions carry raw amounts in the same smallest unit, and the decimals live on the mint account.

The 18-decimals habit

A lot of EVM tooling assumes 18 decimals because ETH and many tokens use 18. If you format a USDC value with 18 decimals, the result is off by a factor of 10^12 and real payments show up as dust.

The reverse mistake, formatting an 18-decimal token as if it had 6, inflates the number by the same factor. Both mistakes are quiet: nothing errors out, the totals are just wrong.

Floating point is the second trap

Converting raw amounts to floating-point dollars before summing them adds rounding error. One payment hides it, but thousands of small x402 payments can drift away from the on-chain balance.

The safer pattern is to sum raw integers (or arbitrary-precision decimals) and convert to dollars only when you display the number. JavaScript code should use BigInt for this, because a Number loses integer precision above 2^53.

Read decimals, don't hardcode them

The decimals value is metadata you can query: decimals() on the ERC-20 contract, or the mint account on Solana. Reading it per token means a new token cannot silently pick up the wrong scale.

It also exposes impostor tokens. A token that calls itself USDC but reports different decimals, or comes from a different contract or mint, is not the asset you meant to track.

How GetAgentCap handles it

We store raw integer amounts exactly as they appear on-chain, tied to the canonical USDC contract or mint, and apply the 6-decimal scale only for display. Totals and budget checks run on integers.

Every number traces back to a transfer you can look up in a block explorer from a public address. We never ask for a key or a wallet connection.