Skip to content

Commit f0579c2

Browse files
committed
fix dust
1 parent e55c49c commit f0579c2

File tree

5 files changed

+62
-12
lines changed

5 files changed

+62
-12
lines changed

src/components/transactions/Swap/actions/DebtSwap/DebtSwapActionsViaCoW.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { normalize } from '@aave/math-utils';
1+
import { normalize, valueToBigNumber } from '@aave/math-utils';
22
import { getOrderToSign, LimitTradeParameters, OrderKind, OrderStatus } from '@cowprotocol/cow-sdk';
33
import { AaveFlashLoanType, HASH_ZERO } from '@cowprotocol/sdk-flash-loans';
44
import { Trans } from '@lingui/macro';
@@ -14,7 +14,11 @@ import { zeroAddress } from 'viem';
1414
import { useShallow } from 'zustand/react/shallow';
1515

1616
import { TrackAnalyticsHandlers } from '../../analytics/useTrackAnalytics';
17-
import { COW_PARTNER_FEE, FLASH_LOAN_FEE_BPS } from '../../constants/cow.constants';
17+
import {
18+
COW_PARTNER_FEE,
19+
DUST_PROTECTION_MULTIPLIER,
20+
FLASH_LOAN_FEE_BPS,
21+
} from '../../constants/cow.constants';
1822
import { APP_CODE_PER_SWAP_TYPE } from '../../constants/shared.constants';
1923
import {
2024
addOrderTypeToAppData,
@@ -173,6 +177,12 @@ export const DebtSwapActionsViaCoW = ({
173177
);
174178
const flashLoanSdk = await getCowFlashLoanSdk(state.chainId);
175179

180+
const buyAmountWithMarginForDustProtection = valueToBigNumber(
181+
state.buyAmountBigInt.toString()
182+
)
183+
.multipliedBy(DUST_PROTECTION_MULTIPLIER)
184+
.toFixed(0);
185+
176186
const delegationPermit = signatureParams
177187
? {
178188
amount: signatureParams?.amount,
@@ -195,7 +205,7 @@ export const DebtSwapActionsViaCoW = ({
195205
buyToken: state.buyAmountToken.underlyingAddress,
196206
buyTokenDecimals: state.buyAmountToken.decimals,
197207
sellAmount: sellAmountToSign.toString(),
198-
buyAmount: state.buyAmountBigInt.toString(),
208+
buyAmount: buyAmountWithMarginForDustProtection.toString(),
199209
kind: state.processedSide === 'buy' ? OrderKind.BUY : OrderKind.SELL,
200210
validTo,
201211
slippageBps: state.orderType == OrderType.MARKET ? Number(state.slippage) * 100 : undefined,
@@ -224,7 +234,7 @@ export const DebtSwapActionsViaCoW = ({
224234
},
225235
{
226236
sellAmount: state.sellAmountBigInt,
227-
buyAmount: state.buyAmountBigInt,
237+
buyAmount: BigInt(buyAmountWithMarginForDustProtection),
228238
orderToSign,
229239
collateralPermit: delegationPermit,
230240
}

src/components/transactions/Swap/actions/RepayWithCollateral/RepayWithCollateralActionsViaCoW.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { normalize } from '@aave/math-utils';
1+
import { normalize, valueToBigNumber } from '@aave/math-utils';
22
import { getOrderToSign, LimitTradeParameters, OrderKind, OrderStatus } from '@cowprotocol/cow-sdk';
33
import { AaveFlashLoanType, HASH_ZERO } from '@cowprotocol/sdk-flash-loans';
44
import { Trans } from '@lingui/macro';
@@ -13,7 +13,11 @@ import { saveCowOrderToUserHistory } from 'src/utils/swapAdapterHistory';
1313
import { useShallow } from 'zustand/react/shallow';
1414

1515
import { TrackAnalyticsHandlers } from '../../analytics/useTrackAnalytics';
16-
import { COW_PARTNER_FEE, FLASH_LOAN_FEE_BPS } from '../../constants/cow.constants';
16+
import {
17+
COW_PARTNER_FEE,
18+
DUST_PROTECTION_MULTIPLIER,
19+
FLASH_LOAN_FEE_BPS,
20+
} from '../../constants/cow.constants';
1721
import { APP_CODE_PER_SWAP_TYPE } from '../../constants/shared.constants';
1822
import {
1923
addOrderTypeToAppData,
@@ -171,6 +175,12 @@ export const RepayWithCollateralActionsViaCoW = ({
171175
);
172176
const flashLoanSdk = await getCowFlashLoanSdk(state.chainId);
173177

178+
const buyAmountWithMarginForDustProtection = valueToBigNumber(
179+
state.buyAmountBigInt.toString()
180+
)
181+
.multipliedBy(DUST_PROTECTION_MULTIPLIER)
182+
.toFixed(0);
183+
174184
const collateralPermit = signatureParams
175185
? {
176186
amount: signatureParams?.amount,
@@ -193,7 +203,7 @@ export const RepayWithCollateralActionsViaCoW = ({
193203
buyToken: state.buyAmountToken.underlyingAddress,
194204
buyTokenDecimals: state.buyAmountToken.decimals,
195205
sellAmount: sellAmountToSign.toString(),
196-
buyAmount: state.buyAmountBigInt.toString(),
206+
buyAmount: buyAmountWithMarginForDustProtection.toString(),
197207
kind: state.processedSide === 'buy' ? OrderKind.BUY : OrderKind.SELL,
198208
validTo,
199209
slippageBps: state.orderType == OrderType.MARKET ? Number(state.slippage) * 100 : undefined,
@@ -222,7 +232,7 @@ export const RepayWithCollateralActionsViaCoW = ({
222232
},
223233
{
224234
sellAmount: state.sellAmountBigInt,
225-
buyAmount: state.buyAmountBigInt,
235+
buyAmount: BigInt(buyAmountWithMarginForDustProtection),
226236
orderToSign,
227237
collateralPermit,
228238
}

src/components/transactions/Swap/constants/cow.constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ export const ADAPTER_FACTORY: Record<SupportedChainId, string> = {
6060
[SupportedChainId.PLASMA]: '0x43c658Ea38bBfD897706fDb35e2468ef5D8F6927',
6161
};
6262

63+
export const DUST_PROTECTION_MULTIPLIER = 1.001;
64+
6365
export const COW_UNSUPPORTED_ASSETS: Partial<
6466
Record<SwapType | 'ALL', Partial<Record<SupportedChainId, string[] | 'ALL'>>>
6567
> = {

src/components/transactions/Swap/helpers/cow/adapters.helpers.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { valueToBigNumber } from '@aave/math-utils';
12
import {
23
AppDataParams,
34
getOrderToSign,
@@ -14,7 +15,11 @@ import {
1415
HASH_ZERO,
1516
} from '@cowprotocol/sdk-flash-loans';
1617

17-
import { COW_PARTNER_FEE, FLASH_LOAN_FEE_BPS } from '../../constants/cow.constants';
18+
import {
19+
COW_PARTNER_FEE,
20+
DUST_PROTECTION_MULTIPLIER,
21+
FLASH_LOAN_FEE_BPS,
22+
} from '../../constants/cow.constants';
1823
import { OrderType, SwapProvider, SwapState, SwapType } from '../../types';
1924
import { getCowFlashLoanSdk } from './env.helpers';
2025

@@ -39,8 +44,24 @@ export const calculateInstanceAddress = async ({
3944
return;
4045

4146
const flashLoanSdk = await getCowFlashLoanSdk(state.chainId);
42-
const { sellAmount, buyAmount, sellToken, buyToken, side, slippageBps, partnerFee } = {
47+
const {
48+
sellAmount,
49+
buyAmountWithMarginForDustProtection,
50+
buyAmount,
51+
sellToken,
52+
buyToken,
53+
side,
54+
slippageBps,
55+
partnerFee,
56+
} = {
4357
sellAmount: state.sellAmountBigInt,
58+
// @note: We wont have dust for borrow side, but we may have dust in collateral swaps
59+
buyAmountWithMarginForDustProtection:
60+
state.swapType !== SwapType.CollateralSwap
61+
? valueToBigNumber(state.buyAmountBigInt.toString())
62+
.multipliedBy(DUST_PROTECTION_MULTIPLIER)
63+
.toFixed(0)
64+
: state.buyAmountBigInt,
4465
sellToken: state.sellAmountToken,
4566
buyAmount: state.buyAmountBigInt,
4667
buyToken: state.buyAmountToken,
@@ -89,7 +110,7 @@ export const calculateInstanceAddress = async ({
89110
flashLoanAmount: sellAmount.toString(),
90111
flashLoanFeeAmount: flashLoanFeeAmount.toString(),
91112
sellAssetAmount: sellAmount.toString(),
92-
buyAssetAmount: buyAmount.toString(),
113+
buyAssetAmount: buyAmountWithMarginForDustProtection.toString(),
93114
};
94115

95116
return await flashLoanSdk.getExpectedInstanceAddress(

src/components/transactions/Swap/hooks/useSwapQuote.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { normalizeBN } from '@aave/math-utils';
22
import { useQuery } from '@tanstack/react-query';
33
import { Dispatch, useEffect, useMemo } from 'react';
4+
import { useModalContext } from 'src/hooks/useModal';
45
import { isTxErrorType, TxErrorType } from 'src/ui-config/errorMapping';
56
import { queryKeysFactory } from 'src/ui-config/queries';
67

@@ -88,7 +89,7 @@ const getTokenSelectionForQuote = (
8889
};
8990
};
9091

91-
export const QUOTE_REFETCH_INTERVAL = 5000; // 30 seconds
92+
export const QUOTE_REFETCH_INTERVAL = 30000; // 30 seconds
9293

9394
/**
9495
* React hook that orchestrates quoting logic across providers.
@@ -280,6 +281,8 @@ const useMultiProviderSwapQuoteQuery = ({
280281
provider: SwapProvider;
281282
requiresQuoteInverted: boolean;
282283
}) => {
284+
const { approvalTxState } = useModalContext();
285+
283286
// Amount to quote depends on side (sell uses input amount, buy uses output amount)
284287
const amount = useMemo(() => {
285288
if (state.side === 'sell') {
@@ -427,6 +430,8 @@ const useMultiProviderSwapQuoteQuery = ({
427430
!state.mainTxState.success &&
428431
!state.mainTxState.txHash && // Don't fetch quotes once transaction is sent
429432
!state.mainTxState.loading && // Don't fetch quotes while transaction is processing
433+
!approvalTxState?.loading && // Don't fetch quotes while approval is processing
434+
!approvalTxState?.success && // Don't fetch quotes while approval is successful
430435
provider !== SwapProvider.NONE &&
431436
!state.quoteRefreshPaused &&
432437
!state.isWrongNetwork
@@ -444,6 +449,8 @@ const useMultiProviderSwapQuoteQuery = ({
444449
!state.mainTxState.success &&
445450
!state.mainTxState.txHash &&
446451
!state.mainTxState.loading &&
452+
!approvalTxState?.loading &&
453+
!approvalTxState?.success &&
447454
!isInsufficientBalance &&
448455
!isFlashloanDisabled
449456
? QUOTE_REFETCH_INTERVAL

0 commit comments

Comments
 (0)