Integration Flow
FX fees and rounding
FX snapshots, fee application, unit conversions, and flooring rules.
FX fees and rounding
OpenPoly settles with integer units only.
Units
- credits-equivalent: integer,
10000 = 1 USDT - shares: integer micro-shares,
1000000 = 1 share - IDR: integer minor unit, exponent
0 - FX rate: IDR per
1 USDT - BPS denominator:
10000
No floating settlement values are persisted.
FX freshness
- target freshness:
<= 30seconds - hard stale threshold:
120seconds - stale FX beyond hard threshold -> execution fails before wallet mutation
Fee model
fx_fee_bpsoperator_fee_bpstotal_fee_bps = fx_fee_bps + operator_fee_bps
Rules:
- fee values are non-negative integers
- total fee must stay
< 10000 - buy applies fee before AMM quote
- sell and redemption apply fee after credits-equivalent proceeds known
Buy formula
Given:
amount_minoridr_per_usdttotal_fee_bps
net_bps = 10000 - total_fee_bps
credits_equivalent = floor(amount_minor * net_bps * 10000 / (10000 * idr_per_usdt))
Debit amount remains original amount_minor.
Sell formula
Given AMM credits-equivalent proceeds:
net_bps = 10000 - total_fee_bps
external_amount_minor = floor(credits * idr_per_usdt * net_bps / (10000 * 10000))
Redemption formula
credits_equivalent = floor(shares_micro * 10000 / 1000000)
net_bps = 10000 - total_fee_bps
external_amount_minor = floor(credits_equivalent * idr_per_usdt * net_bps / (10000 * 10000))
Rounding rule
Always floor final integer conversion. Never round up payout or buying power.
Quote safety
Execution rejects when:
- quote ID missing or changed
- FX snapshot stale beyond hard threshold
- final execution worse than accepted slippage
Why this matters for operators
- wallet side always sees integer IDR minor amounts
- webhook and reporting APIs expose already-rounded final values
- operator reconciliation should compare integer amounts only
