Skip to content

Conversation

@limitofzero
Copy link

@limitofzero limitofzero commented Nov 13, 2025

Summary by CodeRabbit

Release Notes

  • New Features
    • Added protocol fee support to quote calculations and order signing.
    • Quote responses now include protocol fee details (amount and basis points).
    • Slippage calculations updated to account for protocol fees.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

Walkthrough

This pull request introduces protocol fee support throughout the quote calculation pipeline. A new protocolFeeBps parameter is added to fee computations with a dedicated helper calculating protocol fees and applying them before slippage calculations. The parameter propagates through multiple modules with resulting amounts and costs exposed in return types and utilities.

Changes

Cohort / File(s) Summary
Package configuration
packages/order-book/package.json
Updated swagger:codegen script to reference a specific commit hash instead of version tag for OpenAPI input URL
Type definitions
packages/order-book/src/types.ts
Added protocolFee field to Costs<T> with amount and basis points; added afterProtocolFees: Amounts<T> to QuoteAmountsAndCosts<T>
Core fee calculation
packages/order-book/src/quoteAmountsAndCostsUtils.ts
Introduced protocolFeeBps parameter to QuoteAmountsAndCostsParams; added internal getQuoteAmountsWithProtocolFee helper; extended slippage calculation to operate on post-protocol-fee amounts; updated return structure to include protocolFee and afterProtocolFees
Fee propagation in trading
packages/trading/src/getOrderToSign.ts
Added protocolFeeBps?: number to OrderToSignParams; propagated parameter to getQuoteAmountsAndCosts call
Fee propagation in trading (quote)
packages/trading/src/getQuote.ts
Forwarded quote.protocolFeeBps to both getQuoteAmountsAndCosts and orderToSign input object
Fee propagation in trading (slippage)
packages/trading/src/resolveSlippageSuggestion.ts
Added quote.protocolFeeBps to getQuoteAmountsAndCosts arguments
Utility serialization
packages/trading/src/utils/misc.ts
Extended cost destructuring and restructuring to handle protocolFee serialization; added afterProtocolFees mapping in top-level return

Sequence Diagram

sequenceDiagram
    participant Quote as Quote Calc
    participant GetOrder as getOrderToSign
    participant GetQuote as getQuote
    participant GetQAC as getQuoteAmountsAndCosts
    participant ProtocolFee as getQuoteAmountsWithProtocolFee
    
    rect rgb(200, 220, 255)
    Note over Quote: Old Flow
    Quote->>GetQAC: afterPartnerFees → slippage
    end
    
    rect rgb(220, 255, 220)
    Note over Quote: New Flow
    Quote->>GetOrder: protocolFeeBps
    GetOrder->>GetQuote: protocolFeeBps
    GetQuote->>GetQAC: protocolFeeBps
    GetQAC->>ProtocolFee: networkCosts + protocolFeeBps
    ProtocolFee->>ProtocolFee: Calculate protocolFeeAmount
    ProtocolFee->>GetQAC: afterProtocolFees
    GetQAC->>GetQAC: afterProtocolFees → slippage
    GetQAC->>GetOrder: costs.protocolFee
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Logic verification: Review getQuoteAmountsWithProtocolFee helper for correct fee calculation in both sell and buy directions, handling of edge cases (non-positive fees), and order of operations
  • Parameter propagation: Verify that protocolFeeBps flows correctly through all call chains and defaults to undefined or 0 appropriately
  • Type safety: Confirm new fields in Costs<T> and QuoteAmountsAndCosts<T> are properly typed and used consistently
  • OpenAPI commit reference: Validate that the swagger:codegen URL change points to the intended commit with expected schema changes

Possibly related PRs

Suggested reviewers

  • alfetopito
  • shoom3301
  • cowdan

Poem

🐰 Protocol fees now flow so clean,
Through every fee step in between,
From network costs to slippage's call,
We measure them, we track them all! ✨
Basis points dancing, amounts aligned,
Fee calculations refined and designed!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add protocol fee calculation for orders' clearly and concisely describes the main change: introducing protocol fee calculation functionality for orders.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/implement-protocol-fee

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 and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 13, 2025

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@limitofzero
Copy link
Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 13, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 13, 2025

📦 GitHub Packages Published

Last updated: Nov 14, 2025, 03:25:20 PM UTC

The following packages have been published to GitHub Packages with pre-release version pr-675-62c2bc63:


Installation

These packages require authentication to install from GitHub Packages. First, create a .npmrc file:

# Create .npmrc file in your project root
echo "@cowprotocol:registry=https://npm.pkg.github.com" > .npmrc
echo "//npm.pkg.github.com/:_authToken=YOUR_GITHUB_TOKEN" >> .npmrc

To get your GitHub token:

  1. Go to https://github.com/settings/tokens
  2. Click "Generate new token (classic)"
  3. Check only the "read:packages" scope
  4. Copy the token and replace YOUR_GITHUB_TOKEN in the .npmrc file

Then install any of the packages above, either by exact version (i.e. @cowprotocol/[email protected]) or more conveniently by using the tag (@cowprotocol/cow-sdk@pr-675):

# Yarn
yarn add npm:@cowprotocol/cow-sdk@pr-675

# pnpm
pnpm install npm:@cowprotocol/cow-sdk@pr-675

# NPM
npm install npm:@cowprotocol/cow-sdk@pr-675

Update to the latest version (only if you used the tag)

Every commit will publish a new package. To upgrade to the latest version, run:

# Yarn
yarn upgrade @cowprotocol/cow-sdk

# pnpm
pnpm update @cowprotocol/cow-sdk

# NPM
npm update @cowprotocol/cow-sdk

View Packages

You can view the published packages at: https://github.com/cowprotocol/cow-sdk/packages

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b04b9e and eef0f71.

📒 Files selected for processing (7)
  • packages/order-book/package.json (1 hunks)
  • packages/order-book/src/quoteAmountsAndCostsUtils.ts (6 hunks)
  • packages/order-book/src/types.ts (3 hunks)
  • packages/trading/src/getOrderToSign.ts (2 hunks)
  • packages/trading/src/getQuote.ts (1 hunks)
  • packages/trading/src/resolveSlippageSuggestion.ts (1 hunks)
  • packages/trading/src/utils/misc.ts (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: sebastiantf
Repo: cowprotocol/cow-sdk PR: 317
File: src/bridging/providers/bungee/util.ts:0-0
Timestamp: 2025-05-30T13:00:36.623Z
Learning: The `calculateFeeBps` function in the Bungee bridge provider includes proper validation checks (division by zero, fee amount > input amount) and uses BigInt arithmetic with rounding for precision before converting to Number. This approach is safe because fee amounts are always less than input amounts, ensuring the resulting bps value stays under 10,000.
📚 Learning: 2025-05-30T13:00:36.623Z
Learnt from: sebastiantf
Repo: cowprotocol/cow-sdk PR: 317
File: src/bridging/providers/bungee/util.ts:0-0
Timestamp: 2025-05-30T13:00:36.623Z
Learning: The `calculateFeeBps` function in the Bungee bridge provider includes proper validation checks (division by zero, fee amount > input amount) and uses BigInt arithmetic with rounding for precision before converting to Number. This approach is safe because fee amounts are always less than input amounts, ensuring the resulting bps value stays under 10,000.

Applied to files:

  • packages/order-book/src/types.ts
  • packages/trading/src/getQuote.ts
  • packages/trading/src/getOrderToSign.ts
  • packages/trading/src/resolveSlippageSuggestion.ts
  • packages/order-book/src/quoteAmountsAndCostsUtils.ts
📚 Learning: 2025-05-13T12:22:48.422Z
Learnt from: anxolin
Repo: cowprotocol/cow-sdk PR: 306
File: src/trading/getQuote.ts:96-105
Timestamp: 2025-05-13T12:22:48.422Z
Learning: In the CoW SDK's trading functionality, app data must be built before getting a quote, even when using AUTO slippage. If AUTO slippage is used and the suggested slippage is higher than the default, the app data is recreated with the new slippage value, but the quote itself doesn't need to be refetched because slippage has no fundamental impact on the quote.

Applied to files:

  • packages/trading/src/resolveSlippageSuggestion.ts
🔇 Additional comments (11)
packages/trading/src/resolveSlippageSuggestion.ts (1)

39-39: LGTM - Protocol fee parameter correctly propagated.

The conversion of quote.protocolFeeBps to Number is appropriate for BPS values, which are always small integers (typically 0-10000). The conditional ensures undefined is passed when the protocol fee is not present.

packages/trading/src/getQuote.ts (2)

211-211: LGTM - Consistent protocol fee parameter handling.

The protocol fee is correctly converted and passed to getQuoteAmountsAndCosts, maintaining consistency with the pattern used throughout the codebase.


217-217: LGTM - Protocol fee propagated to order signing.

The protocol fee is correctly included in the order-to-sign flow, ensuring it influences the final signed order data.

packages/trading/src/utils/misc.ts (1)

36-36: LGTM - Protocol fee correctly integrated into mapping utility.

The mapQuoteAmountsAndCosts function properly handles the new protocolFee field, maintaining consistency with the existing patterns for networkFee and partnerFee. The afterProtocolFees serialization is correctly added.

Also applies to: 59-62, 67-67

packages/order-book/src/types.ts (2)

24-27: LGTM - Protocol fee type definition matches existing patterns.

The protocolFee field structure is consistent with the existing partnerFee and networkFee patterns.


39-39: LGTM - Documentation and type definition correctly updated.

The documentation accurately describes the protocol fee application order, and the afterProtocolFees field provides visibility into amounts after protocol fees but before slippage.

Also applies to: 79-84

packages/trading/src/getOrderToSign.ts (1)

21-21: LGTM - Protocol fee parameter correctly threaded through order signing.

The protocolFeeBps parameter is properly typed, destructured, and passed to getQuoteAmountsAndCosts, ensuring protocol fees are considered when calculating the order to sign.

Also applies to: 25-25, 67-67

packages/order-book/src/quoteAmountsAndCostsUtils.ts (4)

130-147: LGTM - Early return for zero/negative protocol fees.

The edge case handling for non-positive protocol fees is correct, returning zero fee amount and unchanged amounts.


151-167: LGTM - SELL order protocol fee calculation appears correct.

The formula correctly reconstructs the protocol fee from the buy amount. The comment accurately explains that the API has already deducted the protocol fee from the buy amount, and the reverse calculation extracts it: protocolFeeInBuy = buyAmount * feeBps / (1 - feeBps).


247-252: Correct: Slippage now calculated on afterProtocolFees.

This change correctly implements the intended fee application order: network fees → partner fees → protocol fees → slippage. Previously, slippage was applied to afterPartnerFees, but now it correctly uses afterProtocolFees.


215-215: LGTM - Protocol fee properly integrated into the calculation pipeline.

The protocol fee parameter is correctly read with a default value, computed via the helper function, included in the costs structure, and exposed in the return value. The integration follows the established patterns in the codebase.

Also applies to: 238-245, 265-268, 279-279

"test:coverage": "jest --coverage --json --outputFile=jest.results.json && npx coveralls < ./coverage/lcov.info",
"test:coverage:html": "jest --silent=false --coverage --coverageReporters html",
"swagger:codegen": "openapi --input https://raw.githubusercontent.com/cowprotocol/services/v2.291.0/crates/orderbook/openapi.yml --output src/generated --exportServices false --exportCore false",
"swagger:codegen": "openapi --input https://raw.githubusercontent.com/cowprotocol/services/dfb50cb4a103e8f949f5a7145beb6be63ef41c85/crates/orderbook/openapi.yml --output src/generated --exportServices false --exportCore false",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify if this commit hash corresponds to a released version.

Using a commit hash instead of a version tag makes it harder to track which API version is in use. Before merging, ensure this commit is part of a stable release and consider using a version tag instead.


🏁 Script executed:

#!/bin/bash
# Check if the commit is tagged with a version
cd /tmp
git clone --filter=blob:none --no-checkout https://github.com/cowprotocol/services.git 2>/dev/null || true
cd services
git fetch origin dfb50cb4a103e8f949f5a7145beb6be63ef41c85 2>/dev/null
git tag --contains dfb50cb4a103e8f949f5a7145beb6be63ef41c85 2>/dev/null | head -5

Length of output: 0


Let me try alternative verification approaches to check if this commit is tagged or part of a release:


---

🏁 Script executed:

```shell
#!/bin/bash
# Try using GitHub API to check the commit and its tags
COMMIT="dfb50cb4a103e8f949f5a7145beb6be63ef41c85"
REPO="cowprotocol/services"

# Check if commit exists
echo "Checking if commit exists..."
curl -s "https://api.github.com/repos/${REPO}/commits/${COMMIT}" | jq -r '.sha // empty' | head -1

# Try to find tags associated with this commit
echo "Searching for associated tags..."
curl -s "https://api.github.com/repos/${REPO}/git/refs/tags" | jq -r ".[] | select(.object.sha == \"${COMMIT}\") | .ref" 2>/dev/null | head -5

Length of output: 102



---

🏁 Script executed:

```shell
#!/bin/bash
COMMIT="dfb50cb4a103e8f949f5a7145beb6be63ef41c85"
REPO="cowprotocol/services"

# Get commit details
echo "=== Commit Details ==="
curl -s "https://api.github.com/repos/${REPO}/commits/${COMMIT}" | jq -r '.commit.message, .commit.author.date, .commit.committer.date' 2>/dev/null

# Get v2.291.0 tag info
echo ""
echo "=== v2.291.0 Tag Details ==="
curl -s "https://api.github.com/repos/${REPO}/git/refs/tags/v2.291.0" | jq -r '.object' 2>/dev/null

# Get the commit date for v2.291.0
echo ""
echo "=== v2.291.0 Commit Date ==="
curl -s "https://api.github.com/repos/${REPO}/tags" | jq -r '.[] | select(.name == "v2.291.0") | .commit.url' 2>/dev/null | head -1 | xargs -I {} curl -s {} | jq -r '.commit.author.date' 2>/dev/null

Length of output: 362


Do not merge with this unreleased commit hash. Use a stable version tag instead.

The commit dfb50cb4a103e8f949f5a7145beb6be63ef41c85 is a recent feature branch merge from 2025-11-12, not a released version. It's not tagged and differs from the previous stable version v2.291.0. Using an unreleased commit introduces maintenance risk and makes dependency tracking difficult. Before merging, switch to a stable version tag (e.g., v2.291.0 or a newer release if available).

🤖 Prompt for AI Agents
In packages/order-book/package.json around line 23, the swagger:codegen script
references an unreleased commit hash (dfb50cb4a103e8f949f5a7145beb6be63ef41c85)
in the OpenAPI input URL; replace that commit hash with a stable release tag
(for example v2.291.0 or a newer official release) so the codegen points to a
released version, then update the repository (or CI) to regenerate the
src/generated output with the chosen tag and run tests/linters to ensure no
regressions.

Comment on lines 168 to 183
} else {
/**
* todo This is not implemented properly yet for buyAmount/sellAmount calculations
*/
const ONE_PLUS_PROTOCOL_FEE_BPS = ONE_HUNDRED_BPS + protocolFeeBpsBig
const sellAmountWithNetworkFee = sellAmountAfterNetworkCosts.big + networkCostAmount.big
const protocolFeeAmountInSell = (sellAmountWithNetworkFee * protocolFeeBpsBig) / ONE_PLUS_PROTOCOL_FEE_BPS

return {
protocolFeeAmount: protocolFeeAmountInSell,
afterProtocolFees: {
sellAmount: sellAmountAfterNetworkCosts.big, // todo
buyAmount: buyAmountAfterNetworkCosts.big, // todo
},
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

BUY order protocol fee calculation is incomplete.

The TODO comments on lines 170-171, 179, and 180 indicate that the BUY order protocol fee calculation is not properly implemented yet. Additionally, the formula and amount calculations need verification:

  1. Line 173-174: The calculation uses sellAmountAfterNetworkCosts + networkCostAmount, which appears to reconstruct the original sell amount before network costs. This needs verification against the intended protocol fee application logic for BUY orders.

  2. Lines 179-180: The afterProtocolFees amounts are marked as todo and simply return the input amounts unchanged, meaning protocol fees are not actually being applied to BUY orders.

Since this is a DRAFT PR, this is expected, but these issues must be resolved before merging.

Would you like me to help design the correct formula for BUY order protocol fee calculation? The approach should mirror the SELL order logic but account for the different fee application direction.

@limitofzero
Copy link
Author

I have read the CLA Document and I hereby sign the CLA

github-actions bot added a commit that referenced this pull request Nov 13, 2025
@limitofzero limitofzero changed the title [DRAFT] feat: add protocol fee calculation for orders feat: add protocol fee calculation for orders Nov 14, 2025
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.

2 participants