Skip to main content
Orders in the CTFExchange are represented as signed typed structured data following EIP-712. The Order struct contains all necessary information to execute a trade on-chain.

Order Struct Definition

The complete Order struct is defined in OrderStructs.sol:
OrderStructs.sol
struct Order {
    /// @notice Unique salt to ensure entropy
    uint256 salt;
    /// @notice Maker of the order, i.e the source of funds for the order
    address maker;
    /// @notice Signer of the order
    address signer;
    /// @notice Address of the order taker. The zero address is used to indicate a public order
    address taker;
    /// @notice Token Id of the CTF ERC1155 asset to be bought or sold
    /// If BUY, this is the tokenId of the asset to be bought, i.e the makerAssetId
    /// If SELL, this is the tokenId of the asset to be sold, i.e the takerAssetId
    uint256 tokenId;
    /// @notice Maker amount, i.e the maximum amount of tokens to be sold
    uint256 makerAmount;
    /// @notice Taker amount, i.e the minimum amount of tokens to be received
    uint256 takerAmount;
    /// @notice Timestamp after which the order is expired
    uint256 expiration;
    /// @notice Nonce used for onchain cancellations
    uint256 nonce;
    /// @notice Fee rate, in basis points, charged to the order maker, charged on proceeds
    uint256 feeRateBps;
    /// @notice The side of the order: BUY or SELL
    Side side;
    /// @notice Signature type used by the Order: EOA, POLY_PROXY or POLY_GNOSIS_SAFE
    SignatureType signatureType;
    /// @notice The order signature
    bytes signature;
}

Field Descriptions

Unique Salt

Type: uint256Purpose: Ensures entropy and uniqueness for each order, even if all other parameters are identical.
The salt allows users to create multiple orders with the same parameters while ensuring each order has a unique hash. This is critical for proper order tracking and cancellation.
Example:
order.salt = 12345678901234567890;

Maker Address

Type: addressPurpose: The address that creates the order and is the source of funds.
  • For BUY orders: The maker provides collateral (C)
  • For SELL orders: The maker provides outcome tokens (A or A’)
The maker’s assets are transferred from this address when the order is matched.

Signer Address

Type: addressPurpose: The address that signs the order.
  • For SignatureType.EOA: Must be the same as maker
  • For SignatureType.POLY_PROXY: The EOA that owns the proxy wallet
  • For SignatureType.POLY_GNOSIS_SAFE: The EOA that owns the Gnosis Safe
  • For SignatureType.POLY_1271: Must be the same as maker (smart contract)
The relationship between signer and maker is validated based on the signatureType.

Taker Address

Type: addressPurpose: Specifies who can fill this order.
  • Zero address (0x0): Public order that anyone can fill
  • Specific address: Private order that only the specified address can fill
// Public order
order.taker = address(0);

// Private order for specific user
order.taker = 0x1234567890123456789012345678901234567890;

Token ID

Type: uint256Purpose: Identifies the CTF ERC1155 outcome token being traded.The interpretation depends on the order side:
  • BUY orders: tokenId is the asset to be bought (maker receives this)
  • SELL orders: tokenId is the asset to be sold (maker provides this)
Token IDs are generated by the Conditional Tokens Framework based on condition and partition data.

Maker Amount

Type: uint256Purpose: The maximum amount of tokens the maker is willing to sell/provide.
  • BUY orders: Amount of collateral (C) the maker provides
  • SELL orders: Amount of outcome tokens (A or A’) the maker provides
This represents the maker’s commitment. Orders can be partially filled, so the actual amount transferred may be less.

Taker Amount

Type: uint256Purpose: The minimum amount of tokens the maker expects to receive.
  • BUY orders: Amount of outcome tokens (A or A’) the maker expects
  • SELL orders: Amount of collateral (C) the maker expects
Price Calculation:
// For BUY orders: price = makerAmount / takerAmount
// For SELL orders: price = takerAmount / makerAmount

Expiration Timestamp

Type: uint256Purpose: Unix timestamp after which the order becomes invalid.
// Order expires in 1 hour
order.expiration = block.timestamp + 3600;

// Order expires on specific date (e.g., Jan 1, 2025)
order.expiration = 1735689600;
Orders cannot be filled after the expiration timestamp, even if not explicitly cancelled.

Nonce

Type: uint256Purpose: Used for on-chain order cancellations.The nonce system allows users to:
  • Cancel individual orders by incrementing the nonce
  • Cancel multiple orders simultaneously by using nonce ranges
When a nonce is invalidated on-chain, all orders with that nonce become unfillable.

Fee Rate (Basis Points)

Type: uint256Purpose: Fee rate charged to the order maker, expressed in basis points.
  • 1 BPS = 0.01%
  • 100 BPS = 1%
  • Maximum: 1000 BPS = 10%
// 1% fee
order.feeRateBps = 100;

// 0.5% fee
order.feeRateBps = 50;
Fees are always charged on proceeds (what you receive), not on what you provide. See Fee Structure for detailed calculations.

Side (BUY or SELL)

Type: Side enumPurpose: Indicates whether the maker is buying or selling outcome tokens.
OrderStructs.sol
enum Side {
    // 0: buy
    BUY,
    // 1: sell
    SELL
}
Usage:
// Buying outcome tokens with collateral
order.side = Side.BUY;

// Selling outcome tokens for collateral
order.side = Side.SELL;

Signature Type

Type: SignatureType enumPurpose: Specifies how the order signature should be validated.
OrderStructs.sol
enum SignatureType {
    // 0: ECDSA EIP712 signatures signed by EOAs
    EOA,
    // 1: EIP712 signatures signed by EOAs that own Polymarket Proxy wallets
    POLY_PROXY,
    // 2: EIP712 signatures signed by EOAs that own Polymarket Gnosis safes
    POLY_GNOSIS_SAFE,
    // 3: EIP1271 signatures signed by smart contracts
    POLY_1271
}
See Signature Types for detailed information.

Signature

Type: bytesPurpose: The cryptographic signature proving the order was authorized by the signer.The signature format and validation method depend on the signatureType:
  • EOA: Standard ECDSA signature
  • POLY_PROXY: ECDSA signature + proxy ownership verification
  • POLY_GNOSIS_SAFE: ECDSA signature + safe ownership verification
  • POLY_1271: EIP-1271 contract signature
Invalid signatures will cause the order to be rejected during matching.

EIP-712 Type Hash

The order is hashed using the following EIP-712 type hash:
OrderStructs.sol
bytes32 constant ORDER_TYPEHASH = keccak256(
    "Order(uint256 salt,address maker,address signer,address taker,uint256 tokenId,uint256 makerAmount,uint256 takerAmount,uint256 expiration,uint256 nonce,uint256 feeRateBps,uint8 side,uint8 signatureType)"
);

Supporting Enums

Side

enum Side {
    BUY,   // 0
    SELL   // 1
}

SignatureType

enum SignatureType {
    EOA,                // 0
    POLY_PROXY,         // 1
    POLY_GNOSIS_SAFE,   // 2
    POLY_1271           // 3
}

Order Status Tracking

The exchange tracks order status using the OrderStatus struct:
OrderStructs.sol
struct OrderStatus {
    bool isFilledOrCancelled;
    uint256 remaining;
}
  • isFilledOrCancelled: Whether the order is completely filled or has been cancelled
  • remaining: Remaining maker amount that can still be filled

Matching Scenarios

Learn how orders are matched in different scenarios

Fee Structure

Understand how fees are calculated

Signature Types

Explore different signature validation methods

Build docs developers (and LLMs) love