Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "3.0.1",
"private": true,
"license": "BSD-3-Clause",
"packageManager": "pnpm@10.18.0",
"packageManager": "pnpm@10.19.0",
"engines": {
"node": "24.x"
},
Expand Down Expand Up @@ -63,9 +63,9 @@
"@aave/math-utils": "1.38.0",
"@aave/react": "0.10.0",
"@amplitude/analytics-browser": "^2.13.0",
"@cowprotocol/cow-sdk": "9.2.7",
"@cowprotocol/sdk-ethers-v5-adapter": "0.4.11",
"@cowprotocol/sdk-flash-loans": "3.3.4",
"@cowprotocol/cow-sdk": "9.2.21",
"@cowprotocol/sdk-ethers-v5-adapter": "0.4.21",
"@cowprotocol/sdk-flash-loans": "4.0.0",
"@emotion/cache": "11.10.3",
"@emotion/react": "11.10.4",
"@emotion/server": "latest",
Expand Down
132 changes: 66 additions & 66 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@ minimumReleaseAge: 10080
minimumReleaseAgeExclude:
- '@aave/*'
- '@aave-dao/*'
# TODO: cow-sdk release from 2026-10-13, remove once it clears the 7-day window on 2026-10-20

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

New exclusions bypass the 7-day release quarantine for ten CoW packages
medium · security
The diff adds ten exact @cowprotocol/* versions to minimumReleaseAgeExclude. The TODO says these versions were published on 2026-10-13, so they are new today. The exclusion turns off the supply-chain quarantine for packages that build order data and transaction targets in signing flows. If one of these releases is malicious, nothing delays installs until the community finds the problem. The exact version pins and the TODO limit the exposure, but nothing enforces removal after 2026-10-20. Reviewer confidence: high that the control is bypassed. Reviewer confidence is lower that a compromise is likely.
Why this severity: The diff disables an active supply-chain control for wallet-signing dependencies. Exact version pins and a short time window reduce the risk. An attacker must also control one of these specific releases.
How it is reached: An attacker compromises a CoW npm publisher and ships one of these exact versions with malicious code. CI and developers install it at once because the exclusion skips minimumReleaseAge. The code runs at build time or in the browser. It changes order data or transaction targets, and the user signs a request that drains funds.
Suggested fix: Wait until the versions clear the 7-day window, then merge without the exclusions. The PR is still a draft, so this costs little. If the bypass must stay, verify the lockfile integrity hashes against the upstream release artifacts. Also add a CI check that fails after 2026-10-20 while these entries remain.
Review harness · reply here to accept or reject this finding

- '@cowprotocol/cow-sdk@9.2.21'
- '@cowprotocol/sdk-app-data@6.0.11'
- '@cowprotocol/sdk-common@0.14.5'
- '@cowprotocol/sdk-config@2.10.0'
- '@cowprotocol/sdk-contracts-ts@3.7.5'
- '@cowprotocol/sdk-ethers-v5-adapter@0.4.21'
- '@cowprotocol/sdk-flash-loans@4.0.0'
- '@cowprotocol/sdk-order-book@4.3.4'
- '@cowprotocol/sdk-order-signing@1.1.20'
- '@cowprotocol/sdk-trading@2.7.8'

# Build-script allowlist. pnpm 10 blocks all dependency install/postinstall
# scripts by default; only packages listed here may run them. This is the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { OrderStatus, SupportedChainId } from '@cowprotocol/cow-sdk';
import { OrderStatus } from '@cowprotocol/cow-sdk';
import { Trans } from '@lingui/macro';
import { useQueryClient } from '@tanstack/react-query';
import { Interface } from 'ethers/lib/utils';
Expand All @@ -16,7 +16,7 @@ import { useRootStore } from 'src/store/root';
import { getErrorTextFromError, TxAction } from 'src/ui-config/errorMapping';
import { updateCowOrderStatus } from 'src/utils/swapAdapterHistory';

import { ADAPTER_FACTORY } from '../Swap/constants/cow.constants';
import { LEGACY_ADAPTER_FACTORY } from '../Swap/constants/cow.constants';
import { TxActionsWrapper } from '../TxActionsWrapper';

interface CancelAdapterOrderActionsProps {
Expand Down Expand Up @@ -59,11 +59,8 @@ export const CancelAdapterOrderActions = ({

const adapterInterface = new Interface(ADAPTER_ABI);

const factoryAddress = ADAPTER_FACTORY[cowOrder.chainId as SupportedChainId];

if (!factoryAddress) {
throw new Error('Factory address not found for this chain');
}
// An instance is only cancelled on the factory that created it.
const factoryAddress = cowSwapOrder.adapterFactoryAddress ?? LEGACY_ADAPTER_FACTORY;

const data = adapterInterface.encodeFunctionData('cancelInstance', [
cowSwapOrder.adapterInstanceAddress,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { normalize } from '@aave/math-utils';
import { getOrderToSign, LimitTradeParameters, OrderKind, OrderStatus } from '@cowprotocol/cow-sdk';
import {
getOrderToSign,
LimitTradeParameters,
OrderKind,
OrderStatus,
SupportedChainId,
} from '@cowprotocol/cow-sdk';
import { AaveFlashLoanType, HASH_ZERO } from '@cowprotocol/sdk-flash-loans';
import { Trans } from '@lingui/macro';
import { Dispatch, useEffect, useMemo, useState } from 'react';
Expand All @@ -13,7 +19,7 @@ import { saveCowOrderToUserHistory } from 'src/utils/swapAdapterHistory';
import { useShallow } from 'zustand/react/shallow';

import { TrackAnalyticsHandlers } from '../../analytics/useTrackAnalytics';
import { COW_PARTNER_FEE } from '../../constants/cow.constants';
import { ADAPTER_FACTORY, COW_PARTNER_FEE } from '../../constants/cow.constants';
import { APP_CODE_PER_SWAP_TYPE } from '../../constants/shared.constants';
import {
addOrderTypeToAppData,
Expand Down Expand Up @@ -304,6 +310,7 @@ export const CollateralSwapActionsViaCowAdapters = ({
decimals: state.buyAmountToken.decimals,
},
adapterInstanceAddress: instanceAddress,
adapterFactoryAddress: ADAPTER_FACTORY[state.chainId as SupportedChainId],
usedAdapter: true, // CollateralSwap via adapters always uses adapter (flashloan)
srcAmount: state.sellAmountBigInt.toString(),
destAmount: state.buyAmountBigInt.toString(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { normalize } from '@aave/math-utils';
import { getOrderToSign, LimitTradeParameters, OrderKind, OrderStatus } from '@cowprotocol/cow-sdk';
import {
getOrderToSign,
LimitTradeParameters,
OrderKind,
OrderStatus,
SupportedChainId,
} from '@cowprotocol/cow-sdk';
import { AaveFlashLoanType, HASH_ZERO } from '@cowprotocol/sdk-flash-loans';
import { Trans } from '@lingui/macro';
import { Dispatch, useEffect, useMemo, useState } from 'react';
Expand All @@ -14,7 +20,7 @@ import { zeroAddress } from 'viem';
import { useShallow } from 'zustand/react/shallow';

import { TrackAnalyticsHandlers } from '../../analytics/useTrackAnalytics';
import { COW_PARTNER_FEE } from '../../constants/cow.constants';
import { ADAPTER_FACTORY, COW_PARTNER_FEE } from '../../constants/cow.constants';
import { APP_CODE_PER_SWAP_TYPE } from '../../constants/shared.constants';
import {
addOrderTypeToAppData,
Expand Down Expand Up @@ -331,6 +337,7 @@ export const DebtSwapActionsViaCoW = ({
decimals: state.buyAmountToken.decimals,
},
adapterInstanceAddress: instanceAddress,
adapterFactoryAddress: ADAPTER_FACTORY[state.chainId as SupportedChainId],
usedAdapter: true, // DebtSwap always uses adapter
srcAmount: state.sellAmountBigInt.toString(),
destAmount: state.buyAmountBigInt.toString(),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { normalize } from '@aave/math-utils';
import { getOrderToSign, LimitTradeParameters, OrderKind, OrderStatus } from '@cowprotocol/cow-sdk';
import {
getOrderToSign,
LimitTradeParameters,
OrderKind,
OrderStatus,
SupportedChainId,
} from '@cowprotocol/cow-sdk';
import { AaveFlashLoanType, HASH_ZERO } from '@cowprotocol/sdk-flash-loans';
import { Trans } from '@lingui/macro';
import { Dispatch, useEffect, useMemo, useState } from 'react';
Expand All @@ -13,7 +19,7 @@ import { saveCowOrderToUserHistory } from 'src/utils/swapAdapterHistory';
import { useShallow } from 'zustand/react/shallow';

import { TrackAnalyticsHandlers } from '../../analytics/useTrackAnalytics';
import { COW_PARTNER_FEE } from '../../constants/cow.constants';
import { ADAPTER_FACTORY, COW_PARTNER_FEE } from '../../constants/cow.constants';
import { APP_CODE_PER_SWAP_TYPE } from '../../constants/shared.constants';
import {
addOrderTypeToAppData,
Expand Down Expand Up @@ -329,6 +335,7 @@ export const RepayWithCollateralActionsViaCoW = ({
decimals: state.buyAmountToken.decimals,
},
adapterInstanceAddress: instanceAddress,
adapterFactoryAddress: ADAPTER_FACTORY[state.chainId as SupportedChainId],
usedAdapter: true, // RepayWithCollateral always uses adapter
srcAmount: state.sellAmountBigInt.toString(),
destAmount: state.buyAmountBigInt.toString(),
Expand Down
Loading
Loading