VeilSwap
← All posts
Explainers2026-10-258 min read

Crypto Amount Decimals: Where Less Actually Costs Money

On 25 Oct 2026 we quoted USDT into XMR at 19, 19.9, 100 and 100.000001, then read the code that formats the answer: eight decimals for the payout, eight significant digits for the rate, and limits that move while you read them.

Two kinds of less. At 18:06:17 UTC on 25 October 2026 our quote endpoint priced 19 USDT-TRC20 into XMR at 0.01334439. Two seconds later, 19.9 USDT returned 0.01481818. Sending 4.7% more money bought 11.0% more Monero, because near the floor a shortfall is not proportional. Forty seconds earlier the same endpoint priced 100 USDT and 100.000001 USDT identically, down to the last digit: 0.14598334 XMR at a rate of 0.0014598334. One extra micro-USDT changed nothing at all. Both results are correct, and together they define what a little less means in a swap: below the order floor it is expensive, in the last decimal places it is invisible. (XMR to USDT exit)

Every asset has an indivisible unit. One bitcoin is 100,000,000 satoshi, so a single satoshi was worth 0.000807 dollars at the 80,703 dollar spot price on 25 October. One Monero is 1,000,000,000,000 piconero, and one piconero was worth 0.0000000006 dollars. One ether is 10^18 wei, one wei about 0.0000000000000024 dollars. ZEC counts zatoshi at 10^-8, LTC litoshi at 10^-8, SOL lamports at 10^-9, TRX sun at 10^-6, and USDT carries six decimals on TRON and on Ethereum, so its smallest unit is 0.000001 dollars. These are not display conventions. They are the smallest numbers the ledger can move, and every quote you see is a rounded version of an integer count of them. (SOL to XMR guide)

The quote is rounded to eight decimals. Our quote route returns `Number(best.toAmount.toFixed(8))` for the payout and `Number(best.rate.toPrecision(8))` for the rate, and the order route locks your price with the same eight-decimal figure. That explains the vanished micro-USDT: 0.000001 USDT times a rate of about 0.00146 is 1.5e-12 XMR, nowhere near the eighth decimal. In money the rounding costs at most 0.00000001 XMR, roughly 0.000006 dollars at today's price. In accounting it decides something more important, namely that the promise itself only has eight decimal places, while the chain on the other side records integers. (XMR to USDT exit)

Digit counts lie. The same endpoint printed 595.698 USDT for 1 XMR, 0.0014615927 for a rate, and 293.397277258162 XMR for a maximum. That looks like three precisions and is really two rules plus a formatter. The rate always carries eight significant digits, so its number of decimal places changes with magnitude; a JSON number drops trailing zeros, so 595.698 is 595.69800000 with the zeros hidden. Do not judge precision by counting digits after the point. Read the rule instead: payout eight decimal places, rate eight significant digits, limits whatever the route engine emits, which is why a Monero maximum arrived with twelve decimals and a USDT minimum with six. (XMR to USDT exit)

Limits drift while you read them. At 18:02 the USDT-TRC20 into XMR minimum was 19.801624 and the maximum 176,509.209306. By 18:06 they were 19.786762 and 176,443.886799; by 18:10, 19.791362 and 176,464.859757. Nobody edited anything: both bounds are derived from the payout side and move with the rate. The same holds in reverse, where the maximum printed 293.397277258162 XMR and the minimum 0.02974636. A one-token order returns a structured error rather than a quote, `amount below minimum`, with both bounds attached. The practical consequence is simple. Any number copied from a page, including the ones in this article, is a snapshot. Quote again immediately before you send. (XMR to USDT exit)

The ledger underneath is integers. Bitcoin block 973,103, mined at 18:00:31 UTC today, held 25 transactions and 41 outputs; the largest was 2,449,754,800 satoshi and the smallest was 0, an OP_RETURN carrying no value, while the block's fees totalled 32,787 satoshi over 5,140 virtual bytes, 6.379 sat/vB, about 26.46 dollars. Tron block 87,426,048 held 536 transactions, 131 of them USDT transfers; the smallest moved 3,375,404 base units, which is 3.375404 USDT, and the largest exactly 100,000.000000. Monero block 3,791,996 carried 42 transactions in 87,296 bytes and its reward was 600,030,720,000 atomic units, 0.60003072 XMR. No chain stores 3.375404 of anything. They store integers, and the decimal point is a display decision made at the edge. (XMR to USDT exit)

Where floating point actually bites. Four lines in Node make the class of bug obvious. `0.1 + 0.2` is 0.30000000000000004. `1.15 * 100` is 114.99999999999999, which is how a Max button that multiplies a balance by a price produces an amount a hair under the balance and, worse, a hair under a minimum. `(0.000181501).toFixed(8)` returns 0.00018150, silently discarding the ninth decimal instead of refusing it. And 10^18 wei is larger than 2^53, so JavaScript cannot count wei exactly at all; at that magnitude adding one to the largest safe integer returns the same number. This is why amounts belong in integers or strings and only become decimals at the moment they are shown.

A six-step precision routine. 1) Convert to the smallest unit before any arithmetic: 100 USDT is 100,000,000 units, 1 XMR is 1,000,000,000,000 piconero. 2) Compute the amount you will actually send, not the amount you wish you were sending; exchange withdrawals deduct a fee first, so read the net. 3) Never use Max as a quote amount; it is a float subtraction and it leaves residue. 4) Stay one measurable step above the minimum, 20 USDT when the floor is 19.79, because the floor moves and a rejected order costs a full minute. 5) Keep amounts inside the asset's own precision: a ninth decimal of BTC does not exist, so whoever rounds drops it. 6) Reconcile in integers, not in display values; 1e-8 XMR is 0.000006 dollars, but 1e-6 USDT out of a 100 USDT deposit is a different amount of money than you declared. (XMR to USDT exit)

What this means at the counter. Precision in a swap is not the ability to recite twelve decimal places. It is knowing which number in front of you is exact: the integer on the chain, the eight-decimal promise written into the order, the eight-significant-digit rate, or the drifting limit. The gap between 19 and 19.9 USDT cost 11% of the payout. The gap between 100 and 100.000001 cost nothing, because it was smaller than the resolution of the answer. Both are the same physics, and once you can tell them apart you stop paying for the wrong one. Quote your own size, check the floor, send the net amount, and reconcile the eight-decimal promise against the integer the chain actually received. (XMR to USDT exit)

Frequently asked questions

Does typing more decimal places change the quote?

It is accepted and echoed, but not honoured. 0.123456789012 XMR came back unchanged as the input while the payout was rounded to 73.238 USDT, and 100 versus 100.000001 USDT returned the identical 0.14598334 XMR because one micro-USDT is 1.5e-12 XMR, far below the eight-decimal answer. Anything past the eighth decimal of the payout is display, not money.

What happens if I send slightly less than I quoted?

Below the floor the loss is disproportionate: at 18:06 UTC on 25 October, 19 USDT returned 0.01334439 XMR against 0.01481818 for 19.9, so 4.7% less input bought 11.0% less output, and 1 USDT was refused outright with the minimum reported as 19.786762. Above the floor the shortfall is linear and small: 0.001 USDT is about 1.5e-6 XMR.

Why is the amount I receive not identical to the quote?

Because the promise is written to eight decimals while the chain moves integers. A payout of 0.14598334 XMR is at most 145,983,340,000 piconero, and providers pay whole piconero; on top of that the rate is read again when the order is created. The rounding lives in the last digit, about 0.000006 dollars at today's price. Check the first four decimals, not the eighth.

Keep reading

All articles →

Ready to swap?

No account · No KYC · No email

Exchange now
Crypto Amount Decimals: Where Less Actually Costs Money — VeilSwap