Skip to main content

Programmatic Orders

Programmatic orders (sometimes called conditional orders) are programmable orders that execute automatically when predefined conditions are met. They are implemented by the ComposableCoW contract and are a key component of the CoW Protocol’s programmatic order framework, enabling sophisticated trading strategies without manual intervention.

What are Programmatic Orders?

Programmatic orders allow traders to define complex order logic that executes based on specific blockchain conditions such as price thresholds, time intervals, or custom smart contract logic. Unlike traditional orders that are immediately placed, programmatic orders are monitored by the Watch Tower and only posted to the OrderBook when their conditions are satisfied.
Programmatic orders are created through the ComposableCoW contract, which emits events that the Watch Tower monitors.

Order Structure

Each programmatic order contains the following components:
type ConditionalOrder = {
  /**
   * Id of the programmatic order (which also happens to be the key used for `ctx` in the ComposableCoW contract).
   *
   * This is a `keccak256` hash of the serialized programmatic order.
   */
  id: string;

  /**
   * The transaction hash that created the programmatic order (useful for debugging purposes)
   */
  tx: string;

  /**
   * The parameters of the programmatic order
   */
  params: ConditionalOrderParams;

  /**
   * The merkle proof if the programmatic order is belonging to a merkle root
   * otherwise, if the programmatic order is a single order, this is null
   */
  proof: Proof | null;

  /**
   * Map of discrete order hashes to their status
   */
  orders: Map<OrderUid, OrderStatus>;

  /**
   * the address to poll for orders (may, or **may not** be `ComposableCoW`)
   */
  composableCow: string;

  /**
   * The result of the last poll
   */
  pollResult?: {
    lastExecutionTimestamp: number;
    blockNumber: number;
    result: PollResult;
  };
};

Order Parameters

The ConditionalOrderParams contain the core logic:
  • handler: The smart contract address that implements the programmatic order logic
  • salt: A unique identifier to distinguish orders with identical parameters
  • staticInput: Immutable data passed to the handler for order evaluation

Merkle Proofs

Programmatic orders can be created individually or as part of a merkle tree:
type Proof = {
  merkleRoot: BytesLike;
  path: BytesLike[];
};
Merkle trees allow efficient batch creation of multiple programmatic orders in a single transaction, reducing gas costs.

Order Lifecycle

Programmatic orders follow a specific lifecycle from creation to completion:
  1. Creation: An order is created via the ComposableCoW contract, which emits either a ConditionalOrderCreated event (single order) or MerkleRootSet event (batch orders)
  2. Registration: The Watch Tower detects the event and adds the order to its registry, tracking it by owner
  3. Polling: On each block, the Watch Tower polls the programmatic order to check if conditions are met
  4. Execution: When conditions are satisfied, the Watch Tower posts the discrete order to the CoW Protocol OrderBook API
  5. Tracking: The order is tracked with status updates (SUBMITTED or FILLED)
  6. Cleanup: Expired or cancelled orders are removed from the registry

Order Status

Each discrete order generated from a programmatic order has a status:
enum OrderStatus {
  SUBMITTED = 1,
  FILLED = 2,
}

How They Work in ComposableCoW

The ComposableCoW contract provides the framework for creating and managing programmatic orders:
  • Handler registration: Custom order types register handler contracts that implement specific order logic
  • Event emission: The contract emits events when orders are created or modified
  • Order validation: Handlers validate whether order conditions are met when polled
  • Signature generation: Valid orders return order details and signatures for submission
The Watch Tower calls the getTradeableOrderWithSignature function on the ComposableCoW contract to check if an order should be placed.

Order Identification

Each programmatic order has a unique ID generated by hashing its parameters:
const conditionalOrderId = ConditionalOrder.leafToId(params);
This ID is used throughout the system to track the order’s state and poll results.
Last modified on March 12, 2026