PlatformAmounts and precision

Amounts and precision

How V3 Custody stores and transmits amounts: smallest units (raw) and decimal representation, converted using the network's decimals.

To avoid floating-point rounding errors, amounts are tracked in the token's smallest indivisible unit (raw, an integer) and displayed in decimal form for humans. The token's decimals value bridges the two.

Raw and decimal

  • raw: an integer in the smallest units. Exact, with no floating point. For example, USDT on TRON has decimals = 6, so 1 USDT = 1,000,000 raw.
  • decimal: the familiar representation, such as "1350.00".
  • decimals: the token's scale on the network: raw = decimal × 10^decimals.
Tokendecimalsdecimalraw
USDT (TRON)61.51500000
ETH180.0011000000000000000

In requests and responses

On input (for example, when creating a transfer), you pass a decimal amount, and the platform converts it using decimals. Responses include both representations. Balance checks are performed in raw.

FieldRepresentationWhere it's used
amountraw (or decimal input, depending on the endpoint)responses; input for some endpoints
amountDecimaldecimalresponses
relatedAmountRawrawpartial refunds

Amount field names and meanings vary by endpoint (in some, amount is raw; in others, it's decimal input). See the API Reference for the exact semantics of a specific endpoint.

Why raw

Integer arithmetic in the smallest units eliminates floating-point drift: ledger entries net to exactly zero, and balances always match the ledger. For details, see Ledger (double-entry).

Integration recommendations

  • Pass and store raw amounts as strings. Large values (for example, ETH's 18 decimal places) exceed JavaScript's safe integer range. Responses return amounts as strings ("1350000000").
  • Use decimal arithmetic libraries for conversion and display, not floating-point numbers.

Common mistakes

SymptomCause
amounts are off by a few centsfloats used instead of integer or decimal arithmetic
precision loss or overflow in JSraw stored as a number, not a string (ETH's 18 decimals exceed Number.MAX_SAFE_INTEGER)
amount is 10^decimals times too large or smallraw and decimal were mixed up on input
amount treated the same everywherethe field's semantics vary by endpoint; check the API Reference
wrong scalethe wrong token's decimals was used (USDT-TRON has 6, ETH has 18)

Next steps