Skip to content

Commit

Permalink
Merge pull request cowprotocol#3969 from cowprotocol/hotfix/2024-03-04
Browse files Browse the repository at this point in the history
chore(release): hotfix/2024 03 04
  • Loading branch information
alfetopito authored Mar 4, 2024
2 parents ceb30ed + f965020 commit 65cb39d
Show file tree
Hide file tree
Showing 54 changed files with 226 additions and 157 deletions.
2 changes: 0 additions & 2 deletions apps/cowswap-frontend/src/common/constants/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import ms from 'ms.macro'

export const HIGH_FEE_WARNING_PERCENTAGE = new Percent(1, 10)

export const SAFE_COW_APP_LINK = 'https://app.safe.global/share/safe-app?appUrl=https%3A%2F%2Fswap.cow.fi&chain=eth'

export const MAX_ORDER_DEADLINE = ms`182d` + ms`12h` // 6 months, matching backend's https://github.com/cowprotocol/infrastructure/blob/901ed8e2fe3ea57956585f107bdd7539c2e7d3d1/services/Pulumi.yaml#L15

// Use a 150K gas as a fallback if there's issue calculating the gas estimation (fixes some issues with some nodes failing to calculate gas costs for SC wallets)
Expand Down
8 changes: 4 additions & 4 deletions apps/cowswap-frontend/src/legacy/state/price/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ import { SupportedChainId as ChainId } from '@cowprotocol/cow-sdk'
import { useDispatch, useSelector } from 'react-redux'

import {
updateQuote,
UpdateQuoteParams,
ClearQuoteParams,
getNewQuote,
GetQuoteParams,
refreshQuote,
SetQuoteErrorParams,
setQuoteError,
RefreshQuoteParams,
setQuoteError,
SetQuoteErrorParams,
updateQuote,
UpdateQuoteParams,
} from './actions'
import { QuoteInformationObject, QuotesMap } from './reducer'

Expand Down
2 changes: 1 addition & 1 deletion apps/cowswap-frontend/src/legacy/state/swap/TradeGp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface FeeInformation {
amount: string
}

export type FeeForTrade = { feeAsCurrency: CurrencyAmount<Currency> } & Pick<FeeInformation, 'amount'>
export type FeeForTrade = { feeAsCurrency: CurrencyAmount<Currency> } & FeeInformation

type TradeExecutionPrice = CanonicalMarketParams<CurrencyAmount<Currency> | undefined> & { price?: PriceInformation }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,15 @@ import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { useENS } from '@cowprotocol/ens'
import { TokenLogo, useTokenBySymbolOrAddress } from '@cowprotocol/tokens'
import { UiOrderType } from '@cowprotocol/types'
import { ExternalLink, TokenAmount, UI } from '@cowprotocol/ui'
import {
ExternalLink,
TokenAmount,
UI,
Icon,
IconType,
BannerOrientation,
CustomRecipientWarningBanner,
} from '@cowprotocol/ui'
import { CurrencyAmount } from '@uniswap/sdk-core'

import { OrderProgressBar } from 'legacy/components/OrderProgressBar'
Expand All @@ -19,8 +27,6 @@ import { EthFlowStepper } from 'modules/swap/containers/EthFlowStepper'
import { useCancelOrder } from 'common/hooks/useCancelOrder'
import { isPending } from 'common/hooks/useCategorizeRecentActivity'
import { useGetSurplusData } from 'common/hooks/useGetSurplusFiatValue'
import { Icon, IconType } from 'common/pure/Icon'
import { BannerOrientation, CustomRecipientWarningBanner } from 'common/pure/InlineBanner/banners'
import { RateInfo, RateInfoParams } from 'common/pure/RateInfo'
import { SafeWalletLink } from 'common/pure/SafeWalletLink'
import {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { CHRISTMAS_THEME_ENABLED } from '@cowprotocol/common-const'
import { isInjectedWidget } from '@cowprotocol/common-utils'
import { OnlyUniswapListAvailableBanner } from '@cowprotocol/tokens'

import ErrorBoundary from 'legacy/components/ErrorBoundary'
import Footer from 'legacy/components/Footer'
Expand Down Expand Up @@ -32,7 +31,6 @@ export function App() {

<styledEl.AppWrapper>
<URLWarning />
<OnlyUniswapListAvailableBanner />

<OrdersPanel />

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useAtomValue, useSetAtom } from 'jotai'
import React, { useCallback, useEffect } from 'react'

import { isFractionFalsy } from '@cowprotocol/common-utils'
import { BundleTxApprovalBanner, BundleTxSafeWcBanner, SmallVolumeWarningBanner } from '@cowprotocol/ui'
import { useIsSafeViaWc, useWalletInfo } from '@cowprotocol/wallet'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'

Expand All @@ -23,11 +24,6 @@ import { useTradeQuote } from 'modules/tradeQuote'
import { useShouldZeroApprove } from 'modules/zeroApproval'

import { HIGH_FEE_WARNING_PERCENTAGE } from 'common/constants/common'
import {
BundleTxApprovalBanner,
BundleTxSafeWcBanner,
SmallVolumeWarningBanner,
} from 'common/pure/InlineBanner/banners'
import { ZeroApprovalWarning } from 'common/pure/ZeroApprovalWarning'
import { calculatePercentageInRelationToReference } from 'utils/orderUtils/calculatePercentageInRelationToReference'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { getAddress, getEtherscanLink } from '@cowprotocol/common-utils'
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { TokenLogo } from '@cowprotocol/tokens'
import { Command, UiOrderType } from '@cowprotocol/types'
import { Loader, TokenAmount, TokenSymbol, UI } from '@cowprotocol/ui'
import { Loader, TokenAmount, TokenSymbol, UI, ButtonSecondary } from '@cowprotocol/ui'
import { Currency, CurrencyAmount, Percent, Price } from '@uniswap/sdk-core'

import SVG from 'react-inlinesvg'
Expand All @@ -28,7 +28,6 @@ import { OrderStatusBox } from 'modules/ordersTable/pure/OrderStatusBox'
import { getIsEthFlowOrder } from 'modules/swap/containers/EthFlowStepper'

import { useSafeMemo } from 'common/hooks/useSafeMemo'
import { ButtonSecondary } from 'common/pure/ButtonSecondary'
import { RateInfo } from 'common/pure/RateInfo'
import { getQuoteCurrency } from 'common/services/getQuoteCurrency'
import { isOrderCancellable } from 'common/utils/isOrderCancellable'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import cowMeditatingV2 from '@cowprotocol/assets/cow-swap/meditating-cow-v2.svg'
import imageConnectWallet from '@cowprotocol/assets/cow-swap/wallet-plus.svg'
import { isInjectedWidget } from '@cowprotocol/common-utils'
import { ExternalLink } from '@cowprotocol/ui'
import { UI } from '@cowprotocol/ui'
import { UI, CowSwapSafeAppLink } from '@cowprotocol/ui'

import { Trans } from '@lingui/macro'
import SVG from 'react-inlinesvg'
import styled from 'styled-components/macro'

import { Web3Status } from 'modules/wallet/containers/Web3Status'

import { CowSwapSafeAppLink } from 'common/pure/CowSwapSafeAppLink'

import { OrdersTable, OrdersTableProps } from './OrdersTable'
import { OrdersTabs, OrdersTabsProps } from './OrdersTabs'

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { ExplorerDataType, getExplorerLink, isSellOrder, shortenAddress } from '@cowprotocol/common-utils'
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { Command } from '@cowprotocol/types'
import { ExternalLink, UI } from '@cowprotocol/ui'
import {
UI,
Icon,
IconType,
ExternalLink,
InlineBanner,
BannerOrientation,
CustomRecipientWarningBanner,
} from '@cowprotocol/ui'
import { CurrencyAmount, Fraction, Token } from '@uniswap/sdk-core'

import { OrderStatus } from 'legacy/state/orders/actions'
Expand All @@ -10,9 +18,6 @@ import { CloseIcon } from 'legacy/theme'
import { TwapOrderItem } from 'modules/twap/types'

import { isPending } from 'common/hooks/useCategorizeRecentActivity'
import { Icon, IconType } from 'common/pure/Icon'
import { InlineBanner } from 'common/pure/InlineBanner'
import { BannerOrientation, CustomRecipientWarningBanner } from 'common/pure/InlineBanner/banners'
import { CowModal } from 'common/pure/Modal'
import {
useHideReceiverWalletBanner,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Token } from '@uniswap/sdk-core'

import { QuoteError } from 'legacy/state/price/actions'
import { QuoteInformationObject } from 'legacy/state/price/reducer'
import TradeGp from 'legacy/state/swap/TradeGp'

import { getEthFlowEnabled } from 'modules/swap/helpers/getEthFlowEnabled'
import { isQuoteExpired } from 'modules/tradeQuote/utils/isQuoteExpired'

import { ApprovalState } from 'common/hooks/useApproveState'

Expand All @@ -18,6 +20,7 @@ export enum SwapButtonState {
TransferToSmartContract = 'TransferToSmartContract',
UnsupportedToken = 'UnsupportedToken',
FetchQuoteError = 'FetchQuoteError',
QuoteExpired = 'QuoteExpired',
OfflineBrowser = 'OfflineBrowser',
Loading = 'Loading',
WalletIsNotConnected = 'WalletIsNotConnected',
Expand All @@ -39,7 +42,7 @@ export interface SwapButtonStateParams {
isReadonlyGnosisSafeUser: boolean
isSwapUnsupported: boolean
isBundlingSupported: boolean
quoteError: QuoteError | undefined | null
quote: QuoteInformationObject | undefined | null
inputError?: string
approvalState: ApprovalState
feeWarningAccepted: boolean
Expand All @@ -66,7 +69,8 @@ const quoteErrorToSwapButtonState: { [key in QuoteError]: SwapButtonState | null
}

export function getSwapButtonState(input: SwapButtonStateParams): SwapButtonState {
const { quoteError, approvalState, isPermitSupported, amountsForSignature } = input
const { quote, approvalState, isPermitSupported, amountsForSignature } = input
const quoteError = quote?.error

// show approve flow when: no error on inputs, not approved or pending, or approved in current session
// never show if price impact is above threshold
Expand Down Expand Up @@ -104,6 +108,10 @@ export function getSwapButtonState(input: SwapButtonStateParams): SwapButtonStat
return SwapButtonState.ReadonlyGnosisSafeUser
}

if (isQuoteExpired(quote?.fee?.expirationDate) === true) {
return SwapButtonState.QuoteExpired
}

if (!input.isNativeIn && showApproveFlow) {
if (input.isBundlingSupported) {
return SwapButtonState.ApproveAndSwap
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function useBaseFlowContextSetup(): BaseFlowContextSetup {
const { allowsOffchainSigning } = useWalletDetails()
const gnosisSafeInfo = useGnosisSafeInfo()
const { recipient } = useSwapState()
const { v2Trade: trade } = useDerivedSwapInfo()
const { v2Trade: trade, allowedSlippage } = useDerivedSwapInfo()
const swapZeroFee = useSwapZeroFee()

const appData = useAppData()
Expand All @@ -107,7 +107,6 @@ export function useBaseFlowContextSetup(): BaseFlowContextSetup {
const isSafeEthFlow = useIsSafeEthFlow()
const getCachedPermit = useGetCachedPermit()

const { allowedSlippage } = useDerivedSwapInfo()
const [inputAmountWithSlippage, outputAmountWithSlippage] = useSwapAmountsWithSlippage()
const sellTokenContract = useTokenContract(getAddress(inputAmountWithSlippage?.currency) || undefined, true)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ export function useSwapButtonContext(input: SwapButtonInput): SwapButtonsContext
isSwapUnsupported,
isNativeIn: isNativeInSwap,
wrappedToken,
quoteError: quote?.error,
quote,
inputError: swapInputError,
approvalState,
feeWarningAccepted,
Expand Down Expand Up @@ -166,6 +166,6 @@ function useHasEnoughWrappedBalanceForSwap(inputAmount?: CurrencyAmount<Currency
const { currencies } = useDerivedSwapInfo()
const wrappedBalance = useCurrencyAmountBalance(currencies.INPUT ? getWrappedToken(currencies.INPUT) : undefined)

// is an native currency trade but wrapped token has enough balance
// is a native currency trade but wrapped token has enough balance
return !!(wrappedBalance && inputAmount && !wrappedBalance.lessThan(inputAmount))
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { COW, GNO } from '@cowprotocol/common-const'
import { currencyAmountToTokenAmount } from '@cowprotocol/common-utils'
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { CurrencyAmount, TradeType, Price } from '@uniswap/sdk-core'
import { CurrencyAmount, Price, TradeType } from '@uniswap/sdk-core'

import TradeGp from 'legacy/state/swap/TradeGp'

Expand All @@ -20,7 +20,11 @@ const trade = new TradeGp({
inputAmountWithoutFee: CurrencyAmount.fromRawAmount(currency, amount * 10 ** 18),
outputAmount: CurrencyAmount.fromRawAmount(currency, output * 10 ** 18),
outputAmountWithoutFee: CurrencyAmount.fromRawAmount(currency, (output - 3) * 10 ** 18),
fee: { feeAsCurrency: CurrencyAmount.fromRawAmount(currency, 3 * 10 ** 18), amount: '50' },
fee: {
feeAsCurrency: CurrencyAmount.fromRawAmount(currency, 3 * 10 ** 18),
amount: '50',
expirationDate: new Date().toISOString(),
},
executionPrice: new Price(currency, currencyOut, 1, 4),
tradeType: TradeType.EXACT_INPUT,
quoteId: 10000,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ const swapButtonStateMap: { [key in SwapButtonState]: (props: SwapButtonsContext
<Trans>Error loading price. Try again later.</Trans>
</GreyCard>
),
[SwapButtonState.QuoteExpired]: () => (
<GreyCard style={{ textAlign: 'center' }}>
<Trans>Quote expired. Refreshing...</Trans>
</GreyCard>
),
[SwapButtonState.UnsupportedToken]: () => (
<GreyCard style={{ textAlign: 'center' }}>
<Trans>Unsupported token</Trans>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ const trade = new TradeGp({
inputAmountWithoutFee: CurrencyAmount.fromRawAmount(currency, amount * 10 ** 18),
outputAmount: CurrencyAmount.fromRawAmount(currency, output * 10 ** 18),
outputAmountWithoutFee: CurrencyAmount.fromRawAmount(currency, (output - 3) * 10 ** 18),
fee: { feeAsCurrency: CurrencyAmount.fromRawAmount(currency, 3 * 10 ** 18), amount: '50' },
fee: {
feeAsCurrency: CurrencyAmount.fromRawAmount(currency, 3 * 10 ** 18),
amount: '50',
expirationDate: new Date().toISOString(),
},
executionPrice: new Price(currency, currencyOut, 1, 4),
tradeType: TradeType.EXACT_INPUT,
quoteId: 10000,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { COW, GNO } from '@cowprotocol/common-const'
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { CurrencyAmount, TradeType, Price, Percent } from '@uniswap/sdk-core'
import { CurrencyAmount, Percent, Price, TradeType } from '@uniswap/sdk-core'

import TradeGp from 'legacy/state/swap/TradeGp'

Expand All @@ -20,7 +20,11 @@ const trade = new TradeGp({
inputAmountWithoutFee: CurrencyAmount.fromRawAmount(currency, amount * 10 ** 18),
outputAmount: CurrencyAmount.fromRawAmount(currency, output * 10 ** 18),
outputAmountWithoutFee: CurrencyAmount.fromRawAmount(currency, (output - 3) * 10 ** 18),
fee: { feeAsCurrency: CurrencyAmount.fromRawAmount(currency, 3 * 10 ** 18), amount: '50' },
fee: {
feeAsCurrency: CurrencyAmount.fromRawAmount(currency, 3 * 10 ** 18),
amount: '50',
expirationDate: new Date().toISOString(),
},
executionPrice: new Price(currency, currencyOut, 1, 4),
tradeType: TradeType.EXACT_INPUT,
quoteId: 10000,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { OrderKind, SupportedChainId } from '@cowprotocol/cow-sdk'
import { InlineBanner } from '@cowprotocol/ui'
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'

import { NavLink } from 'react-router-dom'
Expand All @@ -9,7 +10,6 @@ import { parameterizeTradeRoute } from 'modules/trade/utils/parameterizeTradeRou
import { parameterizeTradeSearch } from 'modules/trade/utils/parameterizeTradeSearch'

import { Routes } from 'common/constants/routes'
import { InlineBanner } from 'common/pure/InlineBanner'

const StyledNavLink = styled(NavLink)`
color: inherit;
Expand Down
2 changes: 1 addition & 1 deletion apps/cowswap-frontend/src/modules/swap/pure/warnings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from 'react'

import { genericPropsChecker } from '@cowprotocol/common-utils'
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { BundleTxApprovalBanner, BundleTxSafeWcBanner, BundleTxWrapBanner } from '@cowprotocol/ui'
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'

import styled from 'styled-components/macro'
Expand All @@ -13,7 +14,6 @@ import { CompatibilityIssuesWarning } from 'modules/trade/pure/CompatibilityIssu
import { NoImpactWarning } from 'modules/trade/pure/NoImpactWarning'
import { TradeUrlParams } from 'modules/trade/types/TradeRawState'

import { BundleTxApprovalBanner, BundleTxSafeWcBanner, BundleTxWrapBanner } from 'common/pure/InlineBanner/banners'
import { ZeroApprovalWarning } from 'common/pure/ZeroApprovalWarning'

import { TwapSuggestionBanner } from './banners/TwapSuggestionBanner'
Expand Down
11 changes: 9 additions & 2 deletions apps/cowswap-frontend/src/modules/swap/services/ethFlow/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { reportAppDataWithHooks } from '@cowprotocol/common-utils'
import { reportAppDataWithHooks, reportPlaceOrderWithExpiredQuote } from '@cowprotocol/common-utils'
import { CowEvents } from '@cowprotocol/events'
import { Percent } from '@uniswap/sdk-core'

Expand All @@ -14,6 +14,7 @@ import { addPendingOrderStep } from 'modules/trade/utils/addPendingOrderStep'
import { tradeFlowAnalytics } from 'modules/trade/utils/analytics'
import { logTradeFlow } from 'modules/trade/utils/logger'
import { getSwapErrorMessage } from 'modules/trade/utils/swapErrorHelper'
import { isQuoteExpired } from 'modules/tradeQuote/utils/isQuoteExpired'

import { calculateUniqueOrderId } from './steps/calculateUniqueOrderId'

Expand All @@ -36,7 +37,7 @@ export async function ethFlow(
swapZeroFee,
} = ethFlowContext
const {
trade: { inputAmount, outputAmount },
trade: { inputAmount, outputAmount, fee },
} = context
const tradeAmounts = { inputAmount, outputAmount }

Expand Down Expand Up @@ -66,6 +67,12 @@ export async function ethFlow(
)

try {
// Do not proceed if fee is expired
if (isQuoteExpired(fee.expirationDate)) {
reportPlaceOrderWithExpiredQuote({ ...orderParamsOriginal, fee })
throw new Error('Quote expired. Please refresh.')
}

logTradeFlow('ETH FLOW', 'STEP 4: sign order')
const { order, txReceipt } = await signEthFlowOrderStep(orderId, orderParams, contract, addInFlightOrderId).finally(
() => {
Expand Down
Loading

0 comments on commit 65cb39d

Please sign in to comment.