Simple Flow of PCSX

  1. The Filler pushes their order book to PCSX Order Price API through Websocket
  2. The PCSX Order Price API replies the Swapper with the best order quote
  3. The Swapper approves Permit2 to move their funds.
  4. The Swapper signs the order, including the Permit2 signature and submit to the PCSX Order Handler API
  5. The Filler receives the order from PCSX Kafka, check if the order is correct and profitable, and submit to the Filler contract(Executor)
  6. The Executor calls the Reactor executeWithCallback with the order info.
  7. The Reactor checks the order info and the signature, and transfers the input token from the Swapper to the Executor. (PCSX does not native token as input)
  8. The Reactor then calls the Executor reactorCallback and performs the Executor swap logic.
  9. The Executor should allow the Reactor to transfer the output token from the Executor to the Reactor. (Or transfer the native token to the Reactor at the end of the swap logic)
  10. The Reactor transfer the output tokens from Executor to its own, checks if the output amount is correct or not and transfer the output token to the corresponding recipients.

Exclusivity

Order Time Person eligible to fill
User sign the order → decayStartTime exclusive filler or filler who is willing to pay the exclusivityOverrideBps can fill
decayStartTime → decayEndTime (decay starts) anyone can filler
decayEndTime → deadline (decay stops) anyone can filler

Native Token n Support

PCSX only supports Wrapped native token as input. When user swap from native tokens to any tokens, our frontend will wrap the native token, get quote on the Wrap native token and send the token to the pcsx contracts. Therefore, in order to maximise the gain, we suggest all Market Makers to support both native token and Wrap native token pairs.

Quote Order Price

Get order price

POST <https://sgp1.test.x.pancakeswap.com/order-price/get-price?filler=0x>..

Body:

{
  "tokenInChainId": 56,
  "tokenIn": "0x0e09fabb73bd3ade0a17ecc321fd13a19e81ce82",
  "tokenOutChainId": 56,
  "tokenOut": "0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c",
  "amount": "1000000000000000000" //In wei,
  "type": "EXACT_INPUT",
  "slippageTolerance": "0.01", // Optional
  "configs": [
    {
      "routingType": "DUTCH_LIMIT",
      "swapper": "0x1111111111111111111111111111111111111111", // User
      "exclusivityOverrideBps": 100, // Optional
      "startTimeBufferSecs": 60, // Optional
      "auctionPeriodSecs": 3600, // Optional
      "deadlineBufferSecs": 120 // Optional
    }
  ]
}

Field Descriptions

Field Type Required Description
tokenInChainId number Chain ID of the input token. Supported: 1 (Ethereum), 56 (BSC), 42161 (Arbitrum)
tokenIn string Input token address. Use 0x0000000000000000000000000000000000000000 or "BNB"/"ETH" for native tokens
tokenOutChainId number Chain ID of the output token. Must match tokenInChainId (cross-chain not supported)
tokenOut string Output token address
amount string Trade amount in wei (smallest unit). Must be a string to handle large numbers
type string Trade type: "EXACT_INPUT" or "EXACT_OUTPUT"
slippageTolerance string Slippage tolerance as a percentage (0–100). "1" = 1%. Default: "0.5" (0.5%)
configs array Array of routing configurations (1-2 items). If omitted, defaults are used

Config Object: PCS_CLASSIC (AMM Routing)

Field Type Required Default Description
routingType string - Must be "PCS_CLASSIC"
protocols array ["V2", "V3", "STABLE"] Pool types to use. Options: "V2", "V3", "STABLE"
gasPriceWei string Current gas price Gas price in wei for gas cost estimation
maxHops number 3 Maximum intermediate tokens in route (1-3)
maxSplits number 4 Maximum route splits (1-4)

Config Object: DUTCH_LIMIT (Market Maker Dutch Auction Style PCS-X Routing)

Field Type Required Default Description
routingType string - Must be "DUTCH_LIMIT"
useSyntheticQuotes boolean false If true, generates quotes from AMM prices when no MM orderbook exists
swapper string Zero address User wallet address that will sign and receive tokens
exclusivityOverrideBps number 100 Penalty (basis points) for non-exclusive fillers. 100 = 1%
startTimeBufferSecs number 60 Seconds before auction price decay starts
auctionPeriodSecs number 120 Duration of the Dutch auction in seconds
deadlineBufferSecs number 12 Buffer seconds added after auction ends before order expires

Next response is more pseudo JSON to illustrate format

Response:

{
    "messageType": "PRICE_RESPONSE",
    "message": {
        "bestOrder": DutchOrder,
        "allPossibleOrders": [DutchOrder]
    }
}

Response Field Descriptions

Field Type Description
messageType string Response type: "PRICE_RESPONSE" or "ERROR"
bestOrder object The recommended order with best price
bestOrder.type string Order type: "DUTCH_LIMIT" or "PCS_CLASSIC"
allPossibleOrders array All valid orders found (for comparison)

Order Object Fields

Field Type Description
quoteId string Unique identifier for this quote (use when submitting order)
requestId string Request tracking ID
startTimeBufferSecs number Seconds until auction starts
auctionPeriodSecs number Auction duration in seconds
deadlineBufferSecs number Buffer after auction before expiry
slippageTolerance string Applied slippage tolerance
permitData object EIP-712 typed data for user signature (see below)
orderInfo object Decoded order details
encodedOrder string ABI-encoded order to submit to /order-handler/order
orderHash string A hash of the encoded order

orderInfo Object

Field Type Description
reactor string Dutch Order Reactor contract address
swapper string User address (signer & token recipient)
nonce string Unique nonce for this order (prevents replay)
deadline string Unix timestamp when order expires
additionalValidationContract string Optional validation contract (usually zero address)
additionalValidationData string Optional validation data
decayStartTime string Unix timestamp when price decay starts
decayEndTime string Unix timestamp when price decay ends
exclusiveFiller string Market maker address with exclusive filling rights
exclusivityOverrideBps string Penalty for non-exclusive fillers (basis points)
input object Input token details
outputs array Output token details

input Object

| --- | --- | --- |

outputs Array Item

| --- | --- | --- |


Response that demonstrate order based on MM price calculation

{
    "type": "DUTCH_LIMIT",
    "order": {
        "quoteId": "uniqueQuoteId123",
        "requestId": "7b19d45d-590d-4d8d-b314-8bd22d449cdd",
        "startTimeBufferSecs": 60,
        "auctionPeriodSecs": 3600,
        "deadlineBufferSecs": 120,
        "slippageTolerance": "0.5",
        "permitData": {
            "domain": {
                "name": "Permit2",
                "chainId": 97,
                "verifyingContract": "0x31c2F6fcFf4F8759b3Bd5Bf0e1084A055615c768"
            }
            ...
        },
        "orderInfo": {
            "reactor": "0xCfe2a565072f85381775Eb12644d297bf0F66773",
            "swapper": "0x1111111111111111111111111111111111111111",
            "nonce": "7786519691593674576434758944928673618219620429447126630005716426566992061",
            "deadline": "1712069517",
            "additionalValidationContract": "0x0000000000000000000000000000000000000000",
            "additionalValidationData": "0x00",
            "decayStartTime": "1712065797",
            "decayEndTime": "1712069397",
            "exclusiveFiller": "0x3541a2456E40324Be9c3488755f61e984dECEDf6",
            "exclusivityOverrideBps": "100",
            "input": {
                "token": "0x9f063C8ED6cF9c454993677fd53b2AF572c91d6F",
                "startAmount": "5000000000000000000",
                "endAmount": "10000000000000000000"
            },
            "outputs": [
                {
                    "token": "0x1F3dAD92459B65f98a206D55dbE9F21673C2815A",
                    "startAmount": "5000000000000000000",
                    "endAmount": "5000000000000000000",
                    "recipient": "0xfa4E489A8bB0F7D3a13Ab5352f72981A24c7Cb84"
                }
            ]
        },
        "encodedOrder": "0x0000..."
    }
}

Error Response

| --- | --- |


Submit Price (part of MM integration)

For communication we gonna use WebSockets. When connection to WebSocket add header x-mm-secret=(check with us) for authorization.