Package: @polymarket/clob-client-v2@1.0.8 (latest)
Affected code: getMarketOrderRawAmounts in src/order-builder/helpers (both BUY and SELL branches)
Summary
For market orders, getMarketOrderRawAmounts rounds the taker amount using the tick-size precision from ROUNDING_CONFIG (amount: 5 for tick 0.001, amount: 6 for 0.0001). But the CLOB API only accepts market-order amounts with maker ≤ 2 decimals and taker ≤ 4 decimals, so whenever the rounded taker ends up with a non-zero 5th/6th decimal the order is rejected server-side:
invalid amounts, the market buy orders maker amount supports a max accuracy of 2 decimals, taker amount a max of 4 decimals
The client itself produces the invalid payload, so there is nothing an SDK consumer can do about it short of patching the package (the rounding happens inside createMarketOrder/buildMarketOrderCreationArgs right before signing).
Reproduction
// node >= 18, after `npm i @polymarket/clob-client-v2@1.0.8`
const { buildMarketOrderCreationArgs } = await import(
'./node_modules/@polymarket/clob-client-v2/dist/order-builder/helpers/buildMarketOrderCreationArgs.js'
)
const { ROUNDING_CONFIG } = await import(
'./node_modules/@polymarket/clob-client-v2/dist/order-builder/helpers/roundingConfig.js'
)
// BUY $5 at 0.998 on a 0.001-tick market
const buy = await buildMarketOrderCreationArgs(
'0x0000000000000000000000000000000000000001',
'0x0000000000000000000000000000000000000001',
0,
{ tokenID: '1', amount: 5, price: 0.998, side: 'BUY' },
ROUNDING_CONFIG['0.001']
)
console.log(buy.takerAmount) // 5010020 = 5.01002 shares -> 5 decimals, rejected
// SELL 7.77 shares at 0.998
const sell = await buildMarketOrderCreationArgs(
'0x0000000000000000000000000000000000000001',
'0x0000000000000000000000000000000000000001',
0,
{ tokenID: '1', amount: 7.77, price: 0.998, side: 'SELL' },
ROUNDING_CONFIG['0.001']
)
console.log(sell.takerAmount) // 7754460 = 7.75446 USDC -> 5 decimals, rejected
Math: 5 / 0.998 = 5.010020… → roundDown(…, 5) = 5.01002 (5 decimals). Any price with 3+ significant decimals routinely produces this; it only slips through when the 5th decimal happens to be zero.
The 2/4-decimals cap appears to be specific to market orders (the server error says "the market buy orders …"): limit orders built by getOrderRawAmounts use the same tick precision (5–6 decimals) and are accepted fine.
Suggested fix
Cap the taker amount at 4 decimals (round down, so the order stays marketable and never asks for more than the fair amount) in both branches of getMarketOrderRawAmounts:
if (decimalPlaces(rawTakerAmt) > 4) rawTakerAmt = roundDown(rawTakerAmt, 4);
We are running exactly this as a local patch on top of 1.0.8 and rejections disappeared. Happy to open a PR if useful.
Package:
@polymarket/clob-client-v2@1.0.8(latest)Affected code:
getMarketOrderRawAmountsinsrc/order-builder/helpers(both BUY and SELL branches)Summary
For market orders,
getMarketOrderRawAmountsrounds the taker amount using the tick-size precision fromROUNDING_CONFIG(amount: 5for tick0.001,amount: 6for0.0001). But the CLOB API only accepts market-order amounts with maker ≤ 2 decimals and taker ≤ 4 decimals, so whenever the rounded taker ends up with a non-zero 5th/6th decimal the order is rejected server-side:The client itself produces the invalid payload, so there is nothing an SDK consumer can do about it short of patching the package (the rounding happens inside
createMarketOrder/buildMarketOrderCreationArgsright before signing).Reproduction
Math:
5 / 0.998 = 5.010020…→roundDown(…, 5) = 5.01002(5 decimals). Any price with 3+ significant decimals routinely produces this; it only slips through when the 5th decimal happens to be zero.The 2/4-decimals cap appears to be specific to market orders (the server error says "the market buy orders …"): limit orders built by
getOrderRawAmountsuse the same tick precision (5–6 decimals) and are accepted fine.Suggested fix
Cap the taker amount at 4 decimals (round down, so the order stays marketable and never asks for more than the fair amount) in both branches of
getMarketOrderRawAmounts:We are running exactly this as a local patch on top of 1.0.8 and rejections disappeared. Happy to open a PR if useful.