Skip to content

CIP: Penalty Cap Redesign - #655

Open
fhenneke wants to merge 2 commits into
mainfrom
docs/penalty-cap-redesign
Open

CIP: Penalty Cap Redesign#655
fhenneke wants to merge 2 commits into
mainfrom
docs/penalty-cap-redesign

Conversation

@fhenneke

@fhenneke fhenneke commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Documentation change reflecting the penalty cap redesign CIP draft: the chain-specific absolute penalty cap is replaced by a per-order penalty cap.

This PR would be merged, after filling in the CIP-XX placeholders, if the CIP were to pass.

Summary by CodeRabbit

  • Documentation
    • Updated solver rewards documentation to include CIP-XX guidance.
    • Clarified performance reward caps, including chain-specific upper limits and lower limits based on unsettled orders.
    • Documented per-order penalty caps using quote value, a global 20 USD limit, fill fraction, and chain/token-pair basis points.
    • Expanded solver strategy guidance to explain how penalties are bounded.

@fhenneke
fhenneke requested a review from a team as a code owner August 10, 2026 11:21
@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Error Error Aug 10, 2026 11:21am

Request Review

@fhenneke
fhenneke requested a review from Architsharma7 August 10, 2026 11:21
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The solver rewards documentation references CIP-XX, updates chain-specific performance caps, defines lower caps from unsettled orders, and clarifies penalty guidance for late or absent settlement.

Changes

Solver rewards

Layer / File(s) Summary
Reward caps and solver guidance
docs/cow-protocol/reference/core/auctions/rewards.md
The introduction references CIP-XX. Upper caps use chain-specific β values. Lower caps use unsettled winning orders with quote-based, USD-equivalent, chain-specific, and token-pair-specific limits. Solver guidance refers to the relevant orders’ penalty caps.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • cowprotocol/docs#603: Updates the same solver-rewards documentation and related CIP-XX terminology.

Suggested reviewers: pretf00d, fleupold, harisang

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: redesigning the penalty cap.
Description check ✅ Passed The description explains the documentation change, its rationale, and the conditional CIP-XX follow-up.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/penalty-cap-redesign

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/cow-protocol/reference/core/auctions/rewards.md`:
- Line 155: Update the solver guidance paragraph to replace “revert risk” with
“settlement-failure risk,” ensuring the reported-score adjustment explicitly
covers both late and absent settlement cases represented by the penalty caps.
- Line 44: Update the user-facing definition near the upper cap c_u to replace
“onchain” with “on-chain,” leaving the rest of the sentence unchanged.
- Around line 51-55: Update the definition of c_l in the rewards documentation
to explicitly define unsettled_i as the winning auction-order pairs from solver
i’s solutions that were not fully settled. Specify that each pair contributes
its penalty cap for the unexecuted portion, including the appropriate
partial-fill accounting, rather than treating only entirely unsettled orders as
contributors.
- Around line 59-65: Update the penalty-cap definition near
\textrm{penaltyCap}_o to remove the claim that \bar{c} equals the native-token
equivalent of 20 USD. Describe \bar{c} using the chain-specific lower-cap values
and terminology established by the actual CIP or implementation contract,
without introducing a price source or rounding rule.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d27cfbc0-0ab7-476c-a86a-9bed96b891f0

📥 Commits

Reviewing files that changed from the base of the PR and between b5c361d and 244e6cb.

📒 Files selected for processing (1)
  • docs/cow-protocol/reference/core/auctions/rewards.md

- BNB: $$\beta = 100\%$$, $$0.04 \;\textrm{BNB}$$
- Linea and Ink: $$\beta = 100\%$$, $$0.0015 \;\textrm{ETH}$$
- Plasma: $$\beta = 100\%$$, $$30 \;\textrm{XPL}$$
The upper cap $$c_u$$ is equal to a chain-specific fraction $$\beta$$ of the protocol fee (excluding partner fees) that the protocol earned from the trades in all solutions successfully executed onchain by the solver in that auction. $$\beta$$ is determined by the following values:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use on-chain in this sentence.

Replace onchain with on-chain in this user-facing definition.

Proposed wording fix
- executed onchain by the solver
+ executed on-chain by the solver
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
The upper cap $$c_u$$ is equal to a chain-specific fraction $$\beta$$ of the protocol fee (excluding partner fees) that the protocol earned from the trades in all solutions successfully executed onchain by the solver in that auction. $$\beta$$ is determined by the following values:
The upper cap $$c_u$$ is equal to a chain-specific fraction $$\beta$$ of the protocol fee (excluding partner fees) that the protocol earned from the trades in all solutions successfully executed on-chain by the solver in that auction. $$\beta$$ is determined by the following values:
🧰 Tools
🪛 LanguageTool

[grammar] ~44-~44: Ensure spelling is correct
Context: ... in all solutions successfully executed onchain by the solver in that auction. $$\beta$...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cow-protocol/reference/core/auctions/rewards.md` at line 44, Update the
user-facing definition near the upper cap c_u to replace “onchain” with
“on-chain,” leaving the rest of the sentence unchanged.

Source: Linters/SAST tools

Comment on lines +51 to +55
The lower cap $$c_l$$ is determined by the orders that solver $$i$$ won but did not settle. Every order has a penalty cap associated with it in each auction, expressed in the native token of the chain, and $$c_l$$ is the sum of the penalty caps of all orders in solver $$i$$'s winning solutions that were not executed in time, or not executed at all,

$$
c_l = \sum_{o \,\in\, \textrm{unsettled}_i} \textrm{penaltyCap}_o.
$$

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 6 'unsettled_i|penaltyCap|penalty cap|auction-order|partially fillable' .

Repository: cowprotocol/docs

Length of output: 31888


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== File outline and relevant sections ==="
wc -l docs/cow-protocol/reference/core/auctions/rewards.md
sed -n '1,135p' docs/cow-protocol/reference/core/auctions/rewards.md

echo "\n=== Deterministic parsing of summation / terminology ==="
python3 - <<'PY'
from pathlib import Path
import re

p = Path("docs/cow-protocol/reference/core/auctions/rewards.md")
s = p.read_text()
terms = [
    "unsettled_i",
    "penaltyCap_o",
    "partially fillable",
    "winning solutions that were not executed in time, or not executed at all",
]
for term in terms:
    print(f"{term!r}: {s.count(term)}")

# Extract sentence(s) around c_l and the penalty cap scaling.
for phrase in [
    "The lower cap",
    "For partially fillable orders",
    "Both counts are at the level of auction-order pairs",
    "the sum runs over all order executions",
]:
    idx = s.find(phrase)
    if idx >= 0:
        start = max(0, s.rfind("\n\n", 0, idx-200))
        end = min(len(s), s.find("\n\n", idx+2000))
        print(f"\n--- Context for {phrase!r} ---")
        print(s[start:end])

# Behavioral probe: enumerate possible definitions from the text as text conditions.
# This does not alter any file, only documents which conditions are present/absent.
patterns = {
    "lower cap mentions unsettled_i": r"\$c_l\).*?\\textrm\{unsettled_\i\}",
    "lower cap mentions auction-order pairs": re.escape("auction-order pairs"),
    "penalty cap scaling mentions execution fraction": re.escape("scaled to the fraction of the order that the winning solution proposed to execute"),
    "success rate explicitly uses auction-order pairs": re.escape("Both counts are at the level of auction-order pairs"),
}
for name, pat in patterns.items():
    if isinstance(pat, str):
        print(f"{name}: {len(re.findall(pat, s))}")
    else:
        print(f"{name}: {len(re.findall(pat, s, re.S))}")
PY

Repository: cowprotocol/docs

Length of output: 25908


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== Remaining file sections ==="
sed -n '136,189p' docs/cow-protocol/reference/core/auctions/rewards.md

echo "\n=== References to settlement deadlines, expiry, and fills ==="
rg -n -C 4 'deadline|deadline by which|expires|expired|settle|settlement|fill|filled|execution amount|executed sell|partially' docs/cow-protocol/reference/core docs/cow-protocol/tutorials docs/cow-protocol/concepts 2>/dev/null | sed -n '1,220p'

Repository: cowprotocol/docs

Length of output: 36791


Define unsettled_i and partial-fill accounting for c_l.

unsettled_i is not defined from the referenced sentence. State that $c_l$ is a sum over winning auction-order pairs in solver $i$'s solutions and specify the per-pair penalty when winning only a partial fill.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cow-protocol/reference/core/auctions/rewards.md` around lines 51 - 55,
Update the definition of c_l in the rewards documentation to explicitly define
unsettled_i as the winning auction-order pairs from solver i’s solutions that
were not fully settled. Specify that each pair contributes its penalty cap for
the unexecuted portion, including the appropriate partial-fill accounting,
rather than treating only entirely unsettled orders as contributors.

Comment on lines +59 to +65
The penalty cap of an order is a fraction of the order's quote, bounded by a global absolute cap:

$$
\textrm{penaltyCap}_o = \min(\phi_o \cdot \textrm{quote}_o, \bar{c}).
$$

Here $$\textrm{quote}_o$$ is the value of the quote of order $$o$$, expressed in the native token of the chain. The quote of an order is the buy amount with all volume fees deducted for sell orders, and the sell amount with all volume fees added for buy orders. The global bound $$\bar{c}$$ is the native token equivalent of 20 USD. For partially fillable orders, the penalty cap is scaled to the fraction of the order that the winning solution proposed to execute.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 6 'penaltyCap|penalty cap|20 USD|native token equivalent|Dune|round' .

Repository: cowprotocol/docs

Length of output: 50374


🌐 Web query:

CoW Protocol CIP-XX penalty caps 20 USD c_l solver rewards

💡 Result:

In CoW Protocol, the "20 USD" figure often cited in technical discussions is an example used to illustrate the economic impact of penalty caps on solver bidding strategies, rather than a formal, hard-coded protocol parameter [1][2]. The protocol uses a penalty mechanism to discourage overbidding and maintain competition [2]. When a winning solution fails to execute on-chain (e.g., due to a revert), the solver incurs a penalty [1][3]. This penalty is subject to a lower cap, denoted as c_l, which is defined on a per-chain basis in the protocol's native token (e.g., 0.01 ETH on Ethereum mainnet) [1][4][5]. The relevance of the 20 USD figure is as follows: 1. Economic Modeling: Technical documentation and community discussions use $20 as a hypothetical example of a penalty cap to demonstrate how solvers should adjust their bids [1][2]. For instance, a solver calculating the optimal bid under revert risk must factor in this penalty cap to balance profitability and competitive ranking [1][2]. 2. Incentive Alignment: Because the penalty cap limits a solver's maximum loss per auction, it creates a "first-price auction" dynamic for larger orders [2]. Solvers must discount their submitted surplus based on their success probability and the magnitude of the penalty cap to avoid incurring losses that exceed the reward potential [1][2]. While the penalty cap is a critical parameter, it is currently configured as a chain-specific value in the native network token (e.g., 0.01 ETH, 30 POL, 10 xDAI) to align with local gas economics, not as a flat 20 USD value across all chains [1][4]. The protocol also continues to explore refinements to these caps, such as proposals to shift from fixed absolute caps to relative caps based on trade volume, to improve solver efficiency [6].

Citations:


🌐 Web query:

"penalty cap of an order" "20 USD" CoW Protocol solver rewards

💡 Result:

In CoW Protocol, the reward for solvers is calculated using a capped second-price auction mechanism, where the reward is capped both from above and below [1][2]. As of August 2026, the specific value of 20 USD does not represent a standard protocol-wide penalty cap; rather, penalty caps (lower bounds) are defined in native chain tokens (e.g., ETH, DAI, POL) and vary by network [1]. The CoW Protocol reward formula is defined as cap(x) = max(-c_l, min(c_u, x)) [1][2]. In this formula: 1. Upper Cap (c_u): Following the implementation of CIP-74 in December 2025, the fixed upper reward cap was replaced with a dynamic cap tied to the protocol fees earned from the trades in the solver's solution [1][3][4]. 2. Penalty Cap (c_l / Lower Bound): This value limits the maximum penalty a solver can incur for a reverted or unsuccessful auction [1]. These caps are chain-specific and are not set to a uniform 20 USD value [1]. For example, documentation has historically referenced values such as 0.01 ETH on Ethereum mainnet [1][5]. The figure of 20 USD likely originates from a conceptual example used in technical discussions regarding optimal bidding strategies under revert risk, where a hypothetical solver with a 90% success rate and 100 surplus might consider a penalty cap of 20 units (e.g., USD or other currency) when calculating their bid discount [1]. It is not a hard-coded protocol parameter [1].

Citations:


🌐 Web query:

docs.cow.fi "The global bound c̄ is the native token equivalent of 20 USD"

💡 Result:

Based on an exhaustive review of the official CoW Protocol documentation, there is no technical parameter, rule, or concept referred to as a "global bound" defined as being equivalent to 20 USD [1][2][3][4][5]. In the CoW Swap documentation regarding slippage configuration, the protocol defines "bounds" as numerical ranges (min and max) used to clamp slippage percentage values (expressed in basis points, where 1% = 100 bps) [1][6]. Additionally, the documentation mentions an "ETH-Flow floor" mechanism where slippage may be forced to 2% (on Ethereum Mainnet) or 0.5% (on other networks) if the default slippage is set below certain thresholds, but these are percentage-based constraints, not a 20 USD equivalent "global bound" [1][6]. It is possible that "20 USD" refers to a specific off-chain fee threshold, gas estimation heuristic, or a misinterpretation of one of the protocol's many technical parameters, but no such "global bound" exists in the public CoW Protocol documentation [1][2][3][4][5].

Citations:


🌐 Web query:

"native token equivalent of 20 USD" "penalty cap" CoW Protocol

💡 Result:

CoW Protocol does not use a globally fixed 20 USD penalty cap; instead, it utilizes chain-specific absolute caps defined in the protocol's native currency (e.g., ETH on Ethereum mainnet) [1][2]. While technical discussions in the CoW DAO forum have used a 20 USD figure as a hypothetical example to explain solver bidding behavior—illustrating how solvers should adjust their bids to account for potential penalties—this value is not an official protocol parameter [3][2]. The protocol's penalty mechanism is designed to incentivize solvers to execute settlements successfully [1]. When a winning solution fails to execute (e.g., due to a revert), the solver incurs a penalty [2][4]. This penalty is capped at a chain-specific limit to ensure the economic viability of solvers [3][2]. Because these caps are denominated in the chain's native token, their equivalent value in USD fluctuates based on the market price of that token [1][4]. As of late 2026, the protocol has been exploring a redesign of this penalty structure to move from fixed absolute caps to relative caps based on trade volume, aiming to better align incentives across different order sizes [1][5]. Solvers typically manage the risk of these penalties by incorporating the expected cost of potential reverts—weighted by the probability of success—into their submitted scores [3][2].

Citations:


Do not define \bar{c} as the native token equivalent of 20 USD.

Public CoW Protocol documentation and existing docs present the lower penalty cap value as chain-specific native-token amounts, not a uniform 20 USD conversion. Specifying a deterministic price source and rounding rule here makes this value appear implementable when the documented rule may be incorrect; align this sentence with the actual CIP/implementation contract instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cow-protocol/reference/core/auctions/rewards.md` around lines 59 - 65,
Update the penalty-cap definition near \textrm{penaltyCap}_o to remove the claim
that \bar{c} equals the native-token equivalent of 20 USD. Describe \bar{c}
using the chain-specific lower-cap values and terminology established by the
actual CIP or implementation contract, without introducing a price source or
rounding rule.

To determine the optimal routing, the recommended strategy for a solver is to start by dividing the available orders into groups of orders on the same directed token pairs - i.e., in each group, all orders have the same sell and buy tokens. The next step is to compute the best possible routing for each group and submit it as a solution. Note that, by construction, each of these solutions will use outside liquidity. Finally, a solver should check whether it is possible to improve these solutions by creating batched solutions containing orders on different directed token pairs. These additional efficiencies may come from, for example, exploiting liquidity already available on the protocol - using one order as liquidity for the other (in a CoW) or using [surplus-capturing JIT liquidity](/cow-protocol/reference/core/auctions/the-problem#surplus-capturing-jit-orders) - or from gas savings. Solvers should submit an additional solution for every combination of groups of orders for which additional efficiencies are possible. When submitting such a solution, they should pay attention to sharing the additional efficiencies among all orders in the batch; otherwise, the batched solution may be filtered out as unfair.

As already discussed, solvers are responsible for paying the gas cost of a solution. Also, if a solution reverts, a solver may incur a penalty. Hence, when reporting their solution, solvers should adjust their reported score to account for the expected costs of settling a solution on the chain and the revert risk.
As already discussed, solvers are responsible for paying the gas cost of a solution. Also, if a solution is not settled in time, a solver may incur a penalty, bounded by the sum of the penalty caps of the orders it does not settle. Hence, when reporting their solution, solvers should adjust their reported score to account for the expected costs of settling a solution on the chain and the revert risk.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Include late and absent settlement risk in the solver guidance.

The paragraph covers solutions that are not settled in time, but the final clause refers only to “revert risk”. Replace that phrase with “settlement-failure risk” or explicitly define “revert risk” to include every case covered by the penalty caps.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cow-protocol/reference/core/auctions/rewards.md` at line 155, Update the
solver guidance paragraph to replace “revert risk” with “settlement-failure
risk,” ensuring the reported-score adjustment explicitly covers both late and
absent settlement cases represented by the penalty caps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant