Decimal dust shrinks a cross-chain send because the destination may not represent every fraction held on the source. If you often move tokens between chains, match your send amount to the precision both sides can carry. In omnichain applications, that small check helps keep token balances coordinated across networks.

Token decimals set the smallest amount you can send

Decimals tell wallets how to display a token’s integer balance. A token with 18 decimals stores one whole token as 1,000,000,000,000,000,000 base units; a token with 6 stores one as 1,000,000. A base unit is the smallest amount that contract can record.

Decimals affect the size of each unit, not the token’s value. For example, 1.25 tokens equals 1.25 × 1018 base units at 18 decimals, but 1.25 × 106 at 6 decimals. As OpenZeppelin’s ERC-20 documentation explains, decimals guide display; contract arithmetic still uses whole numbers.

Shared precision decides which fractions survive

Cross-chain token systems need a common precision that both chains can represent. LayerZero’s Omnichain Fungible Token (OFT) standard calls this shared decimals: the number of decimal places used in the cross-chain message. Its default is 6, though an implementation can choose another value.

The source converts its local amount into shared units, sends that integer in a message, then the destination converts it into its own local units. The difference between a chain’s local decimals and shared decimals sets its conversion rate. With 18 local decimals and 6 shared decimals, the rate is 1012 base units per shared unit.

That conversion creates dust: a remainder too small to fit the shared precision. Before sending, an OFT removes it by rounding down to the nearest conversion-rate multiple. Chainlink CCIP’s token-pool documentation describes a similar case: when the remote amount has more decimals than the local token, the pool rounds down.

Compare the two directions before sending

Here are two illustrative cases for a token using 6 shared decimals. The conversion rules determine what arrives; fees and other transfer rules can affect the final receipt separately.

  • 18 decimals to 6: You enter 1.234567891234567891 tokens, or 1,234,567,891,234,567,891 source base units. Only multiples of 1012 source units map cleanly, so the send becomes 1.234567 tokens. The remaining 0.000000891234567891 stays behind.
  • 6 decimals to 18: You enter 1.234567 tokens, or 1,234,567 source units. Each source unit maps to 1012 destination units, so the receiver gets 1.234567 tokens, represented as 1,234,567,000,000,000,000 destination units.

The direction matters because only the higher-precision side can hold fractions the lower-precision side cannot express. A 6-decimal source cannot send a fraction smaller than 0.000001 token, even if the destination supports 18 decimals.

Round the amount before paying for the transfer

For repeat transfers, check the source token’s decimals and the route’s shared precision once, then use an amount that is an exact multiple of the conversion rate. For an 18-to-6 route with 6 shared decimals, divide the source base-unit amount by 1012, discard any remainder, and multiply back. That gives the largest clean amount without a second calculation at send time.

If you enter a smaller amount than one shared unit, rounding can reduce the transferable amount to zero. A minimum-received setting may then stop the transfer; check the amount preview and the destination’s expected units before confirming. In practice, I’d save the route’s conversion rate beside a reusable send amount, then recheck it if the token or route changes. That avoids paying message costs on sends whose useful amount could have been combined into one clean transfer.