From 3ad0048c35b8f82460b0cd6c595b77acd27fe162 Mon Sep 17 00:00:00 2001 From: Etherdrake Date: Fri, 17 Apr 2026 21:53:51 +0200 Subject: [PATCH] Docs update 2026-04-17: CLOB V2 migration guide, changelog Apr 17 update, new endpoints --- docs/api-reference/authentication.md | 42 +- .../markets/get-clob-market-info.md | 183 ++++++ .../markets/get-market-by-token.md | 122 ++++ docs/changelog/changelog.md | 30 + docs/concepts/pusd.md | 166 +++++ docs/market-makers/maker-rebates.md | 23 +- docs/resources/contracts.md | 79 +++ docs/trading/fees.md | 97 +-- docs/v2-migration.md | 609 ++++++++++++++++++ 9 files changed, 1242 insertions(+), 109 deletions(-) create mode 100644 docs/api-reference/markets/get-clob-market-info.md create mode 100644 docs/api-reference/markets/get-market-by-token.md create mode 100644 docs/concepts/pusd.md create mode 100644 docs/resources/contracts.md create mode 100644 docs/v2-migration.md diff --git a/docs/api-reference/authentication.md b/docs/api-reference/authentication.md index 81f0177..2761c5c 100644 --- a/docs/api-reference/authentication.md +++ b/docs/api-reference/authentication.md @@ -62,14 +62,14 @@ Before making authenticated requests, you need to obtain API credentials using L ```typescript theme={null} - import { ClobClient } from "@polymarket/clob-client"; + import { ClobClient } from "@polymarket/clob-client-v2"; import { Wallet } from "ethers"; // v5.8.0 - const client = new ClobClient( - "https://clob.polymarket.com", - 137, // Polygon mainnet - new Wallet(process.env.PRIVATE_KEY) - ); + const client = new ClobClient({ + host: "https://clob.polymarket.com", + chain: 137, // Polygon mainnet + signer: new Wallet(process.env.PRIVATE_KEY), + }); // Creates new credentials or derives existing ones const credentials = await client.createOrDeriveApiKey(); @@ -90,7 +90,7 @@ Before making authenticated requests, you need to obtain API credentials using L client = ClobClient( host="https://clob.polymarket.com", - chain_id=137, # Polygon mainnet + chain=137, # Polygon mainnet key=os.getenv("PRIVATE_KEY") ) @@ -137,7 +137,7 @@ Before making authenticated requests, you need to obtain API credentials using L ### Using the REST API -While we highly recommend using our provided clients to handle signing and authentication, the following is for developers who choose NOT to use our [Python](https://github.com/Polymarket/py-clob-client) or [TypeScript](https://github.com/Polymarket/clob-client) clients. +While we highly recommend using our provided clients to handle signing and authentication, the following is for developers who choose NOT to use our [Python](https://github.com/Polymarket/py-clob-client-v2) or [TypeScript](https://github.com/Polymarket/clob-client-v2) clients. **Create API Credentials** @@ -220,8 +220,8 @@ The `POLY_SIGNATURE` is generated by signing the following EIP-712 struct: Reference implementations: -* [TypeScript](https://github.com/Polymarket/clob-client/blob/main/src/signing/eip712.ts) -* [Python](https://github.com/Polymarket/py-clob-client/blob/main/py_clob_client/signing/eip712.py) +* [TypeScript](https://github.com/Polymarket/clob-client-v2/blob/main/src/signing/eip712.ts) +* [Python](https://github.com/Polymarket/py-clob-client-v2/blob/main/py_clob_client/signing/eip712.py) Response: @@ -249,24 +249,24 @@ All trading endpoints require these 5 headers: | `POLY_API_KEY` | User's API `apiKey` value | | `POLY_PASSPHRASE` | User's API `passphrase` value | -The `POLY_SIGNATURE` for L2 is an HMAC-SHA256 signature created using the user's API credentials `secret` value. Reference implementations can be found in the [TypeScript](https://github.com/Polymarket/clob-client/blob/main/src/signing/hmac.ts) and [Python](https://github.com/Polymarket/py-clob-client/blob/main/py_clob_client/signing/hmac.py) clients. +The `POLY_SIGNATURE` for L2 is an HMAC-SHA256 signature created using the user's API credentials `secret` value. Reference implementations can be found in the [TypeScript](https://github.com/Polymarket/clob-client-v2/blob/main/src/signing/hmac.ts) and [Python](https://github.com/Polymarket/py-clob-client-v2/blob/main/py_clob_client/signing/hmac.py) clients. ### CLOB Client ```typescript theme={null} - import { ClobClient } from "@polymarket/clob-client"; + import { ClobClient } from "@polymarket/clob-client-v2"; import { Wallet } from "ethers"; // v5.8.0 - const client = new ClobClient( - "https://clob.polymarket.com", - 137, - new Wallet(process.env.PRIVATE_KEY), - apiCreds, // Generated from L1 auth, API credentials enable L2 methods - 1, // signatureType explained below - funderAddress // funder explained below - ); + const client = new ClobClient({ + host: "https://clob.polymarket.com", + chain: 137, + signer: new Wallet(process.env.PRIVATE_KEY), + creds: apiCreds, // Generated from L1 auth, API credentials enable L2 methods + signatureType: 1, // signatureType explained below + funderAddress, // funder explained below + }); // Now you can trade! const order = await client.createAndPostOrder( @@ -283,7 +283,7 @@ The `POLY_SIGNATURE` for L2 is an HMAC-SHA256 signature created using the user's client = ClobClient( host="https://clob.polymarket.com", - chain_id=137, + chain=137, key=os.getenv("PRIVATE_KEY"), creds=api_creds, # Generated from L1 auth, API credentials enable L2 methods signature_type=1, # signatureType explained below diff --git a/docs/api-reference/markets/get-clob-market-info.md b/docs/api-reference/markets/get-clob-market-info.md new file mode 100644 index 0000000..9e09aeb --- /dev/null +++ b/docs/api-reference/markets/get-clob-market-info.md @@ -0,0 +1,183 @@ +> ## Documentation Index +> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt +> Use this file to discover all available pages before exploring further. + +# Get CLOB market info + +> Returns all CLOB-level parameters for a market in a single call — +tokens, tick size, base fees, rewards, RFQ status, and fee details. + + + + +## OpenAPI + +````yaml /api-spec/clob-openapi.yaml get /clob-markets/{condition_id} +openapi: 3.1.0 +info: + title: Polymarket CLOB API + description: Polymarket CLOB API Reference + license: + name: MIT + identifier: MIT + version: 1.0.0 +servers: + - url: https://clob.polymarket.com + description: Production CLOB API + - url: https://clob-staging.polymarket.com + description: Staging CLOB API +security: [] +tags: + - name: Trade + description: Trade endpoints + - name: Markets + description: Market data endpoints + - name: Account + description: Account and authentication endpoints + - name: Notifications + description: User notification endpoints + - name: Rewards + description: Rewards and earnings endpoints + - name: Rebates + description: Maker rebate endpoints +paths: + /clob-markets/{condition_id}: + get: + tags: + - Markets + summary: Get CLOB market info + description: | + Returns all CLOB-level parameters for a market in a single call — + tokens, tick size, base fees, rewards, RFQ status, and fee details. + operationId: getClobMarketInfo + parameters: + - name: condition_id + in: path + required: true + description: The condition ID of the market + schema: + type: string + example: '0xbd31dc8a20211944f6b70f31557f1001557b59905b7738480ca09bd4532f84af' + responses: + '200': + description: Successfully retrieved CLOB market info + content: + application/json: + schema: + $ref: '#/components/schemas/ClobMarketDetails' + '400': + description: Bad request - Invalid condition ID + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' +components: + schemas: + ClobMarketDetails: + type: object + description: >- + CLOB-level parameters for a market — tokens, tick size, base fees, + rewards, RFQ status, and fee details. + properties: + gst: + type: string + format: date-time + nullable: true + description: >- + Game start time (used for sports markets), ISO 8601 timestamp or + null + r: + $ref: '#/components/schemas/ClobRewards' + t: + type: array + description: Tokens for this market + items: + $ref: '#/components/schemas/ClobToken' + mos: + type: number + format: float + description: Minimum order size + example: 5 + mts: + type: number + format: float + description: Minimum tick size (price increment) + example: 0.01 + mbf: + type: integer + format: int64 + description: Maker base fee in basis points + example: 0 + tbf: + type: integer + format: int64 + description: Taker base fee in basis points + example: 0 + rfqe: + type: boolean + description: Whether RFQ (Request for Quote) is enabled for this market + itode: + type: boolean + description: Whether taker order delay is enabled + ibce: + type: boolean + description: Whether Blockaid check is enabled + fd: + $ref: '#/components/schemas/FeeDetails' + oas: + type: integer + description: Minimum order age in seconds + ErrorResponse: + type: object + required: + - error + properties: + error: + type: string + description: Error message + ClobRewards: + type: object + description: Rewards configuration for a market. + additionalProperties: true + ClobToken: + type: object + description: A token in a CLOB market with its ID and outcome label. + properties: + t: + type: string + description: The token ID + example: >- + 71321045679252212594626385532706912750332728571942532289631379312455583992563 + o: + type: string + description: Outcome label for the token (e.g. "Yes", "No") + example: 'Yes' + FeeDetails: + type: object + description: Fee curve parameters for a market. + properties: + r: + type: number + format: float + nullable: true + description: Fee rate + example: 0.02 + e: + type: number + format: float + nullable: true + description: Fee curve exponent + example: 2 + to: + type: boolean + nullable: true + description: Whether fees apply to takers only + example: true + +```` \ No newline at end of file diff --git a/docs/api-reference/markets/get-market-by-token.md b/docs/api-reference/markets/get-market-by-token.md new file mode 100644 index 0000000..1d9da35 --- /dev/null +++ b/docs/api-reference/markets/get-market-by-token.md @@ -0,0 +1,122 @@ +> ## Documentation Index +> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt +> Use this file to discover all available pages before exploring further. + +# Get market by token + +> Returns the parent market for a given token ID. Useful when you have +a token ID and need to resolve its parent market without knowing the +condition ID in advance. + + + + +## OpenAPI + +````yaml /api-spec/clob-openapi.yaml get /markets-by-token/{token_id} +openapi: 3.1.0 +info: + title: Polymarket CLOB API + description: Polymarket CLOB API Reference + license: + name: MIT + identifier: MIT + version: 1.0.0 +servers: + - url: https://clob.polymarket.com + description: Production CLOB API + - url: https://clob-staging.polymarket.com + description: Staging CLOB API +security: [] +tags: + - name: Trade + description: Trade endpoints + - name: Markets + description: Market data endpoints + - name: Account + description: Account and authentication endpoints + - name: Notifications + description: User notification endpoints + - name: Rewards + description: Rewards and earnings endpoints + - name: Rebates + description: Maker rebate endpoints +paths: + /markets-by-token/{token_id}: + get: + tags: + - Markets + summary: Get market by token + description: | + Returns the parent market for a given token ID. Useful when you have + a token ID and need to resolve its parent market without knowing the + condition ID in advance. + operationId: getMarketByToken + parameters: + - name: token_id + in: path + required: true + description: The token ID to look up the parent market for + schema: + type: string + responses: + '200': + description: Successfully retrieved market + content: + application/json: + schema: + $ref: '#/components/schemas/MarketByTokenResponse' + '400': + description: Invalid market - empty token_id + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '404': + description: Market not found for token + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorResponse' +components: + schemas: + MarketByTokenResponse: + type: object + description: >- + Response for GET /markets-by-token/{token_id} — condition ID and both + token IDs in the market. + required: + - condition_id + - primary_token_id + - secondary_token_id + properties: + condition_id: + type: string + description: The condition ID of the market containing the given token + example: '0xbd31dc8a20211944f6b70f31557f1001557b59905b7738480ca09bd4532f84af' + primary_token_id: + type: string + description: The primary (Yes) token ID + example: >- + 71321045679252212594626385532706912750332728571942532289631379312455583992563 + secondary_token_id: + type: string + description: The secondary (No) token ID + example: >- + 52114319501245915516055106046884209969926127482827954674443846427813813222426 + ErrorResponse: + type: object + required: + - error + properties: + error: + type: string + description: Error message + +```` \ No newline at end of file diff --git a/docs/changelog/changelog.md b/docs/changelog/changelog.md index 3122c1f..55fe553 100644 --- a/docs/changelog/changelog.md +++ b/docs/changelog/changelog.md @@ -6,6 +6,36 @@ > Welcome to the Polymarket Changelog. Here you will find any important changes to Polymarket, including but not limited to CLOB, API, UI and Mobile Applications. + + Polymarket is shipping a coordinated upgrade: **new Exchange contracts, a rewritten CLOB backend, and a new collateral token (pUSD)**. + + **Exchange upgrades go live April 22, 2026 at \~11:00 UTC with \~1 hour of downtime.** All integrations must migrate to the V2 SDK before the cutover — there will be no backward compatibility after go-live. + + **Full walkthrough:** [Migrating to CLOB V2](/v2-migration). Follow [Discord](https://discord.gg/polymarket), Telegram, and [status.polymarket.com](https://status.polymarket.com) for the exact start time. + + **Test against V2 now:** point your client at `https://clob-v2.polymarket.com`. On April 22, V2 takes over `https://clob.polymarket.com`, so no base-URL change is needed after the cutover. + + **What's changing** + + * New Exchange contracts (CTF Exchange V2 + Neg Risk CTF Exchange V2) + * **pUSD** replaces USDC.e as the collateral token (standard ERC-20 on Polygon, backed by USDC, backing enforced onchain) + * Order struct: `nonce`, `feeRateBps`, `taker` removed — `timestamp` (ms), `metadata`, `builder` added + * Fees are now set at match time — no more `feeRateBps` on orders + * Builder attribution is native via `builderCode` on orders (no more `builder-signing-sdk`) + * EIP-712 Exchange domain version bumps from `"1"` to `"2"` (ClobAuth stays at `"1"`) + + **What you need to do** + + * Install the V2 SDK — [`@polymarket/clob-client-v2`](https://www.npmjs.com/package/@polymarket/clob-client-v2) or [`py-clob-client-v2`](https://pypi.org/project/py-clob-client-v2/) — and remove the legacy `clob-client` / `py-clob-client` packages + * Update constructor from positional args to options object; rename `chainId` → `chain` + * Remove `feeRateBps`, `nonce`, and `taker` from your order creation code + * If you're a builder, copy your code from [Settings → Builder](https://polymarket.com/settings?tab=builder) and attach it to orders + * If you sign orders without the SDK, update the `verifyingContract` and the signed Order fields — see [For API users](/v2-migration#for-api-users) + * Plan for all open orders to be wiped at cutover + + **During the window:** Trading will be paused for \~1 hour on April 22 starting around 11:00 UTC. The SDK's hot-swap mechanism will auto-refresh the client when V2 goes live — no manual action needed if you're on the latest SDK. + + * **Support contact**: Added a link to [our Bridge API provider's support](https://intercom.help/funxyz/en/articles/10732578-contact-us) (Fun.xyz) for failed, stuck, or compliance-held bridge transactions. See [Deposit Status](/trading/bridge/status). diff --git a/docs/concepts/pusd.md b/docs/concepts/pusd.md new file mode 100644 index 0000000..d4f2a3f --- /dev/null +++ b/docs/concepts/pusd.md @@ -0,0 +1,166 @@ +> ## Documentation Index +> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt +> Use this file to discover all available pages before exploring further. + +# Polymarket USD + +> pUSD — the collateral token used for all trading on Polymarket + +**pUSD** (Polymarket USD) is the collateral token used for all trading on Polymarket. It's a standard ERC-20 token on Polygon, backed by USDC. The smart contract — which enables the withdrawal functionality — enforces the backing. No algorithmic peg, no fractional reserve. + + + **Day to day, nothing changes.** You load funds, see a balance, trade, and + withdraw. pUSD is the technical settlement layer underneath the same + experience you're used to. + + +*** + +## Why pUSD + +The protocol settles all trading activity in native USDC, providing a more capital efficient, scalable, and institutionally aligned settlement standard as the platform continues to grow. + +pUSD is a standard ERC-20 wrapper that represents a USDC claim. Wrapping and unwrapping are enforced onchain by the `CollateralOnramp` and `CollateralOfframp` contracts. + +*** + +## Key facts + +| | | +| -------------- | ----------------------- | +| Token standard | ERC-20 | +| Network | Polygon mainnet | +| Decimals | 6 | +| Backing | USDC (enforced onchain) | +| Transferable | Yes — standard ERC-20 | + +pUSD is designed to function within Polymarket. There are no current plans to list it on external exchanges. + +See the [Contracts](/resources/contracts) page for all collateral-related contract addresses. + +*** + +## Wrapping — USDC.e → pUSD + +Use the **CollateralOnramp** to wrap USDC.e into pUSD. + +```solidity theme={null} +function wrap(address _asset, address _to, uint256 _amount) external +``` + +**Parameters** + +* `_asset` — address of the asset being wrapped. Must be USDC.e. +* `_to` — recipient of the minted pUSD. Does not have to be `msg.sender`. +* `_amount` — amount to wrap, in USDC.e base units (6 decimals). + +**Requirements** + +* The caller must first approve the **CollateralOnramp** contract (not the pUSD token) to spend USDC.e. +* Reverts with `OnlyUnpaused()` if the admin has paused USDC.e. + +### Example + + + ```typescript TypeScript theme={null} + import { + createWalletClient, + createPublicClient, + http, + parseAbi, + parseUnits, + } from "viem"; + import { polygon } from "viem/chains"; + import { privateKeyToAccount } from "viem/accounts"; + + const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`); + const walletClient = createWalletClient({ account, chain: polygon, transport: http() }); + const publicClient = createPublicClient({ chain: polygon, transport: http() }); + + const ONRAMP = "0x93070a847efEf7F70739046A929D47a521F5B8ee" as const; + const USDCE = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174" as const; // USDC.e on Polygon + + const amount = parseUnits("100", 6); // 100 USDC.e + + // 1. Approve the Onramp to spend your USDC.e + const approveHash = await walletClient.writeContract({ + address: USDCE, + abi: parseAbi(["function approve(address spender, uint256 amount) returns (bool)"]), + functionName: "approve", + args: [ONRAMP, amount], + }); + await publicClient.waitForTransactionReceipt({ hash: approveHash }); + + // 2. Wrap USDC.e → pUSD + const wrapHash = await walletClient.writeContract({ + address: ONRAMP, + abi: parseAbi(["function wrap(address _asset, address _to, uint256 _amount)"]), + functionName: "wrap", + args: [USDCE, account.address, amount], + }); + await publicClient.waitForTransactionReceipt({ hash: wrapHash }); + ``` + + ```python Python theme={null} + from web3 import Web3 + + ONRAMP = "0x93070a847efEf7F70739046A929D47a521F5B8ee" + USDCE = "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174" + + amount = 100 * 10**6 # 100 USDC.e + + # 1. Approve the Onramp to spend your USDC.e + usdce = w3.eth.contract(address=USDCE, abi=[{ + "name": "approve", "type": "function", + "inputs": [{"name": "spender", "type": "address"}, + {"name": "amount", "type": "uint256"}], + "outputs": [{"type": "bool"}], + }]) + usdce.functions.approve(ONRAMP, amount).transact({"from": address}) + + # 2. Wrap USDC.e → pUSD + onramp = w3.eth.contract(address=ONRAMP, abi=[{ + "name": "wrap", "type": "function", + "inputs": [{"name": "_asset", "type": "address"}, + {"name": "_to", "type": "address"}, + {"name": "_amount", "type": "uint256"}], + "outputs": [], + }]) + onramp.functions.wrap(USDCE, address, amount).transact({"from": address}) + ``` + + +*** + +## Unwrapping — pUSD → USDC.e + +Use the **CollateralOfframp** to unwrap pUSD back into USDC.e. + +```solidity theme={null} +function unwrap(address _asset, address _to, uint256 _amount) external +``` + +**Parameters** + +* `_asset` — asset you want to receive. Must be USDC.e. +* `_to` — recipient of the underlying asset. +* `_amount` — amount of pUSD to unwrap (6 decimals). + +**Requirements** + +* The caller must first approve the **CollateralOfframp** contract to spend their pUSD. +* Same pause gate as the Onramp. + +*** + +## Next steps + + + + All Polymarket contract addresses and audits + + + + Deposit from other chains — auto-wraps to pUSD + + diff --git a/docs/market-makers/maker-rebates.md b/docs/market-makers/maker-rebates.md index 92f45d2..b9359e2 100644 --- a/docs/market-makers/maker-rebates.md +++ b/docs/market-makers/maker-rebates.md @@ -2,11 +2,15 @@ > Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt > Use this file to discover all available pages before exploring further. -# Maker Rebates Program +# Maker rebates -> Earn daily USDC rebates by providing liquidity on Polymarket +*** -Polymarket has enabled taker fees across multiple market categories. These fees fund a **Maker Rebates** program that pays daily USDC rebates to liquidity providers. +title: "Maker Rebates Program" +description: "Earn daily USDC rebates by providing liquidity on Polymarket" +--------------------------------------------------------------------------- + +Polymarket charges taker fees across multiple market categories. Fees are determined by the protocol at match time and fund a **Maker Rebates** program that pays daily USDC rebates to liquidity providers. *** @@ -27,7 +31,7 @@ Place orders that add liquidity to the book and get filled (i.e., your liquidity ### Payment -Rebates are paid daily in USDC, directly to your wallet. +Rebates are paid daily in USDC, directly to your wallet. A minimum accrued rebate of **\$1 USDC** is required for a payout. *** @@ -95,7 +99,7 @@ Totals are calculated per market, so you only compete with other makers in the s ## Taker Fee Structure -Taker fees are calculated in USDC and vary based on the share price. However, fees are collected in shares on buy orders and USDC on sell orders. The fee amount in USDC is symmetric around 50% probability — a trade at 30¢ incurs the same dollar fee as a trade at 70¢. +Taker fees are calculated in USDC and vary based on the share price. The fee amount in USDC is symmetric around 50% probability — a trade at 30¢ incurs the same dollar fee as a trade at 70¢.
@@ -118,7 +122,8 @@ Fees are rounded to 5 decimal places. The smallest fee charged is 0.00001 USDC. The following market categories have taker fees enabled and are eligible for maker rebates: Crypto, Sports, Finance, Politics, Economics, Culture, Weather, Tech, Mentions, and Other / General. - Fees apply only to markets deployed on or after the activation date. Pre-existing markets are unaffected. Markets with fees enabled have `feesEnabled` set to `true` on the market object. + Markets with fees enabled have `feesEnabled` set to `true` on the market + object. Query per-market fee parameters via `getClobMarketInfo(conditionID)`. *** @@ -131,7 +136,7 @@ The following market categories have taker fees enabled and are eligible for mak liquidity is taken by another trader). - Daily, in USDC. + Daily, in USDC. You must accrue at least \$1 in rebates before a payout is issued. Rebates are proportional to your share of executed maker liquidity in each @@ -145,11 +150,11 @@ The following market categories have taker fees enabled and are eligible for mak - Crypto, Sports, Finance, Politics, Economics, Culture, Weather, Tech, Mentions, and Other / General markets. Fees only apply to markets deployed on or after the activation date. + Crypto, Sports, Finance, Politics, Economics, Culture, Weather, Tech, Mentions, and Other / General markets. - Fees apply to markets in fee-enabled categories. Markets with fees enabled have `feesEnabled` set to `true` on the market object. + Fees apply to markets in fee-enabled categories. Markets with fees enabled have `feesEnabled` set to `true` on the market object — check it per-market via `getClobMarketInfo(conditionID)`. diff --git a/docs/resources/contracts.md b/docs/resources/contracts.md new file mode 100644 index 0000000..7ab99c6 --- /dev/null +++ b/docs/resources/contracts.md @@ -0,0 +1,79 @@ +> ## Documentation Index +> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt +> Use this file to discover all available pages before exploring further. + +# Contracts + +> All Polymarket smart contract addresses, audits, and security resources + +All Polymarket contracts are deployed on **Polygon mainnet** (Chain ID: 137). This is the single source of truth for all contract addresses used across the platform. + +*** + +## Core Trading Contracts + +| Contract | Address | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------- | +| CTF Exchange | [`0xE111180000d2663C0091e4f400237545B87B996B`](https://polygonscan.com/address/0xE111180000d2663C0091e4f400237545B87B996B) | +| Neg Risk CTF Exchange | [`0xe2222d279d744050d28e00520010520000310F59`](https://polygonscan.com/address/0xe2222d279d744050d28e00520010520000310F59) | +| Neg Risk Adapter | [`0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296`](https://polygonscan.com/address/0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296) | +| Conditional Tokens (CTF) | [`0x4D97DCd97eC945f40cF65F87097ACe5EA0476045`](https://polygonscan.com/address/0x4D97DCd97eC945f40cF65F87097ACe5EA0476045) | + +*** + +## Collateral Contracts + +| Contract | Address | +| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | +| pUSD — CollateralToken (proxy) | [`0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB`](https://polygonscan.com/address/0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB) | +| pUSD — CollateralToken (impl) | [`0x6bBCef9f7ef3B6C592c99e0f206a0DE94Ad0925f`](https://polygonscan.com/address/0x6bBCef9f7ef3B6C592c99e0f206a0DE94Ad0925f) | +| CollateralOnramp | [`0x93070a847efEf7F70739046A929D47a521F5B8ee`](https://polygonscan.com/address/0x93070a847efEf7F70739046A929D47a521F5B8ee) | +| CollateralOfframp | [`0x2957922Eb93258b93368531d39fAcCA3B4dC5854`](https://polygonscan.com/address/0x2957922Eb93258b93368531d39fAcCA3B4dC5854) | +| PermissionedRamp | [`0xebC2459Ec962869ca4c0bd1E06368272732BCb08`](https://polygonscan.com/address/0xebC2459Ec962869ca4c0bd1E06368272732BCb08) | +| CtfCollateralAdapter | [`0xADa100874d00e3331D00F2007a9c336a65009718`](https://polygonscan.com/address/0xADa100874d00e3331D00F2007a9c336a65009718) | +| NegRiskCtfCollateralAdapter | [`0xAdA200001000ef00D07553cEE7006808F895c6F1`](https://polygonscan.com/address/0xAdA200001000ef00D07553cEE7006808F895c6F1) | + +*** + +## Wallet Factory Contracts + +| Contract | Address | +| ------------------------ | -------------------------------------------------------------------------------------------------------------------------- | +| Gnosis Safe Factory | [`0xaacfeea03eb1561c4e67d661e40682bd20e3541b`](https://polygonscan.com/address/0xaacfeea03eb1561c4e67d661e40682bd20e3541b) | +| Polymarket Proxy Factory | [`0xaB45c5A4B0c941a2F231C04C3f49182e1A254052`](https://polygonscan.com/address/0xaB45c5A4B0c941a2F231C04C3f49182e1A254052) | + +*** + +## Resolution Contracts + +| Contract | Address | +| --------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| UMA Adapter | [`0x6A9D222616C90FcA5754cd1333cFD9b7fb6a4F74`](https://polygonscan.com/address/0x6A9D222616C90FcA5754cd1333cFD9b7fb6a4F74) | +| UMA Optimistic Oracle | [`0xCB1822859cEF82Cd2Eb4E6276C7916e692995130`](https://polygonscan.com/address/0xCB1822859cEF82Cd2Eb4E6276C7916e692995130) | + +*** + +## Security + +### Audits + +CTF Exchange V2 has been audited by two independent firms: + +| Auditor | Report | +| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Quantstamp | [CTF Exchange V2 — Quantstamp — March 2026](https://github.com/Polymarket/ctf-exchange-v2/blob/main/audits/CTF%20Exchange%20V2%20-%20Quantstamp%20-%20March%202026.pdf) | +| Cantina | [CTF Exchange V2 — Cantina — March 2026](https://github.com/Polymarket/ctf-exchange-v2/blob/main/audits/CTF%20Exchange%20V2%20-%20Cantina%20-%20March%202026.pdf) | + +### Bug Bounty + +Security vulnerabilities can be reported through the [Cantina bug bounty program](https://cantina.xyz/bounties/ff945ca2-2a6e-4b83-b1b6-7a0cd3b94bea). + +*** + +## Source Code + + + + Order matching and settlement contracts + + diff --git a/docs/trading/fees.md b/docs/trading/fees.md index 65a8226..bacf905 100644 --- a/docs/trading/fees.md +++ b/docs/trading/fees.md @@ -6,12 +6,14 @@ > Understanding trading fees on Polymarket -Polymarket charges a small taker fee on certain markets. These fees fund the [Maker Rebates Program](/market-makers/maker-rebates), which redistributes fees daily to market makers to incentivize deeper liquidity and tighter spreads. +Polymarket charges a small taker fee on certain markets. Fees are set by the protocol and applied at match time — you don't include fee information in your orders. These fees fund the [Maker Rebates Program](/market-makers/maker-rebates), which redistributes fees daily to market makers to incentivize deeper liquidity and tighter spreads. **Geopolitical and world events markets are fee-free.** Polymarket does not charge fees or profit from trading activity on these markets. There are also no Polymarket fees to deposit or withdraw USDC (though intermediaries like Coinbase or MoonPay may charge their own fees). - Fees apply only to markets deployed on or after the activation date. Pre-existing markets are unaffected. Markets with fees enabled have `feesEnabled` set to `true` on the market object. + Fees are determined per-market at match time. Markets with fees enabled have + `feesEnabled` set to `true` on the market object. Query fee parameters for + any market with `getClobMarketInfo(conditionID)`. *** @@ -42,7 +44,7 @@ Where **C** = number of shares traded and **p** = price of the shares. | Tech | 0.04 | 0 | 25% | | Geopolitics | 0 | 0 | — | -Taker fees are calculated in USDC and vary based on the share price. However, fees are collected in shares on buy orders and USDC on sell orders. The fee amount in USDC is symmetric around 50% probability — a trade at 30¢ incurs the same dollar fee as a trade at 70¢. +Taker fees are calculated in USDC and vary based on the share price. The fee amount in USDC is symmetric around 50% probability — a trade at 30¢ incurs the same dollar fee as a trade at 70¢.
@@ -172,86 +174,23 @@ Fees are rounded to 5 decimal places. The smallest fee charged is **0.00001 USDC *** -## Identifying Fee-Enabled Markets +## Fee Handling -Markets with fees have `feesEnabled` set to `true` on the market object. You can also query the fee-rate endpoint to check any specific market. See the [API Reference](/api-reference/introduction) for full endpoint documentation. +Fees are calculated and applied at match time by the protocol — you do not need to include fee information in your orders. The SDK handles everything automatically. -```bash theme={null} -GET https://clob.polymarket.com/fee-rate?token_id={token_id} -``` +To query fee parameters for a specific market, use `getClobMarketInfo(conditionID)`: -*** + + ```typescript TypeScript theme={null} + const info = await client.getClobMarketInfo(conditionID); + // info.fd = { r: feeRate, e: exponent, to: takerOnly } + ``` -## Fee Handling for API Users - -### Using the SDK - -The official CLOB clients **automatically handle fees** for you — they fetch the fee rate and include it in the signed order payload. - - - - npm install @polymarket/clob-client\@latest - - - - pip install --upgrade py-clob-client - - - - cargo add polymarket-client-sdk - - - -**What the client does automatically:** - -1. Fetches the fee rate for the market's token ID -2. Includes `feeRateBps` in the order structure -3. Signs the order with the fee rate included - -**You don't need to do anything extra.** Your orders will work on fee-enabled markets. - -### Using the REST API - -If you're calling the REST API directly or building your own order signing, you must manually include the fee rate in your signed order payload. - -**Step 1:** Fetch the fee rate for the token ID before creating your order: - -```bash theme={null} -GET https://clob.polymarket.com/fee-rate?token_id={token_id} -``` - -See the [fee-rate API Reference](/api-reference/introduction) for full response details. Fee-enabled markets return a non-zero value; fee-free markets return `0`. - -**Step 2:** Add the `feeRateBps` field to your order object. This value is part of the signed payload — the CLOB validates your signature against it. - -```json theme={null} -{ - "salt": "12345", - "maker": "0x...", - "signer": "0x...", - "taker": "0x...", - "tokenId": "71321045679252212594626385532706912750332728571942532289631379312455583992563", - "makerAmount": "50000000", - "takerAmount": "100000000", - "expiration": "0", - "nonce": "0", - "feeRateBps": "1000", - "side": "0", - "signatureType": 2, - "signature": "0x..." -} -``` - -**Step 3:** Sign and submit: - -1. Include `feeRateBps` in the order object **before signing** -2. Sign the complete order -3. POST to the order endpoint - - - Always fetch `fee_rate_bps` dynamically — do not hardcode. The fee rate varies - by market type and may change over time. You only need to pass `feeRateBps`. - + ```python Python theme={null} + info = client.get_clob_market_info(condition_id) + # info["fd"] = { "r": fee_rate, "e": exponent, "to": taker_only } + ``` + *** diff --git a/docs/v2-migration.md b/docs/v2-migration.md new file mode 100644 index 0000000..50b0bdf --- /dev/null +++ b/docs/v2-migration.md @@ -0,0 +1,609 @@ +> ## Documentation Index +> Fetch the complete documentation index at: https://docs.polymarket.com/llms.txt +> Use this file to discover all available pages before exploring further. + +# Migrating to CLOB V2 + +> A complete guide to upgrading your integration to Polymarket's CLOB V2 — new contracts, new backend, new collateral token, and a simpler builder program. + +Polymarket is shipping a coordinated upgrade of its entire trading infrastructure: **new Exchange contracts**, a **rewritten CLOB backend**, and a **new collateral token** (Polymarket USD, or pUSD). This guide walks you through everything you need to migrate. + + + **Go-live: April 22, 2026 (\~11:00 UTC)** — approximately 1 hour of downtime. All open orders will be wiped during the cutover. Make sure your integration is on the V2 SDK before the maintenance window starts. + + + + **Test against V2 before go-live.** Point your client at `https://clob-v2.polymarket.com` to start integrating now. On April 22nd (\~11:00 UTC), V2 takes over the production URL — `https://clob.polymarket.com` — so you don't need to change the base URL again after the cutover. + + +*** + +## TL;DR + +| What | Before (V1) | After (V2) | +| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| SDK package | `@polymarket/clob-client` / `py-clob-client` | `@polymarket/clob-client-v2` / `py-clob-client-v2` | +| Constructor | Positional args | Options object, `chainId` → `chain` | +| Order fields | `nonce`, `feeRateBps`, `taker` | `timestamp` (ms), `metadata`, `builder` | +| Fees | Embedded in the signed order | Operator-set at match time | +| Collateral | USDC.e | **pUSD** (standard ERC-20, backed by USDC) | +| Builder auth | `POLY_BUILDER_*` HMAC headers + [`builder-signing-sdk`](https://github.com/Polymarket/builder-signing-sdk) | A single `builderCode` field on the order | +| EIP-712 domain version | `"1"` | `"2"` (exchange only — API auth unchanged) | +| Exchange `verifyingContract` (raw API signers) | V1 addresses | V2 addresses — see [Contracts](/resources/contracts) | +| Raw API order signing | V1 Order type | Updated Order type — [see API users section](#for-api-users) | + +**If you're on the latest SDK,** most of this is handled automatically. The hot-swap mechanism detects the cutover and refreshes the client without manual intervention. + +*** + +## Before you start + + + + Even if a section doesn't look relevant, skim it. V2 touches more surface area than any previous release. + + + + Install the V2 SDK: [`@polymarket/clob-client-v2`](https://www.npmjs.com/package/@polymarket/clob-client-v2) (TypeScript) or [`py-clob-client-v2`](https://pypi.org/project/py-clob-client-v2/) (Python). Don't keep using the old `clob-client` / `py-clob-client` packages — those only work against V1 and stop functioning after cutover. + + + + The order book is wiped during the maintenance window. Test your integration before the cutover. + + + + + **Order book wipe:** All open orders are cancelled as part of the cutover. Plan to re-place orders immediately after the window closes. + + +*** + +## What's changing + +### 1. New Exchange contracts + +The onchain exchange has been rewritten from the ground up. + +* Solidity upgraded from **0.8.15 → 0.8.30**, with Solady replacing OpenZeppelin for gas savings. +* Order struct simplified: `nonce`, `feeRateBps`, and `taker` removed; `timestamp`, `metadata`, `builder` added. +* EIP-712 exchange domain version bumped from `"1"` to `"2"`. +* Fees collected onchain at match time (no longer embedded in the signed order). +* Onchain cancel replaced with operator-controlled `pauseUser` / `unpauseUser`. +* Batched mint/merge operations for gas efficiency. + +See [Contracts](/resources/contracts) for V2 addresses. + +### 2. Rewritten CLOB backend + +The order manager, ledger, executor, balance checker, and tracker are all new services. From an integrator's perspective: + +* **Nonce system removed.** Order uniqueness now comes from `timestamp` (milliseconds). You no longer track nonces. +* **New fee model.** Platform fees are dynamic per market and queryable via `getClobMarketInfo()`. +* **Builder codes** enable integrator attribution and revenue sharing, replacing the old HMAC-header flow. + +### 3. New collateral token + +Polymarket is migrating from **USDC.e** to **pUSD** (Polymarket USD), a standard ERC-20 on Polygon backed by USDC. Backing is enforced onchain by the smart contract. + +* For users trading on polymarket.com, the frontend handles wrapping automatically with a one-time approval. +* Power users and API-only traders wrap their USDC.e into pUSD via the Collateral Onramp contract's `wrap()` function. + +*** + +## For API users + +If you sign and post orders directly (without the SDK), here's what changes in the wire protocol. SDK users can skip this section — the client handles it. + +### EIP-712 domain + +The Exchange domain version bumps to `"2"` and the `verifyingContract` moves to the V2 Exchange. + +```ts theme={null} +{ + name: "Polymarket CTF Exchange", + version: "1", // [!code --] + version: "2", // [!code ++] + chainId: 137, + verifyingContract: "0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E", // [!code --] + verifyingContract: "0xE111180000d2663C0091e4f400237545B87B996B", // [!code ++] +} +``` + +For Neg Risk markets, the `verifyingContract` is different: + +```ts theme={null} +{ + verifyingContract: "0xC5d563A36AE78145C45a50134d48A1215220f80a", // [!code --] + verifyingContract: "0xe2222d279d744050d28e00520010520000310F59", // [!code ++] +} +``` + +See [Contracts](/resources/contracts) for the canonical V2 addresses. + + + **Only the Exchange domain changes.** The `ClobAuthDomain` used for L1 API authentication stays at version `"1"` — L1/L2 auth is identical in V2. + + +### EIP-712 Order type + +The signed struct drops `taker`, `expiration`, `nonce`, and `feeRateBps`, and adds `timestamp`, `metadata`, and `builder`. + +```ts theme={null} +Order( + uint256 salt, + address maker, + address signer, + address taker, // [!code --] + uint256 tokenId, + uint256 makerAmount, + uint256 takerAmount, + uint256 expiration, // [!code --] + uint256 nonce, // [!code --] + uint256 feeRateBps, // [!code --] + uint8 side, + uint8 signatureType // [!code --] + uint8 signatureType, // [!code ++] + uint256 timestamp, // [!code ++] + bytes32 metadata, // [!code ++] + bytes32 builder // [!code ++] +) +``` + +### Order value to sign + +```ts theme={null} +{ + salt: "12345", + maker: "0x...", + signer: "0x...", + taker: "0x0000000000000000000000000000000000000000", // [!code --] + tokenId: "102936...", + makerAmount: "1000000", + takerAmount: "2000000", + expiration: "0", // [!code --] + nonce: "0", // [!code --] + feeRateBps: "0", // [!code --] + side: 0, + signatureType: 1 // [!code --] + signatureType: 1, // [!code ++] + timestamp: "1713398400000", // [!code ++] + metadata: "0x0000000000000000000000000000000000000000000000000000000000000000", // [!code ++] + builder: "0x0000000000000000000000000000000000000000000000000000000000000000" // [!code ++] +} +``` + +* **`timestamp`** — order creation time in milliseconds. Replaces `nonce` for per-address uniqueness (not an expiration). +* **`metadata`** — bytes32. +* **`builder`** — bytes32. Zero unless you're attaching a builder code. + +`side` is encoded as `uint8` in the signing payload (`0` = BUY, `1` = SELL), even though the wire body uses the string `"BUY"` / `"SELL"`. No change from V1. + +### POST /order body + +```ts theme={null} +{ + "order": { + "salt": "12345", + "maker": "0x...", + "signer": "0x...", + "taker": "0x0000000000000000000000000000000000000000", // [!code --] + "tokenId": "102936...", + "makerAmount": "1000000", + "takerAmount": "2000000", + "expiration": "0", // [!code --] + "nonce": "0", // [!code --] + "feeRateBps": "0", // [!code --] + "side": "BUY", + "signatureType": 1, + "timestamp": "1713398400000", // [!code ++] + "metadata": "0x0000000000000000000000000000000000000000000000000000000000000000", // [!code ++] + "builder": "0x0000000000000000000000000000000000000000000000000000000000000000", // [!code ++] + "signature": "0x..." + }, + "owner": "", + "orderType": "GTC" +} +``` + +### Request headers + +The API auth headers are unchanged. Builder attribution moves into the signed `builder` field on the order, so the `POLY_BUILDER_*` HMAC headers are gone. + +```yaml theme={null} +POLY_ADDRESS: 0x... +POLY_SIGNATURE: 0x... +POLY_TIMESTAMP: 1713398400 +POLY_API_KEY: ... +POLY_PASSPHRASE: ... +POLY_BUILDER_API_KEY: ... # [!code --] +POLY_BUILDER_SECRET: ... # [!code --] +POLY_BUILDER_PASSPHRASE: ... # [!code --] +POLY_BUILDER_SIGNATURE: 0x... # [!code --] +``` + +*** + +## SDK Migration + +### Install + +CLOB V2 ships under new package names. Install them directly — don't keep using the old `clob-client` / `py-clob-client` packages. + + + ```bash TypeScript theme={null} + npm install @polymarket/clob-client-v2@1.0.0 + ``` + + ```bash Python theme={null} + pip install py-clob-client-v2==1.0.0 + ``` + + + + The legacy `@polymarket/clob-client` and `py-clob-client` packages only work against V1 and will stop functioning after the April 22 cutover. + + + + **What's next.** We're planning a unified SDK that folds Gamma, Data, and CLOB into a single package. Future releases will converge there — for now, `clob-client-v2` / `py-clob-client-v2` are the V2 CLOB clients. + + +### Constructor: positional args → options object + +The single most visible change. `chainId` is renamed to `chain`. `tickSizeTtlMs` is no longer configurable. + + + ```typescript Before (V1) theme={null} + const client = new ClobClient( + host, + chainId, + signer, + creds, + signatureType, + funderAddress, + useServerTime, + builderConfig, + getSigner, + retryOnError, + tickSizeTtlMs, // ← removed in V2 + throwOnError, + ); + ``` + + ```typescript After (V2) theme={null} + const client = new ClobClient({ + host, + chain: chainId, // ← renamed from chainId + signer, + creds, + signatureType, + funderAddress, + useServerTime, + builderConfig, // shape changed — see Builder Program below + getSigner, + retryOnError, + throwOnError, + }); + ``` + + + + The only mental shift: wrap args in `{}` and rename `chainId` → `chain`. Everything else is the same. + + +### Order creation + +Three fields are no longer user-settable: `feeRateBps`, `nonce`, `taker`. One new optional field: `builderCode`. + + + ```typescript Before (V1) theme={null} + const order: UserOrder = { + tokenID: "0x123...", + price: 0.55, + size: 100, + side: Side.BUY, + feeRateBps: 100, // ← removed + nonce: 12345, // ← removed + taker: "0xabc...", // ← removed + expiration: 1714000000, + }; + ``` + + ```typescript After (V2) theme={null} + const order: UserOrderV2 = { + tokenID: "0x123...", + price: 0.55, + size: 100, + side: Side.BUY, + expiration: 1714000000, + builderCode: "0x...", // optional — your builder code + }; + ``` + + +**Market orders** follow the same pattern and add an optional `userUSDCBalance` field so the SDK can calculate fee-adjusted fill amounts: + +```typescript theme={null} +const marketOrder: UserMarketOrderV2 = { + tokenID: "0x123...", + amount: 500, + side: Side.BUY, + orderType: OrderType.FOK, + userUSDCBalance: 1000, // optional — enables fee-aware calculations + builderCode: "0x...", // optional +}; +``` + +## Fee model + +Fees are now **determined by the protocol at match time**, not embedded in your signed order. + +* **Platform fees** are dynamic per market: `fee = C × feeRate × p × (1 - p)` +* **Makers are never charged fees** — only takers pay. +* You no longer set `feeRateBps` on orders. The SDK handles fee calculation automatically. + +### Querying fee parameters + +V2 introduces `getClobMarketInfo()`, which returns all CLOB-level market parameters in one call: + + + ```typescript TypeScript theme={null} + const info = await client.getClobMarketInfo(conditionID); + // info.mts — minimum tick size + // info.mos — minimum order size + // info.fd — fee details { r: rate, e: exponent, to: takerOnly } + // info.t — tokens [{ t: tokenID, o: outcome }, ...] + // info.rfqe — is RFQ enabled + ``` + + ```python Python theme={null} + info = client.get_clob_market_info(condition_id) + # info["mts"] — minimum tick size + # info["mos"] — minimum order size + # info["fd"] — fee details { "r", "e", "to" } + # info["t"] — tokens list + ``` + + +If you were calculating fees manually in your integration, you can now rely on the SDK. Pass `userUSDCBalance` on market buy orders to get accurate fill amounts after fees. + +*** + +## Builder Program + +V2 replaces the old builder authentication flow (HMAC headers + separate signing SDK) with a native **builder code** attached directly to each order. + +### What's gone + +* `@polymarket/builder-signing-sdk` — **no longer needed** +* `POLY_BUILDER_API_KEY`, `POLY_BUILDER_SECRET`, `POLY_BUILDER_PASSPHRASE`, `POLY_BUILDER_SIGNATURE` headers +* Remote vs. local signing distinction + +### What's new + +* A single `builderCode` (bytes32) from your [Builder Profile](https://polymarket.com/settings?tab=builder) +* Attach it per-order via the `builderCode` field, **or** pass it once at construction so every order inherits it + + + `BuilderConfig` still exists, but its shape changed. In V1 it wrapped HMAC credentials from `@polymarket/builder-signing-sdk`. In V2 it's just `{ builderCode: string }`. + + + + ```typescript Before (V1) theme={null} + import { BuilderConfig, BuilderApiKeyCreds } from "@polymarket/builder-signing-sdk"; + + const builderConfig = new BuilderConfig({ + localBuilderCreds: new BuilderApiKeyCreds({ + key: process.env.POLY_BUILDER_API_KEY, + secret: process.env.POLY_BUILDER_SECRET, + passphrase: process.env.POLY_BUILDER_PASSPHRASE, + }), + }); + + const client = new ClobClient( + host, + chainId, + signer, + creds, + signatureType, + funderAddress, + undefined, + false, + builderConfig, + ); + ``` + + ```typescript After (V2) — per-order builder code theme={null} + const client = new ClobClient({ + host, + chain: chainId, + signer, + creds, + signatureType, + funderAddress, + }); + + await client.createAndPostOrder( + { + tokenID: "0x...", + price: 0.55, + size: 100, + side: Side.BUY, + builderCode: process.env.POLY_BUILDER_CODE, + }, + { tickSize: "0.01", negRisk: false }, + ); + ``` + + ```typescript After (V2) — pass once at construction theme={null} + const client = new ClobClient({ + host, + chain: chainId, + signer, + creds, + signatureType, + funderAddress, + builderConfig: { builderCode: process.env.POLY_BUILDER_CODE }, + }); + + // Every order posted by this client now carries your builder code. + await client.createAndPostOrder( + { + tokenID: "0x...", + price: 0.55, + size: 100, + side: Side.BUY, + }, + { tickSize: "0.01", negRisk: false }, + ); + ``` + + +*** + +## Collateral token: USDC.e → pUSD + +Polymarket USD (pUSD) replaces USDC.e as the collateral token. pUSD is a standard ERC-20 on Polygon backed by USDC, with backing enforced onchain by the smart contract. The permissionless Collateral Onramp accepts USDC.e. + +* **For users on polymarket.com:** the UI handles wrapping automatically. +* **For API-only traders:** wrap USDC.e into pUSD via the Collateral Onramp's `wrap()` function. See the [pUSD page](/concepts/pusd) for full examples and [Contracts](/resources/contracts) for addresses. + +*** + +## Test markets + +The following events have liquidity on `clob-v2.polymarket.com` — use them to dry-run your integration end-to-end before go-live. + +### US / Iran nuclear deal in 2027? + +* Event: [`gamma-api.polymarket.com/events/73106`](https://gamma-api.polymarket.com/events/73106) +* Orderbook: [`token_id=102936…7216`](https://clob-v2.polymarket.com/book?token_id=102936224134271070189104847090829839924697394514566827387181305960175107677216) + +### Highest grossing movie in 2026? + +* Event: [`gamma-api.polymarket.com/events/79831`](https://gamma-api.polymarket.com/events/79831) +* Orderbooks: + * [`token_id=81662…2777`](https://clob-v2.polymarket.com/book?token_id=81662326158871781857247725348568394697379926716334270967994039975048021832777) + * [`token_id=17546…1707`](https://clob-v2.polymarket.com/book?token_id=17546146554206665273662853938002443411871542020107489725107067382874986311707) + * [`token_id=28161…2479`](https://clob-v2.polymarket.com/book?token_id=28161183422242370392388296744035422249088647252796713903067039294971789722479) + * [`token_id=89576…4694`](https://clob-v2.polymarket.com/book?token_id=89576274136595202327975910079635847102293810595609428633134997662847357374694) + * [`token_id=21556…6607`](https://clob-v2.polymarket.com/book?token_id=21556669163785052148858748369786715040594704429426952390307023288865165566607) + * [`token_id=51020…2516`](https://clob-v2.polymarket.com/book?token_id=51020513216536535954567404775362000484668846352577848437115610667663875702516) + +*** + +## Migration checklist + +Work through this list as you update your integration: + + + + * [ ] Install `@polymarket/clob-client-v2` / `py-clob-client-v2` (remove the legacy `clob-client` / `py-clob-client` packages) + * [ ] Convert constructor calls from positional args to options object + * [ ] Rename `chainId` parameter to `chain` + * [ ] Remove `tickSizeTtlMs` and `geoBlockToken` from constructor config + + + + * [ ] Remove `feeRateBps`, `nonce`, `taker` from order creation calls + * [ ] Add `builderCode` to orders if you're a builder + * [ ] Pass `userUSDCBalance` on market buy orders for fee-adjusted fill amounts (optional) + * [ ] Remove any manual fee calculation logic — fees are protocol-handled + + + + * [ ] Remove `@polymarket/builder-signing-sdk` from dependencies + * [ ] Remove `POLY_BUILDER_*` environment variables + * [ ] Copy your builder code from [your Builder Profile](https://polymarket.com/settings?tab=builder) + * [ ] Store it as `POLY_BUILDER_CODE` (or any env var you prefer) + * [ ] Attach `builderCode` on every order to get attribution + + + + * [ ] Update any code that inspects raw order structs (new fields: `timestamp`, `metadata`, `builder`) + * [ ] Update manual EIP-712 signing code (Exchange domain version `"1"` → `"2"`) + * [ ] Update onchain contract references to new V2 addresses + + + + * [ ] If you're API-only, plan for wrapping USDC.e into pUSD via the Collateral Onramp + * [ ] Update any hardcoded references to the old USDC.e address + + + + * [ ] Test full order lifecycle on preprod + * [ ] Verify builder attribution appears on the [Builder Leaderboard](https://builders.polymarket.com) + * [ ] Plan for order book wipe — all open orders must be re-placed after migration + + + +*** + +## Cutover day + +**Go-live: April 22, 2026 (\~11:00 UTC).** The migration involves approximately **1 hour of downtime** during which trading is paused. + +**During the window:** + +* All open orders are wiped. You must re-place orders after the migration completes. +* The SDK's **hot-swap mechanism** queries a version endpoint and auto-refreshes when V2 goes live. +* If you're on the latest V2 SDK, **no manual intervention is needed during the cutover.** + +**If your integration is on the V1 SDK after migration, it will stop working.** There is no backward compatibility. + +Follow [Discord](https://discord.gg/polymarket), Telegram, and [status.polymarket.com](https://status.polymarket.com) for the exact maintenance window start time. The window is scheduled to avoid large market resolutions. + +*** + +## FAQ + + + + No. L1/L2 authentication is identical in V2. Your existing API key, secret, and passphrase continue to work. + + + + No — all open orders are wiped during the maintenance window. Re-place them after the window closes. + + + + Your V1 client will fail against the V2 backend after cutover. There is no backward compatibility — upgrade before the maintenance window ends. + + + + If you're trading through polymarket.com, no — the UI handles wrapping automatically with a one-time approval. If you're API-only, you'll need to call `wrap()` on the Collateral Onramp contract. + + + + No. Builder codes are **public identifiers** — they appear onchain in the `builder` field of every attributed order. Only you control which orders include your code, so keep it scoped to apps you own. + + + + Remove the manual calculation. Use `getClobMarketInfo(conditionID)` to query fee parameters (`fd.r`, `fd.e`, `fd.to`), and rely on the SDK to handle fee-adjusted amounts. Pass `userUSDCBalance` on market buy orders for accurate fill math. + + + + WebSocket URLs are unchanged. Most message payloads are unchanged. The `fee_rate_bps` field on `last_trade_price` events continues to reflect the fee actually charged on the trade. + + + +*** + +## Getting help + + + + Real-time help from the Polymarket team and community. + + + + Live status, incidents, and maintenance windows. + + + + Copy your builder code and manage your builder account. + + + + Endpoint-level documentation for every API. + +