@@ -363,6 +363,9 @@ export default class polymarket extends Exchange {
363363 'defaultExpirationDays' : 30 , // Default expiration in days (default: 30 days from now)
364364 'defaultFeeRateBps' : 200 , // Default fee rate fallback in basis points (default: 200 bps = 2%)
365365 'defaultTickSize' : '0.01' , // Default tick size for rounding config (default: 0.01 = 2 decimal places for price, 2 for size, 4 for amount)
366+ 'marketOrderQuoteDecimals' : 2 , // Max decimal places for quote currency (USDC) in market orders (default: 2)
367+ 'marketOrderBaseDecimals' : 4 , // Max decimal places for base currency (tokens) in market orders (default: 4)
368+ 'roundingBufferDecimals' : 4 , // Additional decimal places buffer for rounding up before final rounding down (default: 4)
366369 // Constants matching clob-client
367370 // See https://github.com/Polymarket/clob-client/blob/main/src/signing/constants.ts
368371 // See https://github.com/Polymarket/clob-client/blob/main/src/constants.ts
@@ -1950,34 +1953,62 @@ export default class polymarket extends Exchange {
19501953 }
19511954 // Round price and size first, then calculate amounts (same logic for limit and market orders)
19521955 const rawPrice = this . roundNormal ( orderPrice , priceDecimals ) ;
1956+ // Check if this is a market order for special decimal handling
1957+ const orderType = this . safeString ( params , 'orderType' , 'limit' ) ;
1958+ const isMarketOrder = ( orderType === 'market' ) ;
1959+ // Get rounding buffer constant
1960+ const roundingBuffer = this . safeInteger ( this . options , 'roundingBufferDecimals' , 4 ) ;
1961+ // Determine decimal precision based on order type and side
1962+ let makerDecimals = 0 ;
1963+ let takerDecimals = 0 ;
1964+ if ( isMarketOrder ) {
1965+ // Get market order decimal limits for quote (USDC) and base (tokens)
1966+ const marketOrderQuoteDecimals = this . safeInteger ( this . options , 'marketOrderQuoteDecimals' , 2 ) ;
1967+ const marketOrderBaseDecimals = this . safeInteger ( this . options , 'marketOrderBaseDecimals' , 4 ) ;
1968+ if ( isBuy ) {
1969+ // Market buy orders: maker gives USDC (quote), taker gives tokens (base)
1970+ makerDecimals = marketOrderQuoteDecimals ;
1971+ takerDecimals = marketOrderBaseDecimals ;
1972+ } else {
1973+ // Market sell orders: maker gives tokens (base), taker gives USDC (quote)
1974+ makerDecimals = marketOrderBaseDecimals ;
1975+ takerDecimals = marketOrderQuoteDecimals ;
1976+ }
1977+ } else {
1978+ // Limit orders: use amountDecimals for both
1979+ makerDecimals = amountDecimals ;
1980+ takerDecimals = amountDecimals ;
1981+ }
19531982 if ( isBuy ) {
19541983 // BUY: maker gives USDC, wants tokens
19551984 // Round down size first
1956- const rawTakerAmt = this . roundDown ( size , sizeDecimals ) ;
1985+ let rawTakerAmt = this . roundDown ( size , sizeDecimals ) ;
1986+ // Round taker amount to max decimals
1987+ if ( this . decimalPlaces ( rawTakerAmt ) > takerDecimals ) {
1988+ rawTakerAmt = this . roundDown ( rawTakerAmt , takerDecimals ) ;
1989+ }
19571990 // Calculate maker amount: raw_maker_amt = raw_taker_amt * raw_price
19581991 let rawMakerAmt = Precise . stringMul ( rawTakerAmt , rawPrice ) ;
1959- // Apply rounding logic if too many decimal places
1960- if ( this . decimalPlaces ( rawMakerAmt ) > amountDecimals ) {
1961- rawMakerAmt = this . roundUp ( rawMakerAmt , amountDecimals + 4 ) ;
1962- if ( this . decimalPlaces ( rawMakerAmt ) > amountDecimals ) {
1963- rawMakerAmt = this . roundDown ( rawMakerAmt , amountDecimals ) ;
1964- }
1992+ // Apply rounding logic for maker amount if too many decimal places
1993+ if ( this . decimalPlaces ( rawMakerAmt ) > makerDecimals ) {
1994+ rawMakerAmt = this . roundDown ( rawMakerAmt , makerDecimals ) ;
19651995 }
19661996 // Convert to smallest units: maker gives USDC (quoteDecimals), taker gives tokens (baseDecimals)
19671997 makerAmount = this . toTokenDecimals ( rawMakerAmt , quoteDecimals ) ;
19681998 takerAmount = this . toTokenDecimals ( rawTakerAmt , baseDecimals ) ;
19691999 } else {
19702000 // SELL: maker gives tokens, wants USDC
19712001 // Round down size first
1972- const rawMakerAmt = this . roundDown ( size , sizeDecimals ) ;
2002+ let rawMakerAmt = this . roundDown ( size , sizeDecimals ) ;
2003+ // Round maker amount to max decimals
2004+ if ( this . decimalPlaces ( rawMakerAmt ) > makerDecimals ) {
2005+ rawMakerAmt = this . roundDown ( rawMakerAmt , makerDecimals ) ;
2006+ }
19732007 // Calculate taker amount: raw_taker_amt = raw_maker_amt * raw_price
19742008 let rawTakerAmt = Precise . stringMul ( rawMakerAmt , rawPrice ) ;
1975- // Apply rounding logic if too many decimal places
1976- if ( this . decimalPlaces ( rawTakerAmt ) > amountDecimals ) {
1977- rawTakerAmt = this . roundUp ( rawTakerAmt , amountDecimals + 4 ) ;
1978- if ( this . decimalPlaces ( rawTakerAmt ) > amountDecimals ) {
1979- rawTakerAmt = this . roundDown ( rawTakerAmt , amountDecimals ) ;
1980- }
2009+ // Apply rounding logic for taker amount if too many decimal places
2010+ if ( this . decimalPlaces ( rawTakerAmt ) > takerDecimals ) {
2011+ rawTakerAmt = this . roundDown ( rawTakerAmt , takerDecimals ) ;
19812012 }
19822013 // Convert to smallest units: maker gives tokens (baseDecimals), taker gives USDC (quoteDecimals)
19832014 makerAmount = this . toTokenDecimals ( rawMakerAmt , baseDecimals ) ;
@@ -2119,6 +2150,8 @@ export default class polymarket extends Exchange {
21192150 // For non-GTD orders, expiration must be 0 (will be converted to "0" string in signing)
21202151 orderParams [ 'expiration' ] = 0 ;
21212152 }
2153+ // Pass order type to buildAndSignOrder for market order special handling
2154+ orderParams [ 'orderType' ] = type ;
21222155 // Build and sign the order with EIP-712 (pass market to use fees from market)
21232156 const signedOrder = await this . buildAndSignOrder ( tokenId , polymarketSide , size , priceStr , market , orderParams ) ;
21242157 // override signedOrder types
0 commit comments