cowprotocol/services/docs

Claude Code and agent skill by cowprotocol/services

Trust tier 2
  • community
  • ext:[{"type":"hook","description":"Pre/post lifecycle hooks"}]
Source check pending

Checking that the SKILL.md file is still in the repository.

Install

npx vskill@latest install cowprotocol/services/docs

Semi-extensibleMentions customization, but needs skill-specific knowledge. Read the extensible skills standard

SKILL.md

CoW Protocol Order Debug Skill

Debug why CoW Protocol orders fail to match. Requires DB access + Victoria Logs access (via CoW-Prod MCP).

Quick Checklist

Run through these in order:

  1. [ ] Order status — Check API status first (cancelled/expired/fulfilled/open)
  2. [ ] User cancellation — If cancelled, search logs for "order cancelled" AND all:ORDER_UID FIRST
  3. [ ] Order in auction — Was order in autopilot auction? When?
  4. [ ] Solver bids — Did any solver bid? What happened to their solution?
  5. [ ] Settlement outcome — Did settlement succeed/fail/timeout?
  6. [ ] Limit price sanity — Was quote reasonable? Check slippage, fees, gas
  7. [ ] Price movement — Did price move between quote and expiry?

1. Fetch Order Data

bash
# Replace $NETWORK (mainnet/gnosis/arbitrum) and $ORDER_UID
curl -s "https://api.cow.fi/$NETWORK/api/v1/orders/$ORDER_UID" | jq .
# For staging orders:
curl -s "https://barn.api.cow.fi/$NETWORK/api/v1/orders/$ORDER_UID" | jq .
GPV2Order Struct (Smart Contract Source of Truth)
FieldMeaningDebug Notes
sellTokenToken being sold
buyTokenToken being bought
sellAmountAmount to sell (wei)For sell orders, this is exact
buyAmountMin amount to receiveFor buy orders, this is exact
validToUnix timestamp expiryCheck if expired
appDataHash of metadata JSONContains hooks, partner fees, flash loan hints
feeAmountLegacy, always 0Fee now in limit price
kind"sell" or "buy"
partiallyFillableboolSwaps = false (fill-or-kill), limits can be true
sellTokenBalanceLegacy, always "erc20"Balancer vault balances never took off
buyTokenBalanceLegacy, always "erc20"
signingSchemeeip712/ethsign/presign/eip1271See signing section
signatureThe actual signature bytes
receiverWho gets buy tokensnull = order owner

Additional API fields:

  • class: deprecated, always "limit" — see note below
  • status: fulfilled/open/cancelled/expired
  • surplusFee: Protocol's fee estimate for limit orders
  • surplusFeeTimestamp: Must be <10 min old or order won't enter auction

Note on order class: Order classes no longer exist (there is no class column in the DB anymore and the API always returns limit). The "market" vs "limit" distinction that still matters is about fee policy, not order type:

  • Market order: Had a quote attached, and the order's limit price is within that quote (in-market). Gets market fee policy.
  • Limit order: Either no quote, or limit price is outside the quote (out-of-market). Gets limit fee policy with surplus fee.

The appData.metadata.orderClass field shows what the UI intended, but the actual classification is determined by comparing the order's price to the quote at placement time.


2. Signing Schemes

Orders can fail if signature validation fails. Different schemes have different failure modes:

SchemeTypeValidationCommon Failures
eip712EOAStatic, checked onceSig doesn't match order fields, or signed by unexpected user
ethsignEOA (legacy)Static, checked onceSame as above

Note on unexpected signers: The majority of signature issues are valid signatures but signed by an unexpected user. This causes the settlement contract to attempt transferring tokens from an account that doesn't have the necessary balance.

presignSmart contractOn-chain state (setPreSignature)User called setPreSignature(uid, false) to cancel
eip1271Smart contractCalls isValidSignature() at settlement timeContract state changed, Safe signer removed, custom logic rejects

EIP-1271 is dynamic — signature can be valid at order placement but invalid later. Autopilot re-checks these every auction.

bash
# Check if presign is set (returns signed boolean)
cast call $SETTLEMENT_CONTRACT "preSignature(bytes)" $ORDER_UID --rpc-url $RPC

3. Check Logs (Victoria Logs via MCP)

Logs are stored in Victoria Logs and accessible via the CoW-Prod MCP tools. Use mcp__CoW-Prod__victorialogs_query for log searches. Timestamps must be RFC3339 format (compute from current date).

IMPORTANT — Protect context window: Always append | fields _time, _msg, all to queries to strip kubernetes/ec2 metadata (~4KB per entry). Use small limit values (10-20). When you only need specific fields, use | fields _time, _msg, parsed.fields.err, parsed.fields.driver etc.

Example queries (use `victorialogs_query` tool):

# All order logs (exclude nginx controller, filter by network, strip metadata)
query: "container:!controller AND network:$NETWORK AND all:ORDER_UID | fields _time, _msg, all"
start: "<24h-ago-RFC3339>"
limit: 20
# Search by quote ID
query: "container:!controller AND network:$NETWORK AND all:22788649 | fields _time, _msg, all"
# Search specific solver
query: "container:!controller AND network:$NETWORK AND baseline AND all:22788649 | fields _time, _msg, all"

Useful filters (part of the LogsQL expression):

  • container:!controller — excludes nginx access logs (REQUIRED for order UID searches)
  • network:$NETWORK — always include when debugging an order to filter by chain (mainnet, bnb, arbitrum-one, base, etc). Reduces noise and speeds up queries.
  • all: — prefix for searching structured fields (order UIDs, auction IDs, quote IDs). Without a field prefix, Victoria Logs only searches the log message text, not structured fields. You can also use parsed.fields.order_uid:0x... for precise matching, but all: works universally.
  • | fields _time, _msg, all — always append to strip k8s metadata and protect context window

Note: Always use the full order UID with 0x prefix and the all: field prefix for reliable matching.

IMPORTANT - Run targeted lifecycle queries in parallel (use FULL order UID with 0x). Call multiple victorialogs_query MCP tools simultaneously. Always include network:$NETWORK and | fields pipe:

# Order creation
query: "container:!controller AND network:$NETWORK AND \"order created\" AND all:ORDER_UID | fields _time, _msg, all"
# Order cancellation
query: "container:!controller AND network:$NETWORK AND \"order cancelled\" AND all:ORDER_UID | fields _time, _msg, all"
# Proposed solutions
query: "container:!controller AND network:$NETWORK AND \"proposed solution\" AND all:ORDER_UID | fields _time, _msg, all"
# Settlement failures (use specific parsed fields for concise output)
query: "container:!controller AND network:$NETWORK AND \"settlement failed\" AND all:ORDER_UID | fields _time, _msg, parsed.fields.err, parsed.fields.driver, parsed.spans.auction.auction_id"
# Filtering
query: "container:!controller AND network:$NETWORK AND filtered AND all:ORDER_UID | fields _time, _msg, all"
# Find discarded solutions (use order UID bytes without 0x prefix)
query: "container:!controller AND network:$NETWORK AND discarded AND all:ORDER_UID_WITHOUT_0X | fields _time, _msg, all"

What to look for:

  • order created — order placement with quote_id
  • New orders in auction — order entered auction
  • computed solutions — solver found a route
  • solved auction — solver submitted winning bid
  • filtered out in-flight — order being settled
  • order cancelled — user cancelled via API

Get auction competition data:

bash
curl -s "https://api.cow.fi/$NETWORK/api/v1/solver_competition/$AUCTION_ID" | jq .

4. Common Log Patterns

IMPORTANT: Many log messages use spaces not underscores (e.g., order cancelled not order_cancelled).

Order lifecycle (search by order UID):

orderbook::api::post_order: order created # Order placed
autopilot::run_loop::observe: New orders in auction # Added to auction
driver::infra::observe: computed solutions # Solver found route
driver::infra::observe: solved auction # Solver won
autopilot::run_loop: filtered out in-flight # Being settled
autopilot::run_loop: settlement failed # Settlement failed (check err=)
orderbook::orderbook: order cancelled # User cancelled via API

Issues to watch for:

  • order cancelled — user cancelled the order (check timestamp vs settlement!)
  • settlement failed err=Timeout — driver timed out during settlement
  • settlement failed — settlement failed (other reasons)
  • filtered — order excluded from auction (check reason)
  • error or Error — something went wrong
  • revert — simulation or settlement failed
  • insufficient_balance / insufficient_allowance — user moved funds

5. Quote History

Method 1: API response (easiest)

The order API response includes the quote that was used:

bash
curl -s "https://api.cow.fi/$NETWORK/api/v1/orders/$ORDER_UID" | jq '.quote'

Returns:

json
{
"sellAmount": "4300531427036176000",
"buyAmount": "16788289774218687968",
"feeAmount": "3270684063997860",
"solver": "0x3980daa7eaad0b7e0c53cfc5c2760037270da54d",
"verified": true,
...
}
Method 2: Database
sql
SELECT q.id, q.sell_amount, q.buy_amount, q.gas_amount, q.solver, q.created
FROM quotes q
JOIN order_quotes oq ON oq.quote_id = q.id
WHERE oq.order_uid = '\x$ORDER_UID_HEX';
Method 3: Logs (fallback)

Find the quote_id from the "order created" log using victorialogs_query:

query: "container:!controller AND network:$NETWORK AND \"order created\" AND all:ORDER_UID | fields _time, _msg, all"

Example log line:

orderbook::api::post_order: order created order_uid=0x... quote_id=Some(2720468) quote_solver=Some(0x3980...)

Then search for quote details by ID:

query: "container:!controller AND network:$NETWORK AND all:$QUOTE_ID | fields _time, _msg, all"

6. Quoting Deep Dive

Quotes determine the limit price users sign. Bad quotes = orders that can't fill.

Quote Process
UI requests quote → Orderbook sends "fake auction" (single order, infinite slippage) to all solvers
↓
Solvers return: exchange rate + calldata (recipe)
↓
In parallel, orderbook also fetches:
- Gas price estimate
- Native price of sell token (to convert gas cost)
- Native price of buy token (needed for surplus scoring later)
↓
Simulate winning solver's calldata → get gas units
↓
network_fee = gas_units × gas_price / sell_token_native_price
↓
Return quote with exchange rate + network fee
Quote Types
TypeBehaviorUse Case
FastReturns after first 3 solver responses, always unverifiedUI responsiveness
OptimalWaits for all solvers (5s timeout), attempts verificationActual order placement
NativeCached quote for "buy 0.1 ETH with token X"Native price lookups

Verified vs Unverified:

  • Verified = simulation succeeded, high confidence quote is achievable
  • Unverified = simulation failed or skipped, solver might have bad math
Limit Price Calculation
min_buy_amount = (sell_amount - network_fee) × exchange_rate × (1 - slippage) × (1 - partner_fee)

Smart slippage: Smaller orders get higher slippage bc network fee dominates. A 10% gas price spike on a $10 order (where fee is ~$2) eats way more than on a $1M order.


7. Order Placement Validation

Orderbook rejects orders that have no chance of executing. Checks:

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
288
Repository forks
153
7-day trend score
28

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 18 Mar 2026, 7 months ago.

Extension points

  • hookPre/post lifecycle hooks

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/cowprotocol/services/docs/badge)](https://verified-skill.com/skills/cowprotocol/services/docs)

Something wrong with this skill or its page? Tell us.