> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cow.bleu.builders/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom Orders

> Build custom programmatic order types using the IConditionalOrder and IConditionalOrderGenerator interfaces.

# Custom Orders

Custom orders leverage the `IConditionalOrder` or `IConditionalOrderGenerator` interface to enable sophisticated trading strategies based on on-chain conditions. The framework recommends extending `BaseConditionalOrder` for most implementations, as it handles signature verification automatically.

## Key Interfaces

* **IConditionalOrder** provides the foundational verification method
* **IConditionalOrderGenerator** extends this by adding order generation capabilities on-chain

The `verify` function checks discrete order validity, while `getTradeableOrder` produces executable orders for the CoW Protocol API.

## BaseConditionalOrder Advantages

This abstract contract streamlines development by automating:

* Order hash verification
* ERC165 interface support

Developers focus solely on implementing the order generation logic through the `getTradeableOrder` function, which must return a valid `GPv2Order.Data` struct.

## Implementation Examples

### TradeAboveThreshold

Executes when an owner's token balance exceeds a specified threshold, selling the entire balance.

### PerpetualStableSwap

Automatically rebalances between two tokens based on relative holdings, applying a configurable spread.

## Error Communication

Specialized revert errors guide watchtowers on retry behavior:

| Error                               | Behavior                              |
| ----------------------------------- | ------------------------------------- |
| `PollTryNextBlock`                  | Temporary condition, retry soon       |
| `PollTryAtBlock` / `PollTryAtEpoch` | Order valid at specific time          |
| `PollNever`                         | Permanent invalidity, stop monitoring |
| `OrderNotValid`                     | Generic failure condition             |

## Advanced Features

* **Context-based cabinet storage** for persistent values
* **`offchainInput` parameters** for dynamic watchtower-provided data
* **Validity bucketing** prevents hash collisions across sequential queries

## Best Practices

* Maintain gas efficiency in `getTradeableOrder`
* Ensure deterministic logic within validity buckets
* Employ clear error messaging
* Implement proper ERC165 interface support

<Warning>
  **All revert paths must use recognized custom errors.**

  If `getTradeableOrder` (or `getTradeableOrderWithSignature`) reverts with bytes that the Watch Tower cannot decode to a known error (`OrderNotValid`, `PollTryNextBlock`, `PollTryAtBlock`, `PollTryAtEpoch`), the Watch Tower permanently stops polling your order with no notification to the order creator.

  This means arithmetic overflows, failed external calls, and bare `revert()` statements will silently kill your order's polling. Wrap your handler logic in a try/catch and always revert with `OrderNotValid(reason)` as a fallback for any unexpected failure. See [Troubleshooting — Order stopped being polled](/composable-cow/guides/troubleshooting#order-stopped-being-polled-unexpectedly) for debugging steps.
</Warning>

### Security Considerations

* Validate external calls
* Manage arithmetic carefully — unhandled overflows will cause the Watch Tower to permanently drop your order
* Address reentrancy risks

## Watch Tower Integration

Custom handlers are automatically discovered and executed by the [Watch Tower](/watch-tower/introduction). When a programmatic order is created via `ComposableCoW`, the Watch Tower:

1. Detects the `ConditionalOrderCreated` event on-chain
2. [Polls](/watch-tower/concepts/polling) your handler's `getTradeableOrder()` on every block (or per your error hints)
3. Submits the resulting discrete order to the CoW Protocol OrderBook when conditions are met

You do **not** need to register your handler in the SDK registry — the Watch Tower falls back to direct contract calls for any handler not in the built-in registry. Your handler just needs to be deployed and have an order created via `ComposableCoW.create()` or `ComposableCoW.createWithContext()`.

<Note>
  Test your handler on **Sepolia** first. The Watch Tower supports Sepolia and will poll your handler the same way it does on mainnet. See [Watch Tower Configuration](/watch-tower/getting-started/configuration) for Sepolia setup.
</Note>
