Repository: cowprotocol/cow-sdk
Pull request #313: feat: implement volume slippage + sum all slippages
Author: login: anxolin
Created: 2025-05-14T21:37:57Z | Merged: 2025-05-20T09:52:05Z

Enhance slippage suggestion. Adds the total slippage as the sum of the fee slippage (from https://github.com/cowprotocol/cow-sdk/pull/308) and the volume slippage (introduced in this PR)

This PR follows is the third on the slippage series:
- 1) Follow up on https://github.com/cowprotocol/cow-sdk/pull/306
- 2) And https://github.com/cowprotocol/cow-sdk/pull/308

## Double accounting the fee
The PR fixes one issue with the calculation of the slippage tolerance. It was deducting twice the fee in the formula (denominator). 

This PRs passes the `sellAmountBeforeFee` and `sellAmountAfterFee` to the functions, so they decide which one to pick depending if its sell/buy. 

This helps preventing this issues. Before used to receive `sellAmount` and deduct the fee, but the fee was already deducted for sell orders. This was hard to detect.

## Refactored functions
Now the calculation of the slippage is simpler because I broke them down into smaller functions. 

Basically, the slippage calculation calculate the amount in tokens (not percentual or bps).
The logic to convert from absolute slippage to percentual was moved to a function and added unit tests for it.



## Reviewers
There's a bit additional noise in this PR because I moved the `utils.ts` to `utils/misc.ts` because I wanted to create a utility `utils/slippage.ts`. Sorry for the noise! 🙏

## Tests

## Suggest slippage from fee
Added unit tests for verifying the function that accounts for the slippage for fee increse

<img width="863" alt="Screenshot at May 14 21-14-10" src="https://github.com/user-attachments/assets/0c6423c3-3995-4377-aa56-9d08bd4f1c73" />

## Suggest slippage from volume
Test the slippage for the volume (accounts for price changes)

<img width="1186" alt="Screenshot at May 14 21-53-34" src="https://github.com/user-attachments/assets/e8999460-8362-44b2-a7f9-9381462c8ee9" />

## Get slippage percent
Assert the calculation of slippage percents based in absolute amounts

<img width="853" alt="Screenshot at May 14 22-36-11" src="https://github.com/user-attachments/assets/48732797-32ca-4ab7-9d0e-5ca4f586268f" />




<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced new utility functions for precise slippage calculations, including `suggestSlippageFromFee`, `suggestSlippageFromVolume`, and `getSlippagePercent`.
- **Refactor**
  - Improved slippage suggestion logic to combine multiple components and enforce minimum/maximum bounds.
  - Updated internal import paths and function signatures for consistency.
- **Bug Fixes**
  - Enhanced percentage application logic to support fixed decimal precision.
- **Tests**
  - Added comprehensive tests for slippage calculation utilities to ensure correctness and reliability.
- **Chores**
  - Updated package version to 6.0.0-RC.42.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/package.json b/package.json
index 8c00e22dc..7f624689e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@cowprotocol/cow-sdk",
-  "version": "6.0.0-RC.40",
+  "version": "6.0.0-RC.42",
   "license": "(MIT OR Apache-2.0)",
   "files": [
     "/dist"
diff --git a/src/bridging/BridgingSdk/getQuoteWithBridge.ts b/src/bridging/BridgingSdk/getQuoteWithBridge.ts
index 76e94e1b8..74f8a403a 100644
--- a/src/bridging/BridgingSdk/getQuoteWithBridge.ts
+++ b/src/bridging/BridgingSdk/getQuoteWithBridge.ts
@@ -29,7 +29,7 @@ import { parseUnits } from '@ethersproject/units'
 import { SignerLike } from '../../common'
 import { QuoteResultsWithSigner } from '../../trading/getQuote'
 import { BridgeProviderQuoteError } from '../errors'
-import { getTradeParametersAfterQuote } from '../../trading/utils'
+import { getTradeParametersAfterQuote } from '../../trading/utils/misc'
 
 type GetQuoteWithBridgeParams<T extends BridgeQuoteResult> = {
   /**
diff --git a/src/common/utils/math.ts b/src/common/utils/math.ts
index ddd2a0a89..76cbcdba8 100644
--- a/src/common/utils/math.ts
+++ b/src/common/utils/math.ts
@@ -1,3 +1,5 @@
+const SCALE = 1e6 // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
+const SCALE_BIGINT = BigInt(SCALE)
 const BPS_FACTOR = 10_000n
 
 /**
@@ -23,7 +25,7 @@ export function percentageToBps(percentage: number | bigint): number {
  * @returns The value after applying the percentage
  */
 export function applyPercentage(value: bigint, percentage: number): bigint {
-  const valueMultiplied = value * BigInt(percentage)
+  const valueMultiplied = (value * BigInt(Math.floor(percentage * SCALE))) / SCALE_BIGINT
   const roundUp = valueMultiplied % 100n !== 0n ? 1n : 0n
 
   return valueMultiplied / 100n + roundUp
diff --git a/src/trading/getEthFlowTransaction.ts b/src/trading/getEthFlowTransaction.ts
index e147f1deb..bbba35539 100644
--- a/src/trading/getEthFlowTransaction.ts
+++ b/src/trading/getEthFlowTransaction.ts
@@ -6,7 +6,7 @@ import { BARN_ETH_FLOW_ADDRESS, CowEnv, ETH_FLOW_ADDRESS } from '../common'
 import { SupportedChainId } from '../chains'
 import { GAS_LIMIT_DEFAULT } from './consts'
 import type { EthFlowOrder } from '../common/generated/EthFlow'
-import { adjustEthFlowOrderParams, calculateGasMargin } from './utils'
+import { adjustEthFlowOrderParams, calculateGasMargin } from './utils/misc'
 import { Signer } from '@ethersproject/abstract-signer'
 import type { UnsignedOrder } from '../order-signing'
 
@@ -15,7 +15,7 @@ export async function getEthFlowTransaction(
   appDataKeccak256: string,
   _params: LimitTradeParametersFromQuote,
   chainId: SupportedChainId,
-  additionalParams: PostTradeAdditionalParams = {}
+  additionalParams: PostTradeAdditionalParams = {},
 ): Promise<{ orderId: string; transaction: TransactionParams; orderToSign: UnsignedOrder }> {
   const { networkCostsAmount = '0', checkEthFlowOrderExists } = additionalParams
   const from = await signer.getAddress()
diff --git a/src/trading/getPreSignTransaction.ts b/src/trading/getPreSignTransaction.ts
index a8f2fe4ba..e56091580 100644
--- a/src/trading/getPreSignTransaction.ts
+++ b/src/trading/getPreSignTransaction.ts
@@ -2,7 +2,7 @@ import { COW_PROTOCOL_SETTLEMENT_CONTRACT_ADDRESS } from '../common'
 import { SupportedChainId } from '../chains'
 import type { Signer } from '@ethersproject/abstract-signer'
 import { GAS_LIMIT_DEFAULT } from './consts'
-import { calculateGasMargin } from './utils'
+import { calculateGasMargin } from './utils/misc'
 
 import { GPv2Settlement__factory } from '../common/generated'
 import { TransactionParams } from './types'
@@ -11,7 +11,7 @@ export async function getPreSignTransaction(
   signer: Signer,
   chainId: SupportedChainId,
   account: string,
-  orderId: string
+  orderId: string,
 ): Promise<TransactionParams> {
   const contract = GPv2Settlement__factory.connect(account, signer)
 
diff --git a/src/trading/getQuote.ts b/src/trading/getQuote.ts
index cbc6555a9..9ef8676cd 100644
--- a/src/trading/getQuote.ts
+++ b/src/trading/getQuote.ts
@@ -22,7 +22,7 @@ import {
 } from '../order-book'
 import { buildAppData } from './appDataUtils'
 import { getOrderToSign } from './getOrderToSign'
-import { adjustEthFlowOrderParams, getIsEthFlowOrder, swapParamsToLimitOrderParams } from './utils'
+import { adjustEthFlowOrderParams, getIsEthFlowOrder, swapParamsToLimitOrderParams } from './utils/misc'
 import { Signer } from '@ethersproject/abstract-signer'
 import { getOrderTypedData } from './getOrderTypedData'
 import { getSigner } from '../common/utils/wallet'
diff --git a/src/trading/index.ts b/src/trading/index.ts
index d53bedc68..18e46d408 100644
--- a/src/trading/index.ts
+++ b/src/trading/index.ts
@@ -20,4 +20,4 @@ export { getPreSignTransaction } from './getPreSignTransaction'
 
 export * from './appDataUtils'
 export * from './calculateUniqueOrderId'
-export { swapParamsToLimitOrderParams, mapQuoteAmountsAndCosts } from './utils'
+export { swapParamsToLimitOrderParams, mapQuoteAmountsAndCosts } from './utils/misc'
diff --git a/src/trading/postCoWProtocolTrade.ts b/src/trading/postCoWProtocolTrade.ts
index 9b49423f1..ae76ec1ef 100644
--- a/src/trading/postCoWProtocolTrade.ts
+++ b/src/trading/postCoWProtocolTrade.ts
@@ -5,7 +5,7 @@ import { SIGN_SCHEME_MAP } from './consts'
 import { OrderSigningUtils } from '../order-signing'
 import { getOrderToSign } from './getOrderToSign'
 import { postSellNativeCurrencyOrder } from './postSellNativeCurrencyOrder'
-import { getIsEthFlowOrder } from './utils'
+import { getIsEthFlowOrder } from './utils/misc'
 import { log } from '../common/utils/log'
 
 export async function postCoWProtocolTrade(
@@ -13,7 +13,7 @@ export async function postCoWProtocolTrade(
   signer: Signer,
   appData: AppDataInfo,
   params: LimitTradeParameters,
-  additionalParams: PostTradeAdditionalParams = {}
+  additionalParams: PostTradeAdditionalParams = {},
 ): Promise<OrderPostingResult> {
   const { networkCostsAmount = '0', signingScheme: _signingScheme = SigningScheme.EIP712 } = additionalParams
 
diff --git a/src/trading/postSwapOrder.ts b/src/trading/postSwapOrder.ts
index fc4d5c397..2b17cdeb2 100644
--- a/src/trading/postSwapOrder.ts
+++ b/src/trading/postSwapOrder.ts
@@ -2,7 +2,7 @@ import { OrderPostingResult, SwapAdvancedSettings, SwapParameters } from './type
 
 import { postCoWProtocolTrade } from './postCoWProtocolTrade'
 import { getQuoteWithSigner, QuoteResultsWithSigner } from './getQuote'
-import { swapParamsToLimitOrderParams } from './utils'
+import { swapParamsToLimitOrderParams } from './utils/misc'
 import { OrderBookApi } from '../order-book'
 import { mergeAppDataDoc } from './appDataUtils'
 
diff --git a/src/trading/suggestSlippageBps.ts b/src/trading/suggestSlippageBps.ts
index f3ac92647..6267d797a 100644
--- a/src/trading/suggestSlippageBps.ts
+++ b/src/trading/suggestSlippageBps.ts
@@ -1,8 +1,15 @@
+import { percentageToBps } from 'src/common/utils/math'
 import { getQuoteAmountsWithCosts, OrderQuoteResponse } from '../order-book'
-import { suggestSlippageBpsFromFee } from './suggestSlippageBpsFromFee'
+import { getSlippagePercent } from './utils/slippage'
+import { suggestSlippageFromFee } from './suggestSlippageFromFee'
+import { suggestSlippageFromVolume } from './suggestSlippageFromVolume'
 import { QuoterParameters, SwapAdvancedSettings, TradeParameters } from './types'
 
-const SLIPPAGE_FEE_MULTIPLIER_PERCENT = 50
+const MIN_SLIPPAGE_BPS = 50 // 0.5% in BPS (min slippage)
+const MAX_SLIPPAGE_BPS = 10_000 // 100% in BPS (max slippage)
+
+const SLIPPAGE_FEE_MULTIPLIER_PERCENT = 50 // Account for 50% fee increase
+const SLIPPAGE_VOLUME_MULTIPLIER_PERCENT = 0.5 // Account for 0.5% volume as slippage
 
 export interface SuggestSlippageBps {
   tradeParameters: TradeParameters
@@ -24,15 +31,37 @@ export function suggestSlippageBps(params: SuggestSlippageBps): number {
     buyDecimals: buyTokenDecimals,
     orderParams: quote.quote,
   })
+  const { feeAmount: feeAmountString } = quote.quote
+  const feeAmount = BigInt(feeAmountString)
 
-  // Get the relevant amount of the sell token (depending on the order kind)
-  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
-  const { feeAmount } = quote.quote
+  // Account for some slippage due to the fee increase
+  const slippageBpsFromFee = suggestSlippageFromFee({
+    feeAmount,
+    multiplyingFactorPercent: SLIPPAGE_FEE_MULTIPLIER_PERCENT,
+  })
 
-  return suggestSlippageBpsFromFee({
-    feeAmount: BigInt(feeAmount),
-    sellAmount,
+  // Account for some slippage due to price change (volume slippage)
+  const slippageBpsFromVolume = suggestSlippageFromVolume({
     isSell,
-    multiplyingFactorPercent: SLIPPAGE_FEE_MULTIPLIER_PERCENT,
+    sellAmountBeforeNetworkCosts,
+    sellAmountAfterNetworkCosts,
+    slippagePercent: SLIPPAGE_VOLUME_MULTIPLIER_PERCENT,
+  })
+
+  // Aggregate all slippages
+  const totalSlippageBps = slippageBpsFromFee + slippageBpsFromVolume
+
+  // Get percentage slippage
+  const slippagePercent = getSlippagePercent({
+    isSell,
+    sellAmountBeforeNetworkCosts,
+    sellAmountAfterNetworkCosts,
+    slippage: totalSlippageBps,
   })
+
+  // Convert to BPS
+  const slippageBps = percentageToBps(slippagePercent)
+
+  // Clamp slippage to min/max
+  return Math.max(Math.min(slippageBps, MAX_SLIPPAGE_BPS), MIN_SLIPPAGE_BPS)
 }
diff --git a/src/trading/suggestSlippageBpsFromFee.test.ts b/src/trading/suggestSlippageBpsFromFee.test.ts
deleted file mode 100644
index d9147b123..000000000
--- a/src/trading/suggestSlippageBpsFromFee.test.ts
+++ /dev/null
@@ -1,159 +0,0 @@
-import { suggestSlippageBpsFromFee } from './suggestSlippageBpsFromFee'
-
-interface SuggestedFeeTest {
-  fee: bigint
-  sell: bigint
-  factor: number
-  expected: number | string
-  description?: string
-  only?: boolean
-}
-
-describe('Sell orders', () => {
-  const isSell = true
-
-  assertCases('handle different factors', isSell, [
-    // expected = 1 - (100 - ceil(20 * 1.01)) / (100 - 20) = 0
-    { fee: 20n, sell: 100n, factor: 1, expected: 125 },
-
-    // expected = 1 - (100 - 20 * 1.25) / (100 - 20) = 0.125
-    { fee: 20n, sell: 100n, factor: 25, expected: 625 },
-
-    // expected = 1 - (100 - 20 * 1.50) / (100 - 20) = 0.125
-    { fee: 20n, sell: 100n, factor: 50, expected: 1250 },
-
-    // expected = 1 - (100 - 20 * 1.75) / (100 - 20) = 0.125
-    { fee: 20n, sell: 100n, factor: 75, expected: 1875 },
-
-    // expected = 1 - (100 - 20 * 2) / (100 - 20) = 0.125
-    { fee: 20n, sell: 100n, factor: 100, expected: 2500 },
-
-    // expected = 1 - (100 - 20 * 1.5) / (100 - 20) = 0.125
-    { fee: 20n, sell: 100n, factor: 200, expected: 5000 },
-
-    // Absurd factor, returns max slippage
-    { fee: 20n, sell: 100n, factor: 100_000_000, expected: 10000 },
-  ])
-
-  assertCases('Handle atoms', isSell, [
-    // expected = 1 - (1 - 0.2 * 1) / (1 - 0.2) = 0
-    { fee: atoms(0.2), sell: atoms(1), factor: 0, expected: 50 },
-
-    // expected = 1 - (1 - 0.2 * 1.25) / (1 - 0.2) = 0.125
-    { fee: atoms(0.2), sell: atoms(1), factor: 25, expected: 625 },
-
-    // expected = 1 - (1 - 0.2 * 1.5) / (1 - 0.2) = 0.125
-    { fee: atoms(0.2), sell: atoms(1), factor: 50, expected: 1250 },
-
-    // expected = 1 - (1 - 0.2 * 1.75) / (1 - 0.2) = 0.125
-    { fee: atoms(0.2), sell: atoms(1), factor: 75, expected: 1875 },
-
-    // expected = 1 - (1 - 0.2 * 1.5) / (1 - 0.2) = 0.125
-    { fee: atoms(0.2), sell: atoms(1), factor: 100, expected: 2500 },
-  ])
-
-  assertCases('Handle minimum BPS', isSell, [
-    // expected = 1 - (100 - 20 * 1.00) / (100 - 20) = 0
-    { fee: 20n, sell: 100n, factor: 0, expected: 50 },
-
-    // Fee is 0: returns maximum slippage
-    {
-      fee: 1n,
-      sell: 10000n,
-      factor: 50,
-      expected: 50,
-      description: 'If suggested slippage is too small, returns the minimum slippage (50 BPS)',
-    },
-  ])
-
-  assertCases('Handle edge case with sellAmount', isSell, [
-    // Fee is 0: returns maximum slippage
-    { fee: 0n, sell: 0n, factor: 50, expected: 10_000, description: 'amount is 0, fee is 0' },
-
-    // Fee is 0: returns maximum slippage
-    { fee: 20n, sell: 0n, factor: 50, expected: 10_000, description: 'amount is 0, fee is not 0' },
-  ])
-
-  assertCases('Handle edge case with fees', isSell, [
-    // Fee is 0
-    //   expected = 1 - (100 - 20 * 1.5) / (100 - 20) = 0.125
-    { fee: 0n, sell: 100n, factor: 50, expected: 50, description: 'fee is 0' },
-
-    // Fee is all the sell amount
-    //   expected = 1 - (100 - 20 * 1.5) / (100 - 20) = 0.125
-    { fee: 100n, sell: 100n, factor: 50, expected: 10_000, description: 'fee is equal to sellAmount' },
-
-    // Fee is bigger than the sell amount (should not happen)
-    //   expected = 1 - (100 - 20 * 1.5) / (100 - 20) = 0.125
-    { fee: 100n, sell: 100n, factor: 50, expected: 10_000, description: 'fee is bigger than sellAmount' },
-
-    // Fee is negative, it should throw an error
-    {
-      fee: -100n,
-      sell: 100n,
-      factor: 50,
-      expected: 'Fee amount cannot be negative: -100',
-      description: 'fee is negative',
-    },
-  ])
-})
-
-describe('Buy orders', () => {
-  const isSell = false
-
-  assertCases('handle different factors', isSell, [
-    // // expected = (100 + 20 * 1) / (100 + 20) - 1 = 0
-    { fee: 20n, sell: 100n, factor: 0, expected: 50 },
-
-    // // expected = (100 + 20 * 1.25) / (100 + 20) - 1 = 0.04166666667
-    { fee: 20n, sell: 100n, factor: 25, expected: 417 },
-
-    // expected = (100 + 20 * 1.5) / (100 + 20) - 1 = 0.08333333333
-    { fee: 20n, sell: 100n, factor: 50, expected: 834 },
-
-    // // expected = (100 + 20 * 1.75) / (100 + 20) - 1 = 0.125
-    { fee: 20n, sell: 100n, factor: 75, expected: 1250 },
-
-    // expected = (100 + 20 * 2) / (100 + 20) - 1 = 0.1666666667
-    { fee: 20n, sell: 100n, factor: 100, expected: 1667 },
-
-    // expected = (100 + 20 * 3) / (100 + 20) - 1 = 0.3333333333
-    { fee: 20n, sell: 100n, factor: 200, expected: 3334 },
-
-    // Absurd factor, returns max slippage
-    { fee: 20n, sell: 100n, factor: 100_000_000, expected: 10000 },
-  ])
-})
-
-function atoms(amount: number) {
-  return BigInt(amount * 1e18)
-}
-
-function assertCases(description: string, isSell: boolean, testCases: SuggestedFeeTest[]) {
-  describe(description, () => {
-    testCases.forEach(({ sell, fee, factor, expected, description: testCaseDescription, only }) => {
-      const shouldThrow = typeof expected === 'string'
-      const expectedDescription = shouldThrow ? `should throw "${expected}"` : `should return ${expected} BPS`
-      const caseDescription = testCaseDescription
-        ? `When ${testCaseDescription}, ${expectedDescription}`
-        : `suggestSlippageBpsFromFee(sell=${sell}, fee=${fee}, factor=${factor}) ${expectedDescription}`
-
-      const runTest = only ? it.only : it
-      runTest(`[${isSell ? 'sell' : 'buy'}] ${caseDescription}`, () => {
-        // If expected is a string, it should throw an error
-        const params = {
-          feeAmount: fee,
-          sellAmount: sell,
-          isSell,
-          multiplyingFactorPercent: factor,
-        }
-        if (shouldThrow) {
-          expect(() => suggestSlippageBpsFromFee(params)).toThrow(expected)
-        } else {
-          const result = suggestSlippageBpsFromFee(params)
-          expect(result).toBe(expected)
-        }
-      })
-    })
-  })
-}
diff --git a/src/trading/suggestSlippageBpsFromFee.ts b/src/trading/suggestSlippageBpsFromFee.ts
deleted file mode 100644
index af906d928..000000000
--- a/src/trading/suggestSlippageBpsFromFee.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { applyPercentage, percentageToBps } from 'src/common/utils/math'
-
-const MIN_SLIPPAGE_BPS = 50
-const MAX_SLIPPAGE_BPS = 10_000 // 100% in BPS
-const ONE_HUNDRED_PERCENT_DECIMAL = 1 // 100 in decimal percentage
-
-const SCALE = 10n ** 6n // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
-
-export interface SuggestSlippageBpsFromFeeParams {
-  /**
-   * Fee amount in the sell token returned by the quote
-   */
-  feeAmount: bigint
-
-  /**
-   * Actual amount to be sold
-   *
-   * For sell orders, its expected the sell amount after the fee is applied
-   * For buy orders, its expected to be the sell amount before the fee is applied
-   */
-  sellAmount: bigint
-
-  /**
-   * Whether the order is a sell order or a buy order
-   */
-  isSell: boolean
-
-  /**
-   * The factor to multiply the fee amount by to get the suggested slippage.
-   *
-   * For example, if the factor is 50% it would calculate which slippage would allow the fee to increase by 50% and still go through.
-   */
-  multiplyingFactorPercent: number
-}
-
-/**
- * Return the slippage in BPS that would allow the fee to increase by the multiplying factor percent.
- *
- * If the fees are bigger or equal to the sell amount, it returns the 10_000 BPS (100% slippage).
- */
-export function suggestSlippageBpsFromFee(params: SuggestSlippageBpsFromFeeParams): number {
-  const slippagePercent = suggestSlippagePercent(params)
-  const slippageBps = percentageToBps(slippagePercent)
-
-  return Math.max(Math.min(slippageBps, MAX_SLIPPAGE_BPS), MIN_SLIPPAGE_BPS)
-}
-
-export function suggestSlippagePercent(params: SuggestSlippageBpsFromFeeParams): number {
-  const { feeAmount, sellAmount, isSell, multiplyingFactorPercent } = params
-
-  // Negative fees are not allowed
-  if (feeAmount < 0n) {
-    throw new Error('Fee amount cannot be negative: ' + feeAmount)
-  }
-
-  // Multiplying factor must be a valid percentage
-  if (multiplyingFactorPercent < 0) {
-    throw new Error('multiplyingFactorPercent must be a percentage: ' + multiplyingFactorPercent)
-  }
-
-  // Get the amount we want to account for our slippage
-  const feeAfterIncrease = applyPercentage(feeAmount, 100 + multiplyingFactorPercent)
-
-  // Account fee (fee is deducted to sell amount for sell orders and added for buy orders)
-  const sellAmountAccountingFee = isSell ? sellAmount - feeAmount : sellAmount + feeAmount
-
-  // Return maximum slippage if the sellAmount after accounting for the fee is 0 or negative
-  if (sellAmountAccountingFee <= 0n) {
-    // Return 1 (== 100 %) so that later conversion to BPS is consistent
-    return ONE_HUNDRED_PERCENT_DECIMAL
-  }
-
-  if (isSell) {
-    // For sell orders:
-    // 1 - ((sellAmount - feeAmount * multiplier) / (sellAmount - feeAmount))
-    // i.e: feeAmount=5, sellAmount=100, multiplier=1.5
-    //    suggestSlippageBpsFromFee = 1 - (100-5*1.5) / (100-5) = 0.02631578947
-    //    suggestSlippageBpsFromFee (in scale) = 1e18 - (1e18*(100-5*1.5)) / (100-5) = 26,315,789,473,684,210
-    //    suggestSlippageBpsFromFee = 26,315,789,473,684,210 / 1e18 = 0.02631578947
-    const percentageInScale = SCALE - (SCALE * (sellAmount - feeAfterIncrease)) / sellAmountAccountingFee
-
-    return Number(percentageInScale) / Number(SCALE)
-  } else {
-    // For buy orders:
-    // ((sellAmount + feeAmount * feeMultiplierFactor) / (sellAmount + feeAmount)) - 1
-    // i.e: feeAmount=5, sellAmount=100, multiplier=1.5
-    //    suggestSlippageBpsFromFee = (100+5*1.5) / (100+5) - 1 = 0.02380952381
-    //    suggestSlippageBpsFromFee (in scale) = (1e18*(100+5*1.5)) / (100+5) - 1e18 = 23,809,523,809,523,809
-    //    suggestSlippageBpsFromFee = 23,809,523,809,523,809 / 1e18 = 0.02380952381
-    const percentageInScale = (SCALE * (sellAmount + feeAfterIncrease)) / sellAmountAccountingFee - SCALE
-
-    return Number(percentageInScale) / Number(SCALE)
-  }
-}
diff --git a/src/trading/suggestSlippageFromFee.test.ts b/src/trading/suggestSlippageFromFee.test.ts
new file mode 100644
index 000000000..51e3492e9
--- /dev/null
+++ b/src/trading/suggestSlippageFromFee.test.ts
@@ -0,0 +1,77 @@
+import { suggestSlippageFromFee, SuggestSlippageFromFeeParams } from './suggestSlippageFromFee'
+
+interface SuggestedFeeTest {
+  fee: bigint
+  factor: number
+  expected: number | string
+  description?: string
+  only?: boolean
+}
+
+assertCases('handle different factors', [
+  { fee: 20n, factor: 0, expected: 0 },
+  { fee: 20n, factor: 1, expected: 1 },
+  { fee: 20n, factor: 25, expected: 5 },
+  { fee: 20n, factor: 50, expected: 10 },
+  { fee: 20n, factor: 75, expected: 15 },
+  { fee: 20n, factor: 100, expected: 20 },
+  { fee: 20n, factor: 200, expected: 40 },
+  { fee: 20n, factor: 100_000_000, expected: 20_000_000 },
+])
+
+assertCases('Handle atoms', [
+  { fee: atoms(0.2), factor: 0, expected: 0 },
+  { fee: atoms(0.2), factor: 25, expected: 50000000000000000 },
+  { fee: atoms(0.2), factor: 50, expected: 100000000000000000 },
+  { fee: atoms(0.2), factor: 75, expected: 150000000000000000 },
+  { fee: atoms(0.2), factor: 100, expected: 200000000000000000 },
+])
+
+assertCases('Handle fee edge cases', [
+  // Fee is negative, it should throw an error
+  {
+    fee: -100n,
+    factor: 50,
+    expected: 'Fee amount must be non-negative: -100',
+    description: 'fee is negative',
+  },
+
+  // Fee is negative, it should throw an error
+  {
+    fee: 100n,
+    factor: -50,
+    expected: 'multiplyingFactorPercent must be non-negative: -50',
+    description: 'multiplyingFactorPercent is negative',
+  },
+])
+
+function atoms(amount: number) {
+  return BigInt(amount * 1e18)
+}
+
+function assertCases(description: string, testCases: SuggestedFeeTest[]) {
+  describe(description, () => {
+    testCases.forEach(({ fee, factor, expected, description: testCaseDescription, only }) => {
+      const shouldThrow = typeof expected === 'string'
+      const expectedDescription = shouldThrow ? `should throw "${expected}"` : `should return ${expected} tokens`
+      const caseDescription = testCaseDescription
+        ? `When ${testCaseDescription}, ${expectedDescription}`
+        : `suggestSlippageFromFee(fee=${fee}, factor=${factor}) ${expectedDescription}`
+
+      const runTest = only ? it.only : it
+      runTest(caseDescription, () => {
+        // If expected is a string, it should throw an error
+        const params: SuggestSlippageFromFeeParams = {
+          feeAmount: fee,
+          multiplyingFactorPercent: factor,
+        }
+        if (shouldThrow) {
+          expect(() => suggestSlippageFromFee(params)).toThrow(expected)
+        } else {
+          const result = suggestSlippageFromFee(params)
+          expect(Number(result)).toBe(expected)
+        }
+      })
+    })
+  })
+}
diff --git a/src/trading/suggestSlippageFromFee.ts b/src/trading/suggestSlippageFromFee.ts
new file mode 100644
index 000000000..72e5dcc9d
--- /dev/null
+++ b/src/trading/suggestSlippageFromFee.ts
@@ -0,0 +1,38 @@
+import { applyPercentage } from 'src/common/utils/math'
+
+export interface SuggestSlippageFromFeeParams {
+  /**
+   * Fee amount in the sell token returned by the quote
+   */
+  feeAmount: bigint
+
+  /**
+   * The factor to multiply the fee amount by to get the suggested slippage.
+   *
+   * For example, if the factor is 50% it would calculate which slippage would allow the fee to increase by 50% and still go through.
+   */
+  multiplyingFactorPercent: number
+}
+
+/**
+ * Return the absolute slippage in the sell token that would allow the order to execute, even if the fee increases by the multiplying factor percent.
+ *
+ * @returns The slippage amount in the same units as the fee (sell token amount)
+ * @throws Error if feeAmount or multiplyingFactorPercent is negative
+ */
+export function suggestSlippageFromFee(params: SuggestSlippageFromFeeParams): bigint {
+  const { feeAmount, multiplyingFactorPercent } = params
+
+  // Negative fees are not allowed
+  if (feeAmount < 0n) {
+    throw new Error('Fee amount must be non-negative: ' + feeAmount)
+  }
+
+  // Multiplying factor must be a valid percentage
+  if (multiplyingFactorPercent < 0) {
+    throw new Error('multiplyingFactorPercent must be non-negative: ' + multiplyingFactorPercent)
+  }
+
+  // Get the amount we want to account for our slippage
+  return applyPercentage(feeAmount, multiplyingFactorPercent)
+}
diff --git a/src/trading/suggestSlippageFromVolume.test.ts b/src/trading/suggestSlippageFromVolume.test.ts
new file mode 100644
index 000000000..9d6a20d5d
--- /dev/null
+++ b/src/trading/suggestSlippageFromVolume.test.ts
@@ -0,0 +1,117 @@
+import { suggestSlippageFromVolume, SuggestSlippageFromVolumeParams } from './suggestSlippageFromVolume'
+
+interface SuggestedFeeTest {
+  sellBefore: bigint
+  sellAfter: bigint
+  percentage: number
+  expected: number | string
+  description?: string
+  only?: boolean
+}
+
+const baseParams = { isSell: true, sellBefore: 20n, sellAfter: 15n }
+const baseParamsAtoms = { isSell: true, sellBefore: atoms(20), sellAfter: atoms(15) }
+
+describe('Sell orders', () => {
+  const isSell = true
+
+  assertCases('handle different factors', isSell, [
+    { ...baseParams, percentage: 0, expected: 0 },
+    { ...baseParams, percentage: 0.5, expected: 1 },
+    { ...baseParams, percentage: 10, expected: 2 },
+    { ...baseParams, percentage: 25, expected: 4 },
+    { ...baseParams, percentage: 50, expected: 8 },
+    { ...baseParams, percentage: 100, expected: 15 },
+    { ...baseParams, percentage: 100_000_000, expected: 15_000_000 },
+  ])
+
+  assertCases('Handle atoms', isSell, [
+    { ...baseParamsAtoms, percentage: 0, expected: 0 },
+    { ...baseParamsAtoms, percentage: 0.5, expected: 75000000000000000 },
+    { ...baseParamsAtoms, percentage: 10, expected: 1500000000000000000 },
+    { ...baseParamsAtoms, percentage: 100_000_000, expected: 1.5e25 },
+  ])
+
+  assertCases('Handle edge case with sellAmount', isSell, [
+    // sellBefore is 0: returns maximum slippage
+    {
+      ...baseParams,
+      sellAfter: -10n,
+      percentage: 0.5,
+      expected: 'sellAmount must be non-negative: -10',
+      description: 'sellAmountAfterFees is 0, sellBefore is 0',
+    },
+
+    {
+      ...baseParams,
+      percentage: -0.5,
+      expected: 'slippagePercent must be non-negative: -0.5',
+      description: 'amount is 0, sellBefore is not 0',
+    },
+  ])
+})
+
+describe('Buy orders', () => {
+  const isSell = false
+
+  assertCases('handle different factors', isSell, [
+    { ...baseParams, percentage: 0, expected: 0 },
+    { ...baseParams, percentage: 0.5, expected: 1 },
+    { ...baseParams, percentage: 10, expected: 2 },
+    { ...baseParams, percentage: 25, expected: 5 },
+    { ...baseParams, percentage: 50, expected: 10 },
+    { ...baseParams, percentage: 100, expected: 20 },
+    { ...baseParams, percentage: 100_000_000, expected: 20_000_000 },
+  ])
+
+  assertCases('Handle atoms', isSell, [
+    { ...baseParamsAtoms, percentage: 0, expected: 0 },
+    { ...baseParamsAtoms, percentage: 0.5, expected: 100000000000000000 },
+    { ...baseParamsAtoms, percentage: 10, expected: 2000000000000000000 },
+    { ...baseParamsAtoms, percentage: 100_000_000, expected: 2e25 },
+  ])
+
+  assertCases('Handle edge case with sellAmount', isSell, [
+    // sellBefore is 0: returns maximum slippage
+    {
+      ...baseParams,
+      sellBefore: -10n,
+      percentage: 0.5,
+      expected: 'sellAmount must be non-negative: -10',
+      description: 'sellAmountAfterFees is 0, sellBefore is 0',
+    },
+  ])
+})
+
+function atoms(amount: number) {
+  return BigInt(amount * 1e18)
+}
+
+function assertCases(description: string, isSell: boolean, testCases: SuggestedFeeTest[]) {
+  describe(description, () => {
+    testCases.forEach(({ sellAfter, sellBefore, percentage, expected, description: testCaseDescription, only }) => {
+      const shouldThrow = typeof expected === 'string'
+      const expectedDescription = shouldThrow ? `should throw "${expected}"` : `should return ${expected} tokens`
+      const caseDescription = testCaseDescription
+        ? `When ${testCaseDescription}, ${expectedDescription}`
+        : `suggestSlippageFromVolume(sellAmountBeforeNetworkCosts=${sellBefore}, sellAmountAfterNetworkCosts=${sellAfter}, slippagePercent=${percentage}) ${expectedDescription}`
+
+      const runTest = only ? it.only : it
+      runTest(`[${isSell ? 'sell' : 'buy'}] ${caseDescription}`, () => {
+        // If expected is a string, it should throw an error
+        const params: SuggestSlippageFromVolumeParams = {
+          isSell,
+          sellAmountBeforeNetworkCosts: sellBefore,
+          sellAmountAfterNetworkCosts: sellAfter,
+          slippagePercent: percentage,
+        }
+        if (shouldThrow) {
+          expect(() => suggestSlippageFromVolume(params)).toThrow(expected)
+        } else {
+          const result = suggestSlippageFromVolume(params)
+          expect(Number(result)).toBe(expected)
+        }
+      })
+    })
+  })
+}
diff --git a/src/trading/suggestSlippageFromVolume.ts b/src/trading/suggestSlippageFromVolume.ts
new file mode 100644
index 000000000..3655af25d
--- /dev/null
+++ b/src/trading/suggestSlippageFromVolume.ts
@@ -0,0 +1,29 @@
+import { applyPercentage } from 'src/common/utils/math'
+
+export interface SuggestSlippageFromVolumeParams {
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  isSell: boolean
+  slippagePercent: number
+}
+
+/**
+ * Return the absolute slippage in sell token for the traded amount
+ */
+export function suggestSlippageFromVolume(params: SuggestSlippageFromVolumeParams): bigint {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, isSell, slippagePercent } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Negative sell amounts are not allowed
+  if (sellAmount < 0n) {
+    throw new Error('sellAmount must be non-negative: ' + sellAmount)
+  }
+
+  // Slippage percentage must be non-negative
+  if (slippagePercent < 0) {
+    throw new Error('slippagePercent must be non-negative: ' + slippagePercent)
+  }
+
+  return applyPercentage(sellAmount, slippagePercent)
+}
diff --git a/src/trading/tradingSdk.ts b/src/trading/tradingSdk.ts
index 61cf26de2..210c89d05 100644
--- a/src/trading/tradingSdk.ts
+++ b/src/trading/tradingSdk.ts
@@ -11,7 +11,7 @@ import { postSwapOrder, postSwapOrderFromQuote } from './postSwapOrder'
 import { postLimitOrder } from './postLimitOrder'
 import { getQuoteWithSigner, QuoteResultsWithSigner } from './getQuote'
 import { postSellNativeCurrencyOrder } from './postSellNativeCurrencyOrder'
-import { getTradeParametersAfterQuote, swapParamsToLimitOrderParams } from './utils'
+import { getTradeParametersAfterQuote, swapParamsToLimitOrderParams } from './utils/misc'
 import { getPreSignTransaction } from './getPreSignTransaction'
 import { enableLogging } from '../common/utils/log'
 import { OrderBookApi } from '../order-book'
@@ -27,7 +27,7 @@ export interface TradingSdkOptions {
 export class TradingSdk {
   constructor(
     public traderParams: Partial<TraderParameters> = {},
-    public readonly options: Partial<TradingSdkOptions> = {},
+    public readonly options: Partial<TradingSdkOptions> = {}
   ) {
     if (options.enableLogging !== undefined) {
       enableLogging(options.enableLogging)
@@ -42,7 +42,7 @@ export class TradingSdk {
 
   async getQuote(
     params: WithPartialTraderParams<TradeParameters>,
-    advancedSettings?: SwapAdvancedSettings,
+    advancedSettings?: SwapAdvancedSettings
   ): Promise<QuoteAndPost> {
     const quoteResults = await getQuoteWithSigner(this.mergeParams(params), advancedSettings, this.options.orderBookApi)
 
@@ -60,35 +60,35 @@ export class TradingSdk {
               }),
             },
           },
-          advancedSettings,
+          advancedSettings
         ),
     }
   }
 
   async getQuoteResults(
     params: WithPartialTraderParams<TradeParameters>,
-    advancedSettings?: SwapAdvancedSettings,
+    advancedSettings?: SwapAdvancedSettings
   ): Promise<QuoteResultsWithSigner> {
     return getQuoteWithSigner(this.mergeParams(params), advancedSettings, this.options.orderBookApi)
   }
 
   async postSwapOrder(
     params: WithPartialTraderParams<TradeParameters>,
-    advancedSettings?: SwapAdvancedSettings,
+    advancedSettings?: SwapAdvancedSettings
   ): Promise<OrderPostingResult> {
     return postSwapOrder(this.mergeParams(params), advancedSettings, this.options.orderBookApi)
   }
 
   async postLimitOrder(
     params: WithPartialTraderParams<LimitTradeParameters>,
-    advancedSettings?: LimitOrderAdvancedSettings,
+    advancedSettings?: LimitOrderAdvancedSettings
   ): Promise<OrderPostingResult> {
     return postLimitOrder(this.mergeParams(params), advancedSettings, this.options.orderBookApi)
   }
 
   async postSellNativeCurrencyOrder(
     params: WithPartialTraderParams<TradeParameters>,
-    advancedSettings?: SwapAdvancedSettings,
+    advancedSettings?: SwapAdvancedSettings
   ): Promise<ReturnType<typeof postSellNativeCurrencyOrder>> {
     const quoteResults = await getQuoteWithSigner(this.mergeParams(params), advancedSettings, this.options.orderBookApi)
 
@@ -100,14 +100,14 @@ export class TradingSdk {
       // Quote response always has an id
       swapParamsToLimitOrderParams(
         getTradeParametersAfterQuote({ quoteParameters: tradeParameters, sellToken: params.sellToken }),
-        quoteResponse,
+        quoteResponse
       ),
-      advancedSettings?.additionalParams,
+      advancedSettings?.additionalParams
     )
   }
 
   async getPreSignTransaction(
-    params: WithPartialTraderParams<{ orderId: string; account: string }>,
+    params: WithPartialTraderParams<{ orderId: string; account: string }>
   ): ReturnType<typeof getPreSignTransaction> {
     const traderParams = this.mergeParams(params)
     const signer = getSigner(traderParams.signer)
diff --git a/src/trading/utils.ts b/src/trading/utils/misc.ts
similarity index 86%
rename from src/trading/utils.ts
rename to src/trading/utils/misc.ts
index a832b94e2..899d12d22 100644
--- a/src/trading/utils.ts
+++ b/src/trading/utils/misc.ts
@@ -1,12 +1,12 @@
-import { LimitTradeParametersFromQuote, TradeParameters } from './types'
-import { OrderQuoteResponse, QuoteAmountsAndCosts } from '../order-book'
-import { ETH_ADDRESS, WRAPPED_NATIVE_CURRENCIES } from '../common'
-import { SupportedChainId } from '../chains'
-import { ETH_FLOW_DEFAULT_SLIPPAGE_BPS } from './consts'
+import { LimitTradeParametersFromQuote, TradeParameters } from '../types'
+import { OrderQuoteResponse, QuoteAmountsAndCosts } from '../../order-book'
+import { ETH_ADDRESS, WRAPPED_NATIVE_CURRENCIES } from '../../common'
+import { SupportedChainId } from '../../chains'
+import { ETH_FLOW_DEFAULT_SLIPPAGE_BPS } from '../consts'
 
 export function swapParamsToLimitOrderParams(
   params: TradeParameters,
-  quoteResponse: OrderQuoteResponse
+  quoteResponse: OrderQuoteResponse,
 ): LimitTradeParametersFromQuote {
   return {
     ...params,
@@ -31,7 +31,7 @@ export function calculateGasMargin(value: bigint): bigint {
 
 export function mapQuoteAmountsAndCosts<T, R>(
   value: QuoteAmountsAndCosts<T>,
-  mapper: (value: T) => R
+  mapper: (value: T) => R,
 ): QuoteAmountsAndCosts<R> {
   const {
     costs: { networkFee, partnerFee },
@@ -86,7 +86,7 @@ export function getTradeParametersAfterQuote({
  */
 export function adjustEthFlowOrderParams(
   chainId: SupportedChainId,
-  params: TradeParameters | LimitTradeParametersFromQuote
+  params: TradeParameters | LimitTradeParametersFromQuote,
 ): typeof params {
   return {
     ...params,
diff --git a/src/trading/utils/slippage.test.ts b/src/trading/utils/slippage.test.ts
new file mode 100644
index 000000000..eeb7baee8
--- /dev/null
+++ b/src/trading/utils/slippage.test.ts
@@ -0,0 +1,93 @@
+import { getSlippagePercent } from './slippage'
+
+interface SlippageTest {
+  sellBefore: bigint
+  sellAfter: bigint
+  slippage: bigint
+  expected: number | string
+  description?: string
+  only?: boolean
+}
+
+const baseParams = { sellBefore: 120n, sellAfter: 100n }
+
+describe('getSlippagePercent', () => {
+  describe('Sell orders', () => {
+    const isSell = true
+
+    assertCases('handle standard cases', isSell, [
+      { ...baseParams, slippage: 0n, expected: 0 }, // 0%
+      { ...baseParams, slippage: 5n, expected: 0.05 }, // 5%
+      { ...baseParams, slippage: 10n, expected: 0.1 }, // 10%
+      { ...baseParams, slippage: 20n, expected: 0.2 }, // 20%
+      { ...baseParams, slippage: 100n, expected: 1 }, // 100%
+      { ...baseParams, slippage: 101n, expected: 1.01 }, // 101%
+      { ...baseParams, slippage: 10_000n, expected: 100 }, // 10_000%
+    ])
+
+    assertCases('handle error cases', isSell, [
+      { ...baseParams, sellAfter: -10n, slippage: 20n, expected: 'sellAmount must be greater than 0: -10' },
+      { ...baseParams, slippage: -1n, expected: 'slippage must be non-negative: -1' },
+    ])
+
+    assertCases('handle precision cases', isSell, [
+      { sellBefore: 10000000n, sellAfter: 10000000n, slippage: 123456n, expected: 0.0123456 },
+    ])
+  })
+
+  describe('Buy orders', () => {
+    const isSell = false
+
+    assertCases('handle standard cases', isSell, [
+      { ...baseParams, slippage: 0n, expected: 0 }, // 0%
+      { ...baseParams, slippage: 3n, expected: 0.025 }, // 2.5% (2.5% of 120 --> 3)
+      { ...baseParams, slippage: 6n, expected: 0.05 }, // 5%
+      { ...baseParams, slippage: 12n, expected: 0.1 }, // 10%
+      { ...baseParams, slippage: 120n, expected: 1 }, // 100%
+      { ...baseParams, slippage: 121n, expected: 1.008333 }, // 100.8333%
+      { ...baseParams, slippage: 10_000n, expected: 83.333333 }, // 8,333.3333%
+    ])
+
+    assertCases('handle error cases', isSell, [
+      { ...baseParams, sellBefore: -10n, slippage: 20n, expected: 'sellAmount must be greater than 0: -10' },
+      { ...baseParams, slippage: -1n, expected: 'slippage must be non-negative: -1' },
+    ])
+
+    assertCases('handle precision cases', isSell, [
+      { sellBefore: 10000000n, sellAfter: 10000000n, slippage: 123456n, expected: 0.012345 },
+    ])
+  })
+})
+
+function assertCases(description: string, isSell: boolean, testCases: SlippageTest[]) {
+  describe(description, () => {
+    testCases.forEach(({ sellBefore, sellAfter, slippage, expected, description: testCaseDescription, only }) => {
+      const shouldThrow = typeof expected === 'string'
+      const caseDescription = testCaseDescription
+        ? `When ${testCaseDescription}`
+        : `getSlippagePercent(sellBefore=${sellBefore}, sellAfter=${sellAfter}, slippage=${slippage}) should ${shouldThrow ? 'throw "' + expected + '"' : 'return ' + expected}`
+
+      const runTest = only ? it.only : it
+      runTest(`[${isSell ? 'sell' : 'buy'}] ${caseDescription}`, () => {
+        if (shouldThrow) {
+          expect(() =>
+            getSlippagePercent({
+              isSell,
+              sellAmountBeforeNetworkCosts: sellBefore,
+              sellAmountAfterNetworkCosts: sellAfter,
+              slippage,
+            }),
+          ).toThrow(expected as string)
+        } else {
+          const result = getSlippagePercent({
+            isSell,
+            sellAmountBeforeNetworkCosts: sellBefore,
+            sellAmountAfterNetworkCosts: sellAfter,
+            slippage,
+          })
+          expect(result).toBeCloseTo(expected as number, 6) // Using toBeCloseTo with 6 decimal precision
+        }
+      })
+    })
+  })
+}
diff --git a/src/trading/utils/slippage.ts b/src/trading/utils/slippage.ts
new file mode 100644
index 000000000..1a4521c79
--- /dev/null
+++ b/src/trading/utils/slippage.ts
@@ -0,0 +1,51 @@
+const SCALE = 10n ** 6n // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
+
+/**
+ * Get the slippage percentage for a given absolute slippage.
+ *
+ * Returns a percentage as a portion of 1 with 6 decimals of precision.
+ *
+ * @param params
+ * @returns
+ */
+export function getSlippagePercent(params: {
+  isSell: boolean
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  slippage: bigint
+}): number {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, slippage, isSell } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Check that the sellAmount after accounting for the fee is not negative
+  if (sellAmount <= 0n) {
+    throw new Error('sellAmount must be greater than 0: ' + sellAmount)
+  }
+
+  if (slippage < 0n) {
+    throw new Error('slippage must be non-negative: ' + slippage)
+  }
+
+  if (isSell) {
+    // For sell orders:
+    // 1 - (sellAmount - slippage) / sellAmount
+    // i.e: sellAmount=100, slippage=20
+    //    slippagePercent = 1 - (100-20) / 100 = 0.2
+    //    slippagePercent (in scale) = 1e6 - (1e6*(100-20)) / 100 = 200,000
+    //    slippagePercent = 200,000 / 1e6 = 0.2
+    const percentageInScale = SCALE - (SCALE * (sellAmount - slippage)) / sellAmount
+
+    return Number(percentageInScale) / Number(SCALE)
+  } else {
+    // For buy orders:
+    // ((sellAmount + slippage) / sellAmount) - 1
+    // i.e: feeAmount=5, sellAmount=100, slippage=20
+    //    slippagePercent = (100+20) / 100 - 1 = 0.2
+    //    slippagePercent (in scale) = (1e6*(100+20)) / 100 - 1e6 = 200,000
+    //    slippagePercent = 200,000 / 1e6 = 0.2
+    const percentageInScale = (SCALE * (sellAmount + slippage)) / sellAmount - SCALE
+
+    return Number(percentageInScale) / Number(SCALE)
+  }
+}


Reviews:
user: login: copilot-pull-request-reviewer[bot]
body: ## Pull Request Overview

This PR introduces volume slippage calculations into the overall slippage logic by summing fee and volume slippages, refactoring related functions for clarity and maintainability, and updating corresponding tests. The changes include new functions for computing slippage percentages and absolute slippages, reorganization of utility modules (moved from utils to utils/misc), and adjustments to import paths in several trading-related files.

### Reviewed Changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 3 comments.

<details>
<summary>Show a summary per file</summary>

| File                                         | Description                                                     |
| -------------------------------------------- | --------------------------------------------------------------- |
| src/trading/utils/slippage.ts                | Adds a new function for calculating slippage percentage.        |
| src/trading/utils/slippage.test.ts           | Introduces comprehensive tests for the slippage percent logic.    |
| src/trading/suggestSlippageFromVolume.ts       | Implements volume-based slippage computation.                    |
| src/trading/suggestSlippageFromVolume.test.ts  | Provides unit tests for volume slippage, including edge cases.      |
| src/trading/suggestSlippageFromFee.ts          | Implements fee-based slippage suggestion with error handling.      |
| src/trading/suggestSlippageFromFee.test.ts     | Adds tests for fee slippage calculation and error conditions.       |
| src/trading/suggestSlippageBps.ts              | Aggregates fee and volume slippages to produce final slippage in BPS.  |
| Various files under src/trading and src/common/utils | Update import paths from utils to utils/misc and minor parameter formatting. |
</details>





state: COMMENTED
author_association: NONE
submitted_at: 2025-05-15T09:27:58Z
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (6)</summary><blockquote>

<details>
<summary>src/trading/suggestSlippageFromVolume.test.ts (1)</summary><blockquote>

`97-97`: **Improve test description accuracy.**

The test description references `suggestSlippageBpsFromFee` but the function being tested is `suggestSlippageFromVolume`.

```diff
-        : `suggestSlippageBpsFromFee(sellAmountBeforeNetworkCosts=${sellBefore}, sellAmountAfterNetworkCosts=${sellAfter}, slippagePercent=${percentage}) ${expectedDescription}`
+        : `suggestSlippageFromVolume(sellAmountBeforeNetworkCosts=${sellBefore}, sellAmountAfterNetworkCosts=${sellAfter}, slippagePercent=${percentage}) ${expectedDescription}`
```

</blockquote></details>
<details>
<summary>src/trading/suggestSlippageFromVolume.ts (1)</summary><blockquote>

`1-29`: **Good implementation of volume-based slippage calculation**

The function effectively calculates slippage based on trade volume, properly handling both sell and buy orders by selecting the appropriate sell amount. The validation checks for negative sell amount and slippage percentage are appropriate.



Small grammar fix:
```diff
-    throw new Error('slippagePercent must be a positive: ' + slippagePercent)
+    throw new Error('slippagePercent must be positive: ' + slippagePercent)
```

</blockquote></details>
<details>
<summary>src/trading/utils/slippage.ts (1)</summary><blockquote>

`1-51`: **Well-implemented slippage percentage calculation with fixed-point arithmetic**

The function correctly implements the slippage percentage calculation for both sell and buy orders using scaled integer arithmetic to maintain precision without depending on external decimal libraries. The detailed comments with examples are helpful for understanding the formulas.



The comment on line 21 doesn't match the implementation:
```diff
-  // Return maximum slippage if the sellAmount after accounting for the fee is 0 or negative
+  // Check that the sellAmount after accounting for the fee is not negative
```

</blockquote></details>
<details>
<summary>src/trading/suggestSlippageFromFee.test.ts (3)</summary><blockquote>

`48-50`: **Consider renaming the `atoms` helper function for clarity**

The function `atoms` converts decimal numbers to their bigint representation scaled by 1e18. A more descriptive name like `decimalToAtoms` or `convertToAtoms` would make its purpose clearer to other developers.

```diff
-function atoms(amount: number) {
+function decimalToAtoms(amount: number) {
  return BigInt(amount * 1e18)
}
```

---

`72-72`: **Be cautious about potential precision loss when converting bigint to number**

Converting from `bigint` to `number` using `Number(result)` could lead to precision loss if the values exceed JavaScript's safe integer range (±2^53-1). While the current test values are small enough, this could be an issue with larger values.

Consider using string comparison or a more robust approach for comparing bigint values:

```diff
-expect(Number(result)).toBe(expected)
+expect(result.toString()).toBe(expected.toString())
```

Or if you prefer to keep using numbers for simpler test assertions, add a comment explaining that the values are expected to be within safe ranges.

---

`52-77`: **Consider using Jest's built-in test.each for better test isolation**

While your `assertCases` helper function is clean and well-structured, Jest provides a built-in `test.each` function that offers better test isolation and more descriptive failure messages.

Here's how you could refactor it:

```typescript
function assertCases(description: string, testCases: SuggestedFeeTest[]) {
  describe(description, () => {
    test.each(testCases)(
      '$description',
      ({ fee, factor, expected, description: testCaseDescription, only }) => {
        const shouldThrow = typeof expected === 'string';
        const params: SuggestSlippageFromFeeParams = {
          feeAmount: fee,
          multiplyingFactorPercent: factor,
        };
        
        if (shouldThrow) {
          expect(() => suggestSlippageFromFee(params)).toThrow(expected);
        } else {
          const result = suggestSlippageFromFee(params);
          expect(Number(result)).toBe(expected);
        }
      }
    );
  });
}
```

This would make individual test failures easier to identify in the test output.

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**
**Cache: Disabled due to data retention organization setting**
**Knowledge Base: Disabled due to data retention organization setting**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 39d948926d08455cd67fd6383f78ad59c91848eb and 7239a49816763c27e2c2a03934bdd1e3ff294979.

</details>

<details>
<summary>📒 Files selected for processing (19)</summary>

* `package.json` (1 hunks)
* `src/bridging/BridgingSdk/getQuoteWithBridge.ts` (6 hunks)
* `src/common/utils/math.ts` (2 hunks)
* `src/trading/getEthFlowTransaction.ts` (2 hunks)
* `src/trading/getPreSignTransaction.ts` (2 hunks)
* `src/trading/getQuote.ts` (1 hunks)
* `src/trading/index.ts` (1 hunks)
* `src/trading/postCoWProtocolTrade.ts` (1 hunks)
* `src/trading/postSwapOrder.ts` (1 hunks)
* `src/trading/suggestSlippageBps.ts` (2 hunks)
* `src/trading/suggestSlippageBpsFromFee.ts` (0 hunks)
* `src/trading/suggestSlippageFromFee.test.ts` (1 hunks)
* `src/trading/suggestSlippageFromFee.ts` (1 hunks)
* `src/trading/suggestSlippageFromVolume.test.ts` (1 hunks)
* `src/trading/suggestSlippageFromVolume.ts` (1 hunks)
* `src/trading/tradingSdk.ts` (5 hunks)
* `src/trading/utils/misc.ts` (3 hunks)
* `src/trading/utils/slippage.test.ts` (1 hunks)
* `src/trading/utils/slippage.ts` (1 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (1)</summary>

* src/trading/suggestSlippageBpsFromFee.ts

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (8)</summary>

<details>
<summary>src/trading/suggestSlippageFromFee.test.ts (1)</summary><blockquote>

<details>
<summary>src/trading/suggestSlippageFromFee.ts (2)</summary>

* `SuggestSlippageFromFeeParams` (3-15)
* `suggestSlippageFromFee` (21-36)

</details>

</blockquote></details>
<details>
<summary>src/trading/suggestSlippageFromVolume.test.ts (1)</summary><blockquote>

<details>
<summary>src/trading/suggestSlippageFromVolume.ts (2)</summary>

* `SuggestSlippageFromVolumeParams` (3-8)
* `suggestSlippageFromVolume` (13-29)

</details>

</blockquote></details>
<details>
<summary>src/trading/getEthFlowTransaction.ts (1)</summary><blockquote>

<details>
<summary>src/trading/types.ts (1)</summary>

* `PostTradeAdditionalParams` (227-247)

</details>

</blockquote></details>
<details>
<summary>src/trading/suggestSlippageFromFee.ts (1)</summary><blockquote>

<details>
<summary>src/common/utils/math.ts (1)</summary>

* `applyPercentage` (27-32)

</details>

</blockquote></details>
<details>
<summary>src/trading/suggestSlippageFromVolume.ts (1)</summary><blockquote>

<details>
<summary>src/common/utils/math.ts (1)</summary>

* `applyPercentage` (27-32)

</details>

</blockquote></details>
<details>
<summary>src/trading/utils/slippage.test.ts (1)</summary><blockquote>

<details>
<summary>src/trading/utils/slippage.ts (1)</summary>

* `getSlippagePercent` (11-51)

</details>

</blockquote></details>
<details>
<summary>src/trading/utils/misc.ts (1)</summary><blockquote>

<details>
<summary>src/trading/types.ts (2)</summary>

* `TradeParameters` (93-93)
* `LimitTradeParametersFromQuote` (107-109)

</details>

</blockquote></details>
<details>
<summary>src/trading/suggestSlippageBps.ts (4)</summary><blockquote>

<details>
<summary>src/trading/suggestSlippageFromFee.ts (1)</summary>

* `suggestSlippageFromFee` (21-36)

</details>
<details>
<summary>src/trading/suggestSlippageFromVolume.ts (1)</summary>

* `suggestSlippageFromVolume` (13-29)

</details>
<details>
<summary>src/trading/utils/slippage.ts (1)</summary>

* `getSlippagePercent` (11-51)

</details>
<details>
<summary>src/common/utils/math.ts (1)</summary>

* `percentageToBps` (13-16)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>🔇 Additional comments (33)</summary><blockquote>

<details>
<summary>src/common/utils/math.ts (2)</summary>

`1-2`: **Good addition of fixed-point scaling factors for precision.**

The addition of these constants provides a standardized way to perform fixed-point arithmetic with 6 decimal places of precision without relying on external Big Decimal libraries.

---

`28-28`: **Enhanced precision for fixed-point percentage calculations.**

This change improves the precision of calculations by using a fixed-point arithmetic approach:
1. Multiplies percentage by SCALE to get 6 decimal places of precision
2. Floors the result to handle potential floating-point issues
3. Converts to BigInt for compatibility with the value parameter
4. Divides by SCALE_BIGINT to normalize back after multiplication

The approach provides more accurate percentage calculations while maintaining compatibility with bigint operations, which is essential for financial calculations like slippage.

</details>
<details>
<summary>src/trading/postSwapOrder.ts (1)</summary>

`5-5`: **Import path updated to reflect utility restructuring.**

The import path was updated to point to the new location of the utility functions, which have been moved to a more organized structure. This is part of the broader restructuring of the codebase to better organize utility functions.

</details>
<details>
<summary>src/trading/getQuote.ts (1)</summary>

`25-25`: **Import path updated to reflect utility restructuring.**

The import path was updated to reference the new location of the utility functions, which have been moved to a more organized structure. This change is consistent with the reorganization across the codebase to better separate utility functions by their purpose.

</details>
<details>
<summary>package.json (1)</summary>

`3-3`: **Version increment for the new slippage calculation functionality.**

The package version has been incremented from RC.39 to RC.42, reflecting the changes in this PR that improve slippage calculation, enhance precision with fixed-point arithmetic, and reorganize utility functions.

</details>
<details>
<summary>src/trading/postCoWProtocolTrade.ts (2)</summary>

`8-8`: **Update import path for getIsEthFlowOrder**  
The import has been correctly updated to `'./utils/misc'` following the refactor of utility functions.

---

`16-16`: **Add trailing comma in function signature**  
A trailing comma has been added to the `additionalParams` parameter for consistency with other function signatures in the module.

</details>
<details>
<summary>src/trading/index.ts (1)</summary>

`23-23`: **Align export paths to new utils structure**  
Export statements have been updated to use `'./utils/misc'` instead of `'./utils'`, reflecting the reorganization of utility modules.

</details>
<details>
<summary>src/trading/getPreSignTransaction.ts (2)</summary>

`5-5`: **Import calculateGasMargin from misc utils**  
The import path for `calculateGasMargin` has been updated to `'./utils/misc'` in line with the new directory structure for utility functions.

---

`14-14`: **Add trailing comma to function parameters**  
A trailing comma was added after the `orderId` parameter to maintain consistency with the rest of the codebase’s function signatures.

</details>
<details>
<summary>src/trading/getEthFlowTransaction.ts (2)</summary>

`9-9`: **Update utility imports to misc**  
`adjustEthFlowOrderParams` and `calculateGasMargin` are now imported from the new `'./utils/misc'` path, matching the refactored utilities layout.

---

`18-18`: **Add trailing comma in function signature**  
Trailing comma added to `additionalParams` for consistent formatting across the trading module.

</details>
<details>
<summary>src/bridging/BridgingSdk/getQuoteWithBridge.ts (3)</summary>

`32-32`: **Correct import for getTradeParametersAfterQuote**  
Updated the import to `'../../trading/utils/misc'` to reflect the relocation of utility methods.

---

`67-67`: **Consistent use of trailing commas**  
Added trailing commas in the `getQuoteWithBridge` function signature (line 67) and the `log` call (line 88) to align with the project's style guidelines. 


Also applies to: 88-88

---

`122-123`: **Handle BigInt serialization in logs**  
The inclusion of `jsonWithBigintReplacer` as a `JSON.stringify` replacer ensures proper serialization of BigInt values when logging swap parameters.

</details>
<details>
<summary>src/trading/tradingSdk.ts (2)</summary>

`14-14`: **Import path updated correctly.**

The import path has been updated from `'./utils'` to `'./utils/misc'` to align with the file restructuring mentioned in the PR objectives.

---

`30-31`: **Trailing commas removed for consistency.**

Trailing commas have been consistently removed from method parameters and argument lists throughout the file for stylistic consistency.



Also applies to: 45-46, 63-64, 70-71, 77-78, 84-85, 91-92, 103-104, 105-106, 110-111

</details>
<details>
<summary>src/trading/suggestSlippageFromFee.ts (2)</summary>

`3-15`: **Well-documented interface with clear parameter descriptions.**

The interface clearly defines the parameters needed for fee-based slippage calculation, with helpful JSDoc comments explaining the purpose of each parameter.

---

`21-36`: **Function implementation is robust with proper validation.**

The function correctly:
1. Validates that fee amount is non-negative
2. Ensures the multiplying factor is positive
3. Uses `applyPercentage` for precise calculation

This implementation aligns with the PR objective of breaking slippage calculations into smaller, simpler units.

</details>
<details>
<summary>src/trading/suggestSlippageBps.ts (4)</summary>

`1-12`: **Good use of constants for slippage boundaries and multipliers.**

The constants provide clear configuration for:
- Minimum slippage (50 bps or 0.5%)
- Maximum slippage (10,000 bps or 100%)
- Fee multiplier (50%)
- Volume multiplier (0.5%)

This makes the code more maintainable and easier to adjust in the future.

---

`34-36`: **Safe conversion of fee amount to bigint.**

The code correctly extracts the fee amount from the quote response as a string and safely converts it to a bigint for arithmetic operations.

---

`37-52`: **Improved slippage calculation by combining fee and volume components.**

The implementation now correctly calculates:
1. Slippage from potential fee increases
2. Slippage from potential volume changes
3. Total slippage as the sum of both components

This addresses the PR objective of enhancing slippage calculation by considering both fee and volume factors.

---

`54-66`: **Comprehensive slippage bounds enforcement.**

The function now:
1. Converts absolute slippage to percentage using the specialized utility
2. Converts percentage to basis points
3. Clamps the result between minimum and maximum boundaries

This ensures the returned slippage value is always within reasonable limits while preserving precision through the calculation pipeline.

</details>
<details>
<summary>src/trading/suggestSlippageFromVolume.test.ts (3)</summary>

`15-52`: **Comprehensive test cases for sell orders.**

The tests cover:
- Multiple slippage percentages (0% to 100,000,000%)
- Different numerical scales including atoms (values scaled by 1e18)
- Error cases for invalid inputs

This thorough testing ensures the function works correctly across all expected scenarios for sell orders.

---

`54-84`: **Comprehensive test cases for buy orders.**

Similar to the sell order tests, these cover various percentages, numerical scales, and error cases, ensuring the function handles buy orders correctly.

---

`86-117`: **Well-structured test helpers improve maintainability.**

The test includes:
1. A helper to convert values to atoms scale (multiplied by 1e18)
2. A flexible test case generator that handles both expected values and expected errors

This approach makes adding new test cases straightforward and keeps test logic DRY.

</details>
<details>
<summary>src/trading/utils/misc.ts (4)</summary>

`1-6`: **Import paths updated to reflect reorganized project structure**

The import paths have been updated to use proper relative paths with additional directory levels, consistent with the project reorganization.

---

`7-18`: **Function signature updated with trailing comma**

The function signature has been updated with a trailing comma after the `quoteResponse` parameter, which is a consistent style change.

---

`32-66`: **Function signature updated with trailing comma**

The function signature for `mapQuoteAmountsAndCosts` has been updated with a trailing comma after the `mapper` parameter, maintaining consistent code style.

---

`87-96`: **Function signature updated with trailing comma**

The function signature for `adjustEthFlowOrderParams` has been updated with a trailing comma after the `params` parameter, maintaining consistent code style throughout the codebase.

</details>
<details>
<summary>src/trading/utils/slippage.test.ts (1)</summary>

`1-94`: **Comprehensive test suite for slippage percentage calculation**

This test suite thoroughly validates the `getSlippagePercent` function across multiple scenarios:
- Standard cases with various slippage values (0% to 10,000%)
- Error handling for negative inputs
- Precision with large values
- Both sell and buy order calculations

The use of a helper function to generate test cases reduces code duplication, and the dynamic test descriptions make it clear what's being tested in each case. Using `toBeCloseTo` with 6 decimal places is appropriate for floating-point comparisons.

</details>
<details>
<summary>src/trading/suggestSlippageFromFee.test.ts (2)</summary>

`11-20`: **Well-structured test cases covering various scenarios**

The test suites effectively cover different scenarios:
1. Different factor values (0% to 100,000,000%)
2. Decimal values represented as atoms
3. Edge cases for negative inputs

This comprehensive testing approach ensures the function behaves correctly across various inputs.



Also applies to: 22-28, 30-46

---

`61-61`: <details>
<summary>❌ Incorrect review comment</summary>

**Be cautious with the `only` flag in tests**

The use of `only` flag can be helpful during development, but it's easy to accidentally commit tests with `only` enabled, which would cause other tests to be skipped.

---

🏁 Script executed:

```shell
#!/bin/bash
# Check for any .only occurrences in test files
rg "\.only\(" "src/**/*.test.ts"
```

Length of output: 91

---

Let’s broaden the search to correctly catch any `only` flags in all test files:

---

🏁 Script executed:

```shell
#!/bin/bash
# Search for any `.only` usage in .test.ts files under src
rg "\.only" -g '*.test.ts' -n src
```

Length of output: 294

---



</details>

**Ignore parameterized `it.only` usage**

Our search confirms that `.only` only appears in conjunction with the `only` variable inside parameterized test loops—there are no accidental standalone `it.only` calls that would skip other tests.  
Affected files:
- src/trading/suggestSlippageFromVolume.test.ts: line 99  
- src/trading/utils/slippage.test.ts: line 70  
- src/trading/suggestSlippageFromFee.test.ts: line 61  

No action required. 

> Likely an incorrect or invalid review comment.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-15T09:28:13Z
user: login: shoom3301
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-19T11:49:33Z
user: login: alfetopito
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T09:58:45Z
user: login: anxolin
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T10:59:23Z
user: login: anxolin
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T11:09:11Z
user: login: anxolin
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T11:10:01Z
user: login: alfetopito
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-20T14:13:55Z

Review comments:
diff_hunk: @@ -1,3 +1,5 @@
+const SCALE = 10e6 // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
path: src/common/utils/math.ts
user: login: Copilot
body: The constant 'SCALE' is defined as 10e6 (i.e. 10,000,000) which conflicts with the intended 6-decimal precision used elsewhere (e.g. 10n ** 6n equals 1,000,000). Consider updating it to 1e6 (or 10e5) to maintain consistency.
```suggestion
const SCALE = 1e6 // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
```
created_at: 2025-05-15T09:27:57Z
author_association: NONE
diff_hunk: @@ -0,0 +1,29 @@
+import { applyPercentage } from 'src/common/utils/math'
+
+export interface SuggestSlippageFromVolumeParams {
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  isSell: boolean
+  slippagePercent: number
+}
+
+/**
+ * Return the absolute slippage in sell token for the traded amount
+ */
+export function suggestSlippageFromVolume(params: SuggestSlippageFromVolumeParams): bigint {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, isSell, slippagePercent } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Negative fees are not allowed
+  if (sellAmount < 0n) {
+    throw new Error('sellAmount cannot be negative: ' + sellAmount)
+  }
+
+  // Multiplying factor must be a valid percentage
+  if (slippagePercent < 0) {
+    throw new Error('slippagePercent must be a positive: ' + slippagePercent)
path: src/trading/suggestSlippageFromVolume.ts
user: login: Copilot
body: [nitpick] The error message 'slippagePercent must be a positive: ' may be misleading since 0 is a valid value. Consider changing it to 'slippagePercent must be non-negative: ' for clarity.
```suggestion
    throw new Error('slippagePercent must be non-negative: ' + slippagePercent)
```
created_at: 2025-05-15T09:27:58Z
author_association: NONE
diff_hunk: @@ -0,0 +1,36 @@
+import { applyPercentage } from 'src/common/utils/math'
+
+export interface SuggestSlippageFromFeeParams {
+  /**
+   * Fee amount in the sell token returned by the quote
+   */
+  feeAmount: bigint
+
+  /**
+   * The factor to multiply the fee amount by to get the suggested slippage.
+   *
+   * For example, if the factor is 50% it would calculate which slippage would allow the fee to increase by 50% and still go through.
+   */
+  multiplyingFactorPercent: number
+}
+
+/**
+ * Return the absolute slippage in the sell token that would allow the order to execute, even if the fee increases by the multiplying factor percent.
+ *
+ */
+export function suggestSlippageFromFee(params: SuggestSlippageFromFeeParams): bigint {
+  const { feeAmount, multiplyingFactorPercent } = params
+
+  // Negative fees are not allowed
+  if (feeAmount < 0n) {
+    throw new Error('Fee amount cannot be negative: ' + feeAmount)
+  }
+
+  // Multiplying factor must be a valid percentage
+  if (multiplyingFactorPercent < 0) {
+    throw new Error('multiplyingFactorPercent must be a positive: ' + multiplyingFactorPercent)
path: src/trading/suggestSlippageFromFee.ts
user: login: Copilot
body: [nitpick] The error message 'multiplyingFactorPercent must be a positive: ' could be improved for clarity since a zero value is acceptable. Consider revising it to 'multiplyingFactorPercent must be non-negative: '.
```suggestion
    throw new Error('multiplyingFactorPercent must be non-negative: ' + multiplyingFactorPercent)
```
created_at: 2025-05-15T09:27:58Z
author_association: NONE
diff_hunk: @@ -0,0 +1,29 @@
+import { applyPercentage } from 'src/common/utils/math'
+
+export interface SuggestSlippageFromVolumeParams {
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  isSell: boolean
+  slippagePercent: number
+}
+
+/**
+ * Return the absolute slippage in sell token for the traded amount
+ */
+export function suggestSlippageFromVolume(params: SuggestSlippageFromVolumeParams): bigint {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, isSell, slippagePercent } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Negative sell amounts are not allowed
+  if (sellAmount < 0n) {
+    throw new Error('sellAmount must be non-negative: ' + sellAmount)
+  }
path: src/trading/suggestSlippageFromVolume.ts
user: login: alfetopito
body: Can it be 0?

I'd say it must be positive
created_at: 2025-05-20T09:56:31Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,51 @@
+const SCALE = 10n ** 6n // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
+
+/**
+ * Get the slippage percentage for a given absolute slippage.
+ *
+ * Returns a percentage as a portion of 1 with 6 decimals of precision.
+ *
+ * @param params
+ * @returns
+ */
+export function getSlippagePercent(params: {
+  isSell: boolean
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  slippage: bigint
+}): number {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, slippage, isSell } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Check that the sellAmount after accounting for the fee is not negative
+  if (sellAmount <= 0n) {
+    throw new Error('sellAmount must be greater than 0: ' + sellAmount)
+  }
path: src/trading/utils/slippage.ts
user: login: alfetopito
body: Same here, sellAmount must be > 0
created_at: 2025-05-20T09:58:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,51 @@
+const SCALE = 10n ** 6n // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
+
+/**
+ * Get the slippage percentage for a given absolute slippage.
+ *
+ * Returns a percentage as a portion of 1 with 6 decimals of precision.
+ *
+ * @param params
+ * @returns
+ */
+export function getSlippagePercent(params: {
+  isSell: boolean
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  slippage: bigint
+}): number {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, slippage, isSell } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Check that the sellAmount after accounting for the fee is not negative
+  if (sellAmount <= 0n) {
+    throw new Error('sellAmount must be greater than 0: ' + sellAmount)
+  }
path: src/trading/utils/slippage.ts
user: login: anxolin
body: But this is asserting the `sellAmount` is positive, right? (in the other case, you were right that it was not enforced)
created_at: 2025-05-20T10:59:23Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,29 @@
+import { applyPercentage } from 'src/common/utils/math'
+
+export interface SuggestSlippageFromVolumeParams {
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  isSell: boolean
+  slippagePercent: number
+}
+
+/**
+ * Return the absolute slippage in sell token for the traded amount
+ */
+export function suggestSlippageFromVolume(params: SuggestSlippageFromVolumeParams): bigint {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, isSell, slippagePercent } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Negative sell amounts are not allowed
+  if (sellAmount < 0n) {
+    throw new Error('sellAmount must be non-negative: ' + sellAmount)
+  }
path: src/trading/suggestSlippageFromVolume.ts
user: login: anxolin
body: Yes, should be positive. Fixed https://github.com/cowprotocol/cow-sdk/pull/316
created_at: 2025-05-20T11:09:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,51 @@
+const SCALE = 10n ** 6n // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
+
+/**
+ * Get the slippage percentage for a given absolute slippage.
+ *
+ * Returns a percentage as a portion of 1 with 6 decimals of precision.
+ *
+ * @param params
+ * @returns
+ */
+export function getSlippagePercent(params: {
+  isSell: boolean
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  slippage: bigint
+}): number {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, slippage, isSell } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Check that the sellAmount after accounting for the fee is not negative
+  if (sellAmount <= 0n) {
+    throw new Error('sellAmount must be greater than 0: ' + sellAmount)
+  }
path: src/trading/utils/slippage.ts
user: login: anxolin
body: https://github.com/cowprotocol/cow-sdk/pull/316
created_at: 2025-05-20T11:10:01Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,51 @@
+const SCALE = 10n ** 6n // 6 decimal places of precision. Used to avoid depending on Big Decimal libraries
+
+/**
+ * Get the slippage percentage for a given absolute slippage.
+ *
+ * Returns a percentage as a portion of 1 with 6 decimals of precision.
+ *
+ * @param params
+ * @returns
+ */
+export function getSlippagePercent(params: {
+  isSell: boolean
+  sellAmountBeforeNetworkCosts: bigint
+  sellAmountAfterNetworkCosts: bigint
+  slippage: bigint
+}): number {
+  const { sellAmountBeforeNetworkCosts, sellAmountAfterNetworkCosts, slippage, isSell } = params
+
+  const sellAmount = isSell ? sellAmountAfterNetworkCosts : sellAmountBeforeNetworkCosts
+
+  // Check that the sellAmount after accounting for the fee is not negative
+  if (sellAmount <= 0n) {
+    throw new Error('sellAmount must be greater than 0: ' + sellAmount)
+  }
path: src/trading/utils/slippage.ts
user: login: alfetopito
body: You are right, I thought it was like the previous case for some reason.
created_at: 2025-05-20T14:13:55Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-05-14T21:38:04Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

This update introduces new slippage calculation utilities and tests, reorganizes import paths for trading utilities, and refines slippage logic for trading operations. It removes the old fee-based slippage module, replaces it with more granular functions, and enhances precision using fixed-point arithmetic. Several function signatures are updated for consistency, and comprehensive tests are added.

## Changes

| File(s)                                                                                   | Change Summary |
|-------------------------------------------------------------------------------------------|---------------|
| `package.json`                                                                            | Updated version from `6.0.0-RC.40` to `6.0.0-RC.42`. |
| `src/common/utils/math.ts`                                                                | Added fixed-point constants and updated `applyPercentage` for higher precision. |
| `src/bridging/BridgingSdk/getQuoteWithBridge.ts`<br>`src/trading/getEthFlowTransaction.ts`<br>`src/trading/getPreSignTransaction.ts`<br>`src/trading/getQuote.ts`<br>`src/trading/postCoWProtocolTrade.ts`<br>`src/trading/postSwapOrder.ts`<br>`src/trading/tradingSdk.ts`<br>`src/trading/index.ts` | Updated import paths from `./utils` to `./utils/misc` and adjusted trailing commas in function signatures. |
| `src/trading/suggestSlippageBps.ts`                                                       | Refactored to aggregate slippage from fee and volume, enforce min/max bounds, and use new utility functions. |
| `src/trading/suggestSlippageBpsFromFee.ts`                                                | Deleted. Removed old fee-based slippage calculation logic and related exports. |
| `src/trading/suggestSlippageBpsFromFee.test.ts`                                           | Deleted. Removed tests for the old fee-based slippage module. |
| `src/trading/suggestSlippageFromFee.ts`                                                   | Added new module for calculating absolute slippage from fee increases with input validation. |
| `src/trading/suggestSlippageFromFee.test.ts`                                              | Added comprehensive tests validating `suggestSlippageFromFee` behavior and input handling. |
| `src/trading/suggestSlippageFromVolume.ts`                                                | Added new module for calculating absolute slippage from volume/price changes with input validation. |
| `src/trading/suggestSlippageFromVolume.test.ts`                                          | Added comprehensive tests validating `suggestSlippageFromVolume` behavior and input handling. |
| `src/trading/utils/misc.ts`                                                               | Updated function signatures to add trailing commas; reorganized import paths. |
| `src/trading/utils/slippage.ts`                                                           | Added new utility function `getSlippagePercent` for precise slippage percentage calculation. |
| `src/trading/utils/slippage.test.ts`                                                     | Added tests verifying correctness and error handling for `getSlippagePercent`. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant TradingSDK
    participant SlippageUtils

    User->>TradingSDK: Request trade with parameters
    TradingSDK->>SlippageUtils: suggestSlippageBps(params)
    SlippageUtils->>SlippageUtils: suggestSlippageFromFee(fee, factor)
    SlippageUtils->>SlippageUtils: suggestSlippageFromVolume(sellAmounts, slippagePercent)
    SlippageUtils->>SlippageUtils: getSlippagePercent(...)
    SlippageUtils-->>TradingSDK: Aggregated slippage (bps)
    TradingSDK-->>User: Trade quote/transaction with slippage
```

## Poem

> In the meadow of code, where slippage is sly,  
> Rabbits now measure with a keener eye.  
> Old ways are gone, new math is precise,  
> With tests that ensure the numbers are nice.  
> Hopping through decimals, scaling with glee—  
> This release brings clarity, as crisp as can be!  
> 🐇✨

<!-- walkthrough_end -->

<!-- announcements_start -->

> [!NOTE]
> <details>
> <summary>⚡️ AI Code Reviews for VS Code, Cursor, Windsurf</summary>
> 
> CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
> Learn more [here](http://coderabbit.ai/ide).
> 
> </details>

---

> [!NOTE]
> <details>
> <summary>⚡️ Faster reviews with caching</summary>
> 
> CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure `Review - Disable Cache` at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the `Data Retention` setting under your Organization Settings.
> Enjoy the performance boost—your workflow just got faster.
> 
> </details>

<!-- announcements_end -->

---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**
**Cache: Disabled due to data retention organization setting**
**Knowledge Base: Disabled due to data retention organization setting**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between fb0cd539847289142201ac7076d44c668b4c1bd0 and 08c4e140686777bb40fefd356d8dc3670edf521d.

</details>

<details>
<summary>📒 Files selected for processing (20)</summary>

* `package.json` (1 hunks)
* `src/bridging/BridgingSdk/getQuoteWithBridge.ts` (1 hunks)
* `src/common/utils/math.ts` (2 hunks)
* `src/trading/getEthFlowTransaction.ts` (2 hunks)
* `src/trading/getPreSignTransaction.ts` (2 hunks)
* `src/trading/getQuote.ts` (1 hunks)
* `src/trading/index.ts` (1 hunks)
* `src/trading/postCoWProtocolTrade.ts` (1 hunks)
* `src/trading/postSwapOrder.ts` (1 hunks)
* `src/trading/suggestSlippageBps.ts` (2 hunks)
* `src/trading/suggestSlippageBpsFromFee.test.ts` (0 hunks)
* `src/trading/suggestSlippageBpsFromFee.ts` (0 hunks)
* `src/trading/suggestSlippageFromFee.test.ts` (1 hunks)
* `src/trading/suggestSlippageFromFee.ts` (1 hunks)
* `src/trading/suggestSlippageFromVolume.test.ts` (1 hunks)
* `src/trading/suggestSlippageFromVolume.ts` (1 hunks)
* `src/trading/tradingSdk.ts` (5 hunks)
* `src/trading/utils/misc.ts` (3 hunks)
* `src/trading/utils/slippage.test.ts` (1 hunks)
* `src/trading/utils/slippage.ts` (1 hunks)

</details>

<details>
<summary>💤 Files with no reviewable changes (2)</summary>

* src/trading/suggestSlippageBpsFromFee.test.ts
* src/trading/suggestSlippageBpsFromFee.ts

</details>

<details>
<summary>✅ Files skipped from review due to trivial changes (2)</summary>

* src/trading/index.ts
* package.json

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (16)</summary>

* src/trading/getQuote.ts
* src/trading/postSwapOrder.ts
* src/trading/postCoWProtocolTrade.ts
* src/bridging/BridgingSdk/getQuoteWithBridge.ts
* src/trading/getPreSignTransaction.ts
* src/common/utils/math.ts
* src/trading/tradingSdk.ts
* src/trading/utils/slippage.ts
* src/trading/suggestSlippageFromFee.test.ts
* src/trading/suggestSlippageFromFee.ts
* src/trading/suggestSlippageFromVolume.test.ts
* src/trading/suggestSlippageBps.ts
* src/trading/utils/slippage.test.ts
* src/trading/getEthFlowTransaction.ts
* src/trading/suggestSlippageFromVolume.ts
* src/trading/utils/misc.ts

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (4)</summary>

* GitHub Check: test
* GitHub Check: Build Package
* GitHub Check: eslint
* GitHub Check: test

</details>

</details>
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=cowprotocol/cow-sdk&utm_content=313):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: anxolin
created_at: 2025-05-14T21:53:01Z
body: @coderabbitai review
author_association: CONTRIBUTOR
user: login: coderabbitai[bot]
created_at: 2025-05-14T21:53:50Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
<details>
<summary>✅ Actions performed</summary>

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.

</details>
author_association: CONTRIBUTOR
user: login: socket-security[bot]
created_at: 2025-05-14T21:55:56Z
body: **Review the following changes in direct dependencies.** Learn more about [Socket for GitHub](https://socket.dev?utm_medium=gh).

<table>
<thead>
<tr>
<th>Diff</th>
<th width="200px">Package</th>
<th align="left" width="100px">Supply Chain<br/>Security</th>
<th align="left" width="100px">Vulnerability</th>
<th align="left" width="100px">Quality</th>
<th align="left" width="100px">Maintenance</th>
<th align="left" width="100px">License</th>
</tr>
</thead>
<tbody>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921207570"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921207570">node-releases@​2.0.19</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921207570"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921207570"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921207570"><img src="https://github-app-statics.socket.dev/score-41.svg" title="Quality" width="40" height="40" alt="41"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921207570"><img src="https://github-app-statics.socket.dev/score-79.svg" title="Maintenance" width="40" height="40" alt="79"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921207570"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=12804"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=12804">safer-buffer@​2.1.2</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=12804"><img src="https://github-app-statics.socket.dev/score-67.svg" title="Supply Chain Security" width="40" height="40" alt="67"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=12804"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=12804"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Quality" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=12804"><img src="https://github-app-statics.socket.dev/score-51.svg" title="Maintenance" width="40" height="40" alt="51"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=12804"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=30294"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=30294">array-flatten@​2.1.2</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=30294"><img src="https://github-app-statics.socket.dev/score-67.svg" title="Supply Chain Security" width="40" height="40" alt="67"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=30294"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=30294"><img src="https://github-app-statics.socket.dev/score-82.svg" title="Quality" width="40" height="40" alt="82"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=30294"><img src="https://github-app-statics.socket.dev/score-51.svg" title="Maintenance" width="40" height="40" alt="51"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=30294"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13119"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13119">path-parse@​1.0.7</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13119"><img src="https://github-app-statics.socket.dev/score-67.svg" title="Supply Chain Security" width="40" height="40" alt="67"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13119"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13119"><img src="https://github-app-statics.socket.dev/score-78.svg" title="Quality" width="40" height="40" alt="78"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13119"><img src="https://github-app-statics.socket.dev/score-51.svg" title="Maintenance" width="40" height="40" alt="51"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13119"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921713089"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921713089">side-channel@​1.1.0</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921713089"><img src="https://github-app-statics.socket.dev/score-66.svg" title="Supply Chain Security" width="40" height="40" alt="66"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921713089"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921713089"><img src="https://github-app-statics.socket.dev/score-86.svg" title="Quality" width="40" height="40" alt="86"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921713089"><img src="https://github-app-statics.socket.dev/score-52.svg" title="Maintenance" width="40" height="40" alt="52"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15921713089"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13429"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13429">function-bind@​1.1.1</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13429"><img src="https://github-app-statics.socket.dev/score-67.svg" title="Supply Chain Security" width="40" height="40" alt="67"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13429"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13429"><img src="https://github-app-statics.socket.dev/score-83.svg" title="Quality" width="40" height="40" alt="83"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13429"><img src="https://github-app-statics.socket.dev/score-52.svg" title="Maintenance" width="40" height="40" alt="52"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13429"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13054"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13054">safe-buffer@​5.2.1</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13054"><img src="https://github-app-statics.socket.dev/score-67.svg" title="Supply Chain Security" width="40" height="40" alt="67"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13054"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13054"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Quality" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13054"><img src="https://github-app-statics.socket.dev/score-52.svg" title="Maintenance" width="40" height="40" alt="52"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13054"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=31113"><img src="https://github-app-statics.socket.dev/diff-updated.svg" title="Updated" alt="Updated" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=31113">is-core-module@​2.14.0 ⏵ 2.11.0</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=31113"><img src="https://github-app-statics.socket.dev/score-67.svg" title="Supply Chain Security" width="40" height="40" alt="67"></a> <sup>+1</sup></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=31113"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=31113"><img src="https://github-app-statics.socket.dev/score-80.svg" title="Quality" width="40" height="40" alt="80"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=31113"><img src="https://github-app-statics.socket.dev/score-54.svg" title="Maintenance" width="40" height="40" alt="54"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=31113"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20596"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20596">detect-node@​2.1.0</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20596"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20596"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20596"><img src="https://github-app-statics.socket.dev/score-60.svg" title="Quality" width="40" height="40" alt="60"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20596"><img src="https://github-app-statics.socket.dev/score-76.svg" title="Maintenance" width="40" height="40" alt="76"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20596"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577995"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577995">@​webassemblyjs/​ieee754@​1.13.2</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577995"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577995"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577995"><img src="https://github-app-statics.socket.dev/score-61.svg" title="Quality" width="40" height="40" alt="61"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577995"><img src="https://github-app-statics.socket.dev/score-80.svg" title="Maintenance" width="40" height="40" alt="80"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577995"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577990"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577990">@​webassemblyjs/​helper-api-error@​1.13.2</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577990"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577990"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577990"><img src="https://github-app-statics.socket.dev/score-61.svg" title="Quality" width="40" height="40" alt="61"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577990"><img src="https://github-app-statics.socket.dev/score-80.svg" title="Maintenance" width="40" height="40" alt="80"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577990"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20909"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20909">@​types/​mime@​3.0.1</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20909"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20909"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20909"><img src="https://github-app-statics.socket.dev/score-62.svg" title="Quality" width="40" height="40" alt="62"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20909"><img src="https://github-app-statics.socket.dev/score-76.svg" title="Maintenance" width="40" height="40" alt="76"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=20909"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581253"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581253">@​webassemblyjs/​wasm-opt@​1.14.1</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581253"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581253"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581253"><img src="https://github-app-statics.socket.dev/score-62.svg" title="Quality" width="40" height="40" alt="62"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581253"><img src="https://github-app-statics.socket.dev/score-79.svg" title="Maintenance" width="40" height="40" alt="79"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581253"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13251"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13251">core-util-is@​1.0.3</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13251"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13251"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13251"><img src="https://github-app-statics.socket.dev/score-63.svg" title="Quality" width="40" height="40" alt="63"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13251"><img src="https://github-app-statics.socket.dev/score-76.svg" title="Maintenance" width="40" height="40" alt="76"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=13251"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581244"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581244">@​webassemblyjs/​helper-buffer@​1.14.1</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581244"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581244"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581244"><img src="https://github-app-statics.socket.dev/score-63.svg" title="Quality" width="40" height="40" alt="63"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581244"><img src="https://github-app-statics.socket.dev/score-79.svg" title="Maintenance" width="40" height="40" alt="79"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910581244"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr><td align="center"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577992"><img src="https://github-app-statics.socket.dev/diff-added.svg" title="Added" alt="Added" width="20" height="20"></a></td><td><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577992">@​webassemblyjs/​helper-numbers@​1.13.2</a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577992"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Supply Chain Security" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577992"><img src="https://github-app-statics.socket.dev/score-100.svg" title="Vulnerability" width="40" height="40" alt="100"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577992"><img src="https://github-app-statics.socket.dev/score-63.svg" title="Quality" width="40" height="40" alt="63"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577992"><img src="https://github-app-statics.socket.dev/score-79.svg" title="Maintenance" width="40" height="40" alt="79"></a></td><td align="left"><a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies&dependency_item_key=15910577992"><img src="https://github-app-statics.socket.dev/score-100.svg" title="License" width="40" height="40" alt="100"></a></td></tr>
<tr>
<td colspan="7" align="center" height="50px">
<a href="https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies">See 217 more rows in the dashboard</a>
</td>
</tbody>
</table>

[View full report](https://socket.dev/dashboard/org/cowprotocol/diff/40c87fc8-940e-4c97-a525-15425cb68cbb/fd685659-ba04-455d-b1cb-dee535f9fca6?tab=dependencies)

<!-- overview-comment -->
author_association: NONE
user: login: coveralls
created_at: 2025-05-14T22:02:47Z
body: 
[![Coverage Status](https://coveralls.io/builds/73753529/badge)](https://coveralls.io/builds/73753529)

coverage: 77.449% (+0.4%) from 77.017%
when pulling **08c4e140686777bb40fefd356d8dc3670edf521d on slippage-calculation-vol**
into **5208521e2960edc408746c13ebc3c3ea2f271700 on main**.

author_association: COLLABORATOR
user: login: anxolin
created_at: 2025-05-15T09:25:16Z
body: @coderabbitai review
author_association: CONTRIBUTOR
user: login: coderabbitai[bot]
created_at: 2025-05-15T09:25:21Z
body: <!-- This is an auto-generated reply by CodeRabbit -->
<details>
<summary>✅ Actions performed</summary>

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.

</details>
author_association: CONTRIBUTOR