Skip to content

Commit 9024f60

Browse files
committed
fix(swap): throttle quote request only in "smart" slippage mode
1 parent eac18d7 commit 9024f60

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

apps/cowswap-frontend/src/modules/tradeQuote/hooks/useTradeQuotePolling.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import { useAtom, useAtomValue } from 'jotai'
22
import { useEffect, useLayoutEffect, useRef } from 'react'
33

4-
import { useIsOnline, useIsWindowVisible, usePrevious } from '@cowprotocol/common-hooks'
4+
import { useIsOnline, useIsWindowVisible, usePrevious, useSyncedRef } from '@cowprotocol/common-hooks'
55
import { getCurrencyAddress } from '@cowprotocol/common-utils'
66

77
import ms from 'ms.macro'
88

9+
import { useIsSmartSlippageApplied } from 'modules/tradeSlippage/hooks/useIsSmartSlippageApplied'
10+
911
import { usePollQuoteCallback } from './usePollQuoteCallback'
1012
import { useQuoteParams } from './useQuoteParams'
1113
import { useTradeQuote } from './useTradeQuote'
@@ -21,7 +23,7 @@ import { checkOnlySlippageBpsChanged } from '../utils/quoteParamsChanges'
2123

2224
const ONE_SEC = 1000
2325
const QUOTE_VALIDATION_INTERVAL = ms`2s`
24-
const QUOTE_SLIPPAGE_CHANGE_INTERVAL = ms`1.5s`
26+
const QUOTE_SLIPPAGE_CHANGE_THROTTLE_INTERVAL = ms`1.5s`
2527

2628
// eslint-disable-next-line max-lines-per-function
2729
export function useTradeQuotePolling(quotePollingParams: TradeQuotePollingParameters): null {
@@ -58,6 +60,8 @@ export function useTradeQuotePolling(quotePollingParams: TradeQuotePollingParame
5860
prevQuoteParamsRef.current = quoteParams
5961
}, [quoteParams])
6062

63+
const isSmartSlippageApplied = useSyncedRef(useIsSmartSlippageApplied())
64+
6165
/**
6266
* Reset quote when window is not visible or sell amount has been cleared
6367
*/
@@ -83,27 +87,29 @@ export function useTradeQuotePolling(quotePollingParams: TradeQuotePollingParame
8387
*/
8488
if (isConfirmOpen) return
8589

86-
const onlySlippageBpsChanged = checkOnlySlippageBpsChanged(
87-
quoteParams,
88-
prevQuoteParamsRef.current,
89-
tradeQuoteRef.current,
90-
)
91-
92-
if (onlySlippageBpsChanged) {
93-
const quoteTimestampDiff = tradeQuoteRef.current.localQuoteTimestamp
94-
? Date.now() - tradeQuoteRef.current.localQuoteTimestamp
95-
: undefined
96-
// slippageBps updates on every fetch /quote response
97-
// so we should throttle duplicated additional requests caused by following slippageBps updates to prevent re-fetch loop (#6675)
98-
if (typeof quoteTimestampDiff === 'number' && quoteTimestampDiff < QUOTE_SLIPPAGE_CHANGE_INTERVAL) {
99-
return
90+
if (isSmartSlippageApplied.current) {
91+
const onlySlippageBpsChanged = checkOnlySlippageBpsChanged(
92+
quoteParams,
93+
prevQuoteParamsRef.current,
94+
tradeQuoteRef.current,
95+
)
96+
97+
if (onlySlippageBpsChanged) {
98+
const quoteTimestampDiff = tradeQuoteRef.current.localQuoteTimestamp
99+
? Date.now() - tradeQuoteRef.current.localQuoteTimestamp
100+
: undefined
101+
// in "smart" slippage mode slippageBps updates on every fetch /quote response
102+
// so we should throttle duplicated additional requests caused by following slippageBps updates to prevent re-fetch loop (#6675)
103+
if (typeof quoteTimestampDiff === 'number' && quoteTimestampDiff < QUOTE_SLIPPAGE_CHANGE_THROTTLE_INTERVAL) {
104+
return
105+
}
100106
}
101107
}
102108

103109
if (pollQuoteRef.current(true)) {
104110
resetQuoteCounter()
105111
}
106-
}, [isConfirmOpen, isQuoteUpdatePossible, quoteParams, resetQuoteCounter])
112+
}, [isConfirmOpen, isQuoteUpdatePossible, isSmartSlippageApplied, quoteParams, resetQuoteCounter])
107113

108114
/**
109115
* Update quote once a QUOTE_POLLING_INTERVAL

libs/common-hooks/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ export * from './useComponentDestroyedRef'
2323
export * from './useReducedMotionPreference'
2424
export * from './useElementViewportTracking'
2525
export * from './usePreventDoubleExecution'
26+
export * from './useSyncedRef'
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { useMemo, useRef } from 'react'
2+
3+
/**
4+
* Like `useRef`, but it returns immutable ref that contains actual value.
5+
*
6+
* @param value
7+
* @see https://github.com/react-hookz/web/blob/master/src/useSyncedRef/index.ts
8+
*/
9+
export function useSyncedRef<T>(value: T): { readonly current: T } {
10+
const ref = useRef(value)
11+
12+
ref.current = value
13+
14+
return useMemo(
15+
() =>
16+
Object.freeze({
17+
get current() {
18+
return ref.current
19+
},
20+
}),
21+
[],
22+
)
23+
}

0 commit comments

Comments
 (0)