From ac517e8656e6c0a42d3b3e4eb25318d5bc4c69db Mon Sep 17 00:00:00 2001 From: Alexandr Kazachenko Date: Wed, 10 Jan 2024 20:52:22 +0600 Subject: [PATCH 1/2] fix: don't crash when permittable tokens atom doesn't contain new network (#3603) --- .../src/modules/permit/hooks/useGetPermitInfo.ts | 2 +- .../src/modules/permit/hooks/usePermitInfo.ts | 2 +- .../src/modules/permit/state/permittableTokensAtom.ts | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/cowswap-frontend/src/modules/permit/hooks/useGetPermitInfo.ts b/apps/cowswap-frontend/src/modules/permit/hooks/useGetPermitInfo.ts index f8c89dfe12..cb5356b5b9 100644 --- a/apps/cowswap-frontend/src/modules/permit/hooks/useGetPermitInfo.ts +++ b/apps/cowswap-frontend/src/modules/permit/hooks/useGetPermitInfo.ts @@ -15,7 +15,7 @@ export function useGetPermitInfo(chainId: SupportedChainId): (tokenAddress: stri const permittableTokens = useAtomValue(permittableTokensAtom) return useCallback( - (tokenAddress: string) => permittableTokens[chainId][tokenAddress.toLowerCase()], + (tokenAddress: string) => permittableTokens[chainId]?.[tokenAddress.toLowerCase()], [chainId, permittableTokens] ) } diff --git a/apps/cowswap-frontend/src/modules/permit/hooks/usePermitInfo.ts b/apps/cowswap-frontend/src/modules/permit/hooks/usePermitInfo.ts index c078822a7a..e5034d6a5d 100644 --- a/apps/cowswap-frontend/src/modules/permit/hooks/usePermitInfo.ts +++ b/apps/cowswap-frontend/src/modules/permit/hooks/usePermitInfo.ts @@ -117,6 +117,6 @@ function _usePermitInfo(chainId: SupportedChainId, tokenAddress: string | undefi return useMemo(() => { if (!tokenAddress) return undefined - return permittableTokens[chainId][tokenAddress.toLowerCase()] + return permittableTokens[chainId]?.[tokenAddress.toLowerCase()] }, [chainId, permittableTokens, tokenAddress]) } diff --git a/apps/cowswap-frontend/src/modules/permit/state/permittableTokensAtom.ts b/apps/cowswap-frontend/src/modules/permit/state/permittableTokensAtom.ts index 0f24218c94..1dd33e7651 100644 --- a/apps/cowswap-frontend/src/modules/permit/state/permittableTokensAtom.ts +++ b/apps/cowswap-frontend/src/modules/permit/state/permittableTokensAtom.ts @@ -15,7 +15,7 @@ type PermittableTokens = Record * Contains either the permit info for every token checked locally */ -export const permittableTokensAtom = atomWithStorage>( +export const permittableTokensAtom = atomWithStorage>( 'permittableTokens:v2', mapSupportedNetworks({}) ) @@ -28,7 +28,10 @@ export const addPermitInfoForTokenAtom = atom( (get, set, { chainId, tokenAddress, permitInfo }: AddPermitTokenParams) => { const permittableTokens = { ...get(permittableTokensAtom) } - permittableTokens[chainId][tokenAddress.toLowerCase()] = permitInfo + permittableTokens[chainId] = { + ...permittableTokens[chainId], + [tokenAddress.toLowerCase()]: permitInfo, + } set(permittableTokensAtom, permittableTokens) } From 878e99f1cb0079c37ff5b163f31fd1dda578f6c9 Mon Sep 17 00:00:00 2001 From: Leandro Date: Wed, 10 Jan 2024 09:12:40 -0800 Subject: [PATCH 2/2] fix(swap): fix swap out of market (#3576) * fix: query all pending orders * fix: do not quote when there's nothing left in the order * chore: pass the appData from the order when doing new quotes --- .../common/updaters/orders/UnfillableOrdersUpdater.ts | 11 +++++++---- .../cowswap-frontend/src/legacy/state/orders/hooks.ts | 9 +++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/cowswap-frontend/src/common/updaters/orders/UnfillableOrdersUpdater.ts b/apps/cowswap-frontend/src/common/updaters/orders/UnfillableOrdersUpdater.ts index fc62427ed2..5917c34c1e 100644 --- a/apps/cowswap-frontend/src/common/updaters/orders/UnfillableOrdersUpdater.ts +++ b/apps/cowswap-frontend/src/common/updaters/orders/UnfillableOrdersUpdater.ts @@ -1,5 +1,5 @@ import { useSetAtom } from 'jotai' -import { useCallback, useEffect, useMemo, useRef } from 'react' +import { useCallback, useEffect, useRef } from 'react' import { priceOutOfRangeAnalytics } from '@cowprotocol/analytics' import { useTokensBalances } from '@cowprotocol/balances-and-allowances' @@ -44,9 +44,7 @@ export function UnfillableOrdersUpdater(): null { const updatePendingOrderPrices = useSetAtom(updatePendingOrderPricesAtom) const isWindowVisible = useIsWindowVisible() - const pendingLimit = useOnlyPendingOrders(chainId, UiOrderType.LIMIT) - const pendingTwap = useOnlyPendingOrders(chainId, UiOrderType.TWAP) - const pending = useMemo(() => pendingLimit.concat(pendingTwap), [pendingLimit, pendingTwap]) + const pending = useOnlyPendingOrders(chainId) const setIsOrderUnfillable = useSetIsOrderUnfillable() const strategy = useGetGpPriceStrategy() @@ -225,6 +223,9 @@ async function _getOrderPrice( const amount = getRemainderAmount(order.kind, order) + // Don't quote if there's nothing left to match in this order + if (amount === '0') return null + if (order.kind === 'sell') { // this order sell amount is sellAmountAfterFees // this is an issue as it will be adjusted again in the backend @@ -262,6 +263,8 @@ async function _getOrderPrice( receiver: order.receiver, isEthFlow, priceQuality: getPriceQuality({ verifyQuote }), + appData: order.appData ?? undefined, + appDataHash: order.appDataHash ?? undefined, } try { return getBestQuote({ strategy, quoteParams, fetchFee: false, isPriceRefresh: false }) diff --git a/apps/cowswap-frontend/src/legacy/state/orders/hooks.ts b/apps/cowswap-frontend/src/legacy/state/orders/hooks.ts index e18ee5f682..d465204179 100644 --- a/apps/cowswap-frontend/src/legacy/state/orders/hooks.ts +++ b/apps/cowswap-frontend/src/legacy/state/orders/hooks.ts @@ -294,7 +294,7 @@ export const useCombinedPendingOrders = ({ * The difference is that this hook returns only orders that have the status PENDING * while usePendingOrders aggregates all pending states */ -export const useOnlyPendingOrders = (chainId: SupportedChainId, uiOrderType: UiOrderType): Order[] => { +export const useOnlyPendingOrders = (chainId: SupportedChainId): Order[] => { const state = useSelector( (state) => chainId && state.orders?.[chainId]?.pending ) @@ -302,11 +302,8 @@ export const useOnlyPendingOrders = (chainId: SupportedChainId, uiOrderType: UiO return useMemo(() => { if (!state) return [] - return Object.values(state) - .filter((order) => order && getUiOrderType(order.order) === uiOrderType) - .map(_deserializeOrder) - .filter(isTruthy) - }, [state, uiOrderType]) + return Object.values(state).map(_deserializeOrder).filter(isTruthy) + }, [state]) } export const useCancelledOrders = ({ chainId }: GetOrdersParams): Order[] => {