Trading
Prices and rounding
How the minimum is computed from your limit, and how output rounds.
Every number on chain is an integer in token base units. The app shows human prices; the program works in raw ones. This page shows how one becomes the other, and how each rounding step is chosen so a fill at exactly your limit still goes through.
#Price units
A market has a base token A and a quote token B. Chord’s price is a fraction of two u64 integers: raw B per raw A. The price you see is that fraction scaled by the decimals of both tokens:
human price = (numerator / denominator) × 10^(decimals A − decimals B)For a pair with 9-decimal A and 6-decimal B, a committed price of 14220 / 100000 raw B per raw A reads as 142.20 B per A.
#Your minimum
When you sign, the app turns your amount and limit into You receive at least, the minBuyAmount in your order. With the limit written as a fraction n / d in human units:
| You | Minimum, in raw units of what you buy |
|---|---|
| Sell A for B | floor(sell × n × 10^decB / (d × 10^decA)) |
| Sell B for A | floor(sell × d × 10^decA / (n × 10^decB)) |
Rounding down makes your minimum a hair more lenient than the exact limit, never stricter, so a batch that clears exactly at your limit fills you.
#Example: selling
Sell 2 A (2000000000 raw, 9 decimals) with a limit of 142.20 B per A (6 decimals):
floor(2000000000 × 14220 × 10^6 / (100 × 10^9)) = 284400000 raw B = 284.40 B#Example: buying
Pay 500 B (500000000 raw) with a limit of 143.00 B per A:
floor(500000000 × 100 × 10^9 / (14300 × 10^6)) = 3496503496 raw A ≈ 3.4965 A#Your output
At a committed price p = numerator / denominator, the program pays:
| You sell | Output |
|---|---|
| A | floor(sell × numerator / denominator) raw B |
| B | floor(sell × denominator / numerator) raw A |
The program then checks everything you’ve received against your minimum, scaled to everything sold so far: received ≥ ceil(sold × minBuy / sell). A fill that fails this check is rejected outright; it can’t pay you a little less.
#Partial fills
If you allow partial fills, a fill can cover part of your sell amount. The program tracks your cumulative sold and received amounts on the order’s receipt and pays each increment as the difference between floor(cumulative sell × price) and what it already paid you. Splitting a fill can’t create or lose a base unit: three partial fills pay exactly what one fill of the same total would.
Very small partial fills can fail the proportional minimum because of rounding. Solvers avoid them.
#The same price for everyone
Every fill in a batch uses the one price in the batch account. Two orders on the same side with the same amount receive exactly the same output, whatever their limits and whenever they were signed. Your limit decides whether you fill, not what you get.