diff --git a/src/components/transactions/Swap/actions/CollateralSwap/CollateralSwapActionsViaCoWAdapters.tsx b/src/components/transactions/Swap/actions/CollateralSwap/CollateralSwapActionsViaCoWAdapters.tsx index 05cf50d702..ee82e3e28d 100644 --- a/src/components/transactions/Swap/actions/CollateralSwap/CollateralSwapActionsViaCoWAdapters.tsx +++ b/src/components/transactions/Swap/actions/CollateralSwap/CollateralSwapActionsViaCoWAdapters.tsx @@ -198,7 +198,11 @@ export const CollateralSwapActionsViaCowAdapters = ({ kind: state.processedSide === 'buy' ? OrderKind.BUY : OrderKind.SELL, validTo, slippageBps: state.orderType == OrderType.MARKET ? Number(state.slippage) * 100 : undefined, - partnerFee: COW_PARTNER_FEE(state.sellAmountToken.symbol, state.buyAmountToken.symbol), + partnerFee: COW_PARTNER_FEE( + state.sellAmountToken.symbol, + state.buyAmountToken.symbol, + state.swapType + ), }; const orderToSign = getOrderToSign( diff --git a/src/components/transactions/Swap/actions/DebtSwap/DebtSwapActionsViaCoW.tsx b/src/components/transactions/Swap/actions/DebtSwap/DebtSwapActionsViaCoW.tsx index 16a32e33a3..1487130d56 100644 --- a/src/components/transactions/Swap/actions/DebtSwap/DebtSwapActionsViaCoW.tsx +++ b/src/components/transactions/Swap/actions/DebtSwap/DebtSwapActionsViaCoW.tsx @@ -220,7 +220,11 @@ export const DebtSwapActionsViaCoW = ({ quoteId: isCowProtocolRates(state.swapRate) ? state.swapRate?.quoteId : undefined, validTo, slippageBps: state.orderType == OrderType.MARKET ? Number(state.slippage) * 100 : undefined, - partnerFee: COW_PARTNER_FEE(state.sellAmountToken.symbol, state.buyAmountToken.symbol), + partnerFee: COW_PARTNER_FEE( + state.sellAmountToken.symbol, + state.buyAmountToken.symbol, + state.swapType + ), }; const orderToSign = getOrderToSign( diff --git a/src/components/transactions/Swap/actions/RepayWithCollateral/RepayWithCollateralActionsViaCoW.tsx b/src/components/transactions/Swap/actions/RepayWithCollateral/RepayWithCollateralActionsViaCoW.tsx index 715e66d713..336b16da98 100644 --- a/src/components/transactions/Swap/actions/RepayWithCollateral/RepayWithCollateralActionsViaCoW.tsx +++ b/src/components/transactions/Swap/actions/RepayWithCollateral/RepayWithCollateralActionsViaCoW.tsx @@ -218,7 +218,11 @@ export const RepayWithCollateralActionsViaCoW = ({ quoteId: isCowProtocolRates(state.swapRate) ? state.swapRate?.quoteId : undefined, validTo, slippageBps: state.orderType == OrderType.MARKET ? Number(state.slippage) * 100 : undefined, - partnerFee: COW_PARTNER_FEE(state.sellAmountToken.symbol, state.buyAmountToken.symbol), + partnerFee: COW_PARTNER_FEE( + state.sellAmountToken.symbol, + state.buyAmountToken.symbol, + state.swapType + ), }; const orderToSign = getOrderToSign( diff --git a/src/components/transactions/Swap/actions/SwapActions/SwapActionsViaCoW.tsx b/src/components/transactions/Swap/actions/SwapActions/SwapActionsViaCoW.tsx index f6743a4abe..3e2dcca891 100644 --- a/src/components/transactions/Swap/actions/SwapActions/SwapActionsViaCoW.tsx +++ b/src/components/transactions/Swap/actions/SwapActions/SwapActionsViaCoW.tsx @@ -184,6 +184,7 @@ export const SwapActionsViaCoW = ({ smartSlippage, appCode, state.orderType, + params.swapType, state.swapRate.quoteId ); const txWithGasEstimation = await estimateGasLimit(ethFlowTx, state.chainId); @@ -218,6 +219,7 @@ export const SwapActionsViaCoW = ({ appCode, orderType: state.orderType, validTo, + swapType: params.swapType, }); const calculatedOrderId = await calculateUniqueOrderId(state.chainId, unsignerOrder); @@ -230,7 +232,8 @@ export const SwapActionsViaCoW = ({ slippageBps, smartSlippage, state.orderType, - APP_CODE_PER_SWAP_TYPE[params.swapType] + APP_CODE_PER_SWAP_TYPE[params.swapType], + params.swapType ) ), state.chainId @@ -286,6 +289,7 @@ export const SwapActionsViaCoW = ({ appCode, orderBookQuote: state.swapRate?.orderBookQuote, orderType: state.orderType, + swapType: params.swapType, kind: state.orderType === OrderType.MARKET ? OrderKind.SELL @@ -331,6 +335,7 @@ export const SwapActionsViaCoW = ({ slippageBps, smartSlippage, orderType: state.orderType, + swapType: params.swapType, kind: state.orderType === OrderType.MARKET ? OrderKind.SELL diff --git a/src/components/transactions/Swap/constants/cow.constants.ts b/src/components/transactions/Swap/constants/cow.constants.ts index 0ea41ff57c..63ec4696e2 100644 --- a/src/components/transactions/Swap/constants/cow.constants.ts +++ b/src/components/transactions/Swap/constants/cow.constants.ts @@ -145,10 +145,29 @@ export const COW_PROTOCOL_ETH_FLOW_ADDRESS_BY_ENV = (env: CowEnv) => { export const COW_CREATE_ORDER_ABI = 'function createOrder((address,address,uint256,uint256,bytes32,uint256,uint32,bool,int64)) returns (bytes32)'; -export const COW_PARTNER_FEE = (tokenFromSymbol: string, tokenToSymbol: string) => ({ - volumeBps: getAssetGroup(tokenFromSymbol) == getAssetGroup(tokenToSymbol) ? 15 : 25, - recipient: COW_EVM_RECIPIENT, -}); +const DEFAULT_PARTNER_FEE_SAME_GROUP_BPS = 15; +const DEFAULT_PARTNER_FEE_CROSS_GROUP_BPS = 25; +const PARTNER_FEE_BPS_BY_SWAP_TYPE: Partial> = { + [SwapType.DebtSwap]: 0, +}; + +export const COW_PARTNER_FEE = ( + tokenFromSymbol: string, + tokenToSymbol: string, + swapType?: SwapType +) => { + const swapTypeBps = swapType !== undefined ? PARTNER_FEE_BPS_BY_SWAP_TYPE[swapType] : undefined; + + const defaultBps = + getAssetGroup(tokenFromSymbol) == getAssetGroup(tokenToSymbol) + ? DEFAULT_PARTNER_FEE_SAME_GROUP_BPS + : DEFAULT_PARTNER_FEE_CROSS_GROUP_BPS; + + return { + volumeBps: swapTypeBps !== undefined ? swapTypeBps : defaultBps, + recipient: COW_EVM_RECIPIENT, + }; +}; export const FLASH_LOAN_FEE_BPS = 5; @@ -159,6 +178,7 @@ export const COW_APP_DATA = ( smartSlippage: boolean, orderType: OrderType, appCode: string, + swapType?: SwapType, hooks?: Record ) => ({ appCode: appCode, @@ -171,7 +191,7 @@ export const COW_APP_DATA = ( ? { quote: { slippageBips, smartSlippage } } : // Slippage is not used in limit orders {}), - partnerFee: COW_PARTNER_FEE(tokenFromSymbol, tokenToSymbol), + partnerFee: COW_PARTNER_FEE(tokenFromSymbol, tokenToSymbol, swapType), hooks, }, }); diff --git a/src/components/transactions/Swap/helpers/cow/adapters.helpers.ts b/src/components/transactions/Swap/helpers/cow/adapters.helpers.ts index 3b0cf9e519..afe3c35e8a 100644 --- a/src/components/transactions/Swap/helpers/cow/adapters.helpers.ts +++ b/src/components/transactions/Swap/helpers/cow/adapters.helpers.ts @@ -82,7 +82,11 @@ export const calculateInstanceAddress = async ({ quoteId: isCowProtocolRates(state.swapRate) ? state.swapRate?.quoteId : undefined, side: state.processedSide, slippageBps: state.orderType == OrderType.MARKET ? Number(state.slippage) * 100 : undefined, - partnerFee: COW_PARTNER_FEE(state.sellAmountToken.symbol, state.buyAmountToken.symbol), + partnerFee: COW_PARTNER_FEE( + state.sellAmountToken.symbol, + state.buyAmountToken.symbol, + state.swapType + ), }; const { flashLoanFeeAmount, sellAmountToSign } = flashLoanSdk.calculateFlashLoanAmounts({ diff --git a/src/components/transactions/Swap/helpers/cow/orders.helpers.ts b/src/components/transactions/Swap/helpers/cow/orders.helpers.ts index a4dbbfd107..4b8ef9a4f7 100644 --- a/src/components/transactions/Swap/helpers/cow/orders.helpers.ts +++ b/src/components/transactions/Swap/helpers/cow/orders.helpers.ts @@ -27,7 +27,7 @@ import { COW_PROTOCOL_ETH_FLOW_ADDRESS_BY_ENV, isChainIdSupportedByCoWProtocol, } from '../../constants/cow.constants'; -import { OrderType, SwapState } from '../../types'; +import { OrderType, SwapState, SwapType } from '../../types'; import { getCowTradingSdkByChainIdAndAppCode } from './env.helpers'; export const COW_ENV: CowEnv = 'prod'; @@ -74,6 +74,7 @@ export type CowProtocolActionParams = { signatureParams?: SignedParams; estimateGasLimit?: (tx: PopulatedTransaction, chainId?: number) => Promise; validTo: number; + swapType?: SwapType; }; export const getPreSignTransaction = async ({ @@ -94,6 +95,7 @@ export const getPreSignTransaction = async ({ tokenDestDecimals, kind, validTo, + swapType, }: CowProtocolActionParams) => { if (!isChainIdSupportedByCoWProtocol(chainId)) { throw new Error('Chain not supported.'); @@ -125,7 +127,8 @@ export const getPreSignTransaction = async ({ slippageBps, smartSlippage, orderType, - appCode + appCode, + swapType ), additionalParams: { signingScheme: SigningScheme.PRESIGN, @@ -165,6 +168,7 @@ export const sendOrder = async ({ signatureParams, estimateGasLimit, validTo, + swapType, }: CowProtocolActionParams) => { const signer = provider?.getSigner(); @@ -199,6 +203,7 @@ export const sendOrder = async ({ smartSlippage, orderType, appCode, + swapType, hooks ); @@ -289,6 +294,7 @@ export const getUnsignerOrder = async ({ validTo, srcToken, receiver, + swapType, }: { sellAmount: string; buyAmount: string; @@ -304,10 +310,19 @@ export const getUnsignerOrder = async ({ validTo: number; srcToken?: string; receiver?: string; + swapType?: SwapType; }) => { const metadataApi = new MetadataApi(); const { appDataHex } = await metadataApi.getAppDataInfo( - COW_APP_DATA(tokenFromSymbol, tokenToSymbol, slippageBps, smartSlippage, orderType, appCode) + COW_APP_DATA( + tokenFromSymbol, + tokenToSymbol, + slippageBps, + smartSlippage, + orderType, + appCode, + swapType + ) ); return { @@ -346,10 +361,19 @@ export const populateEthFlowTx = async ( smartSlippage: boolean, appCode: string, orderType: OrderType, + swapType?: SwapType, quoteId?: number ): Promise => { const appDataHex = await hashAppData( - COW_APP_DATA(tokenFromSymbol, tokenToSymbol, slippageBps, smartSlippage, orderType, appCode) + COW_APP_DATA( + tokenFromSymbol, + tokenToSymbol, + slippageBps, + smartSlippage, + orderType, + appCode, + swapType + ) ); const orderData = { diff --git a/src/components/transactions/Swap/helpers/cow/rates.helpers.ts b/src/components/transactions/Swap/helpers/cow/rates.helpers.ts index 06cf2b7f4f..addd218766 100644 --- a/src/components/transactions/Swap/helpers/cow/rates.helpers.ts +++ b/src/components/transactions/Swap/helpers/cow/rates.helpers.ts @@ -103,7 +103,7 @@ export async function getCowProtocolSellRates({ buyTokenDecimals: destDecimals, signer, appCode: appCode, - partnerFee: COW_PARTNER_FEE(inputSymbol, outputSymbol), + partnerFee: COW_PARTNER_FEE(inputSymbol, outputSymbol, swapType), }, { // Price Quality is set to OPTIMAL by default diff --git a/src/components/transactions/Swap/hooks/useSwapOrderAmounts.ts b/src/components/transactions/Swap/hooks/useSwapOrderAmounts.ts index 78b5196041..a7a84eb119 100644 --- a/src/components/transactions/Swap/hooks/useSwapOrderAmounts.ts +++ b/src/components/transactions/Swap/hooks/useSwapOrderAmounts.ts @@ -79,7 +79,8 @@ export const useSwapOrderAmounts = ({ let networkFeeAmountInBuyFormatted = '0'; const partnetFeeBps = state.provider === SwapProvider.COW_PROTOCOL - ? COW_PARTNER_FEE(state.sourceToken.symbol, state.destinationToken.symbol).volumeBps + ? COW_PARTNER_FEE(state.sourceToken.symbol, state.destinationToken.symbol, state.swapType) + .volumeBps : 0; const partnerFeeAmount = state.side === 'sell'