Skip to content

fix(clob): enforce backend precision limits for market orders#165

Open
Haut wants to merge 5 commits intoPolymarket:mainfrom
Haut:fix/market-order-precision-rounding
Open

fix(clob): enforce backend precision limits for market orders#165
Haut wants to merge 5 commits intoPolymarket:mainfrom
Haut:fix/market-order-precision-rounding

Conversation

@Haut
Copy link
Contributor

@Haut Haut commented Jan 11, 2026

Fixes #114

The existing implementation in OrderBuilder<Market, K>::build() calculated maker/taker amounts using:

(raw_amount / price).trunc_with_scale(decimals + LOT_SIZE_SCALE)

Where decimals is the tick size scale (1-4) and LOT_SIZE_SCALE is 2. This produces amounts with 3-6 decimal places depending on tick size, violating the backend's strict precision requirements:

Order Side Maker Asset Max Precision Taker Asset Max Precision
BUY USDC 2 decimals Shares 4 decimals
SELL Shares 2 decimals USDC 4 decimals

Changes Made

  1. Added RoundingStrategy enum with three variants:

    • Down (default) - Truncate towards zero (safest to avoid overspending)
    • HalfUp - Standard rounding (round 0.5 away from zero)
    • Up - Round away from zero
  2. Added .rounding_strategy() builder method on OrderBuilder<Market, K> allowing users to configure rounding behavior per-order

  3. Implemented context-aware rounding that respects the backend's precision matrix:

    • BUY orders: Maker (USDC) → 2 decimals, Taker (shares) → 4 decimals
    • SELL orders: Maker (shares) → 2 decimals, Taker (USDC) → 4 decimals
  4. Added zero-amount validation - Returns Error::validation() when rounding produces zero amounts (e.g., trying to sell 0.001 shares when limit is 0.01)

  5. Exported RoundingStrategy from the clob module for user access

Tests

  • Integration tests for market order building pass
  • Integration test against live/testnet API

Market orders (FOK/FAK) were being rejected by the backend due to
precision violations. The backend requires maker amounts to have max
2 decimal places and taker amounts to have max 4 decimal places.

Changes:
- Add RoundingStrategy enum (Down, HalfUp, Up) with Down as default
- Add .rounding_strategy() builder method for OrderBuilder<Market, K>
- Apply context-aware rounding based on order side:
  - BUY: maker=USDC(2 dec), taker=shares(4 dec)
  - SELL: maker=shares(2 dec), taker=USDC(4 dec)
- Add validation to reject orders where amounts round to zero
- Export RoundingStrategy from clob module

Fixes Polymarket#114
@Haut
Copy link
Contributor Author

Haut commented Jan 11, 2026

@chaz-polymarket this fixes #114 for me. adds an optional builder method for setting rounding and matches the other python / ts clients from what I can see. tested live and seems to work for everything I tried. not sure if you want to get in before 0.4 but its here if needed

@codecov
Copy link

codecov bot commented Jan 11, 2026

Codecov Report

❌ Patch coverage is 95.00000% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 85.96%. Comparing base (0169712) to head (1214f60).

Files with missing lines Patch % Lines
src/clob/order_builder.rs 94.93% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #165      +/-   ##
==========================================
+ Coverage   85.81%   85.96%   +0.14%     
==========================================
  Files          32       32              
  Lines        4885     4965      +80     
==========================================
+ Hits         4192     4268      +76     
- Misses        693      697       +4     
Flag Coverage Δ
rust 85.96% <95.00%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@2msd
Copy link

2msd commented Feb 17, 2026

Is it possible that this affects limit orders too?

If I try to sell an amount of shares with a limit oder, I get "not available funds". If I subtract 0.01 from the amount, the sell order goes though.

If this is another issue, I will gladly open a new ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants