Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: distance to market #5307

Open
wants to merge 4 commits into
base: feat/limit-ui-upgrade-2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion apps/cowswap-frontend/src/common/hooks/useSafeMemo.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { EffectCallback, useEffect, useMemo } from 'react'

import { CurrencyAmount, NativeCurrency, Percent, Token } from '@uniswap/sdk-core'
import { CurrencyAmount, NativeCurrency, Percent, Price, Token } from '@uniswap/sdk-core'

export function useSafeDeps(deps: unknown[]): unknown[] {
return deps.map((dep) => {
if (dep instanceof NativeCurrency) return dep.symbol
if (dep instanceof Token) return dep.address.toLowerCase()
if (dep instanceof CurrencyAmount) return dep.toExact() + dep.currency.symbol + dep.currency.chainId
if (dep instanceof Percent) return dep.toFixed(6)
if (dep instanceof Price) return dep.toFixed(12) + dep.baseCurrency.symbol + dep.quoteCurrency.symbol

return dep
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import AlertTriangle from '@cowprotocol/assets/cow-swap/alert.svg'
import allowanceIcon from '@cowprotocol/assets/images/icon-allowance.svg'
import { ZERO_FRACTION } from '@cowprotocol/common-const'
import { Command } from '@cowprotocol/types'
import { UI, SymbolElement, TokenAmount, TokenAmountProps, HoverTooltip, ButtonSecondary } from '@cowprotocol/ui'
import { Currency, CurrencyAmount, Fraction, Percent } from '@uniswap/sdk-core'
import { ButtonSecondary, HoverTooltip, SymbolElement, TokenAmount, TokenAmountProps, UI } from '@cowprotocol/ui'
import { Currency, CurrencyAmount, Fraction, Percent, Price } from '@uniswap/sdk-core'

import { darken } from 'color2k'
import SVG from 'react-inlinesvg'
import styled from 'styled-components/macro'
import { Nullish } from 'types'

import { PENDING_EXECUTION_THRESHOLD_PERCENTAGE, HIGH_FEE_WARNING_PERCENTAGE } from 'common/constants/common'
import { HIGH_FEE_WARNING_PERCENTAGE, PENDING_EXECUTION_THRESHOLD_PERCENTAGE } from 'common/constants/common'

import * as styledEl from './styled'

Expand All @@ -28,6 +29,7 @@ export const EstimatedExecutionPriceWrapper = styled.span<{ hasWarning: boolean;
}

// Popover container override

> div > div,
> span {
display: flex;
Expand All @@ -41,12 +43,10 @@ const UnfillableLabel = styled.span`
position: relative;
display: flex;
align-items: center;
justify-content: center;
font-size: inherit;
font-weight: 500;
line-height: 1.1;
flex-flow: row wrap;
align-items: center;
justify-content: flex-start;
gap: 3px;

Expand Down Expand Up @@ -94,6 +94,8 @@ export type EstimatedExecutionPriceProps = TokenAmountProps & {
amountDifference?: CurrencyAmount<Currency>
percentageFee?: Percent
amountFee?: CurrencyAmount<Currency>
marketPrice?: Nullish<Price<Currency, Currency>>
executesAtPrice?: Nullish<Price<Currency, Currency>>
warningText?: string
WarningTooltip?: React.FC<{ children: React.ReactNode; showIcon: boolean }>
onApprove?: Command
Expand All @@ -109,6 +111,8 @@ export function EstimatedExecutionPrice(props: EstimatedExecutionPriceProps) {
percentageDifference,
amountDifference,
percentageFee,
marketPrice,
executesAtPrice,
amountFee,
warningText,
WarningTooltip,
Expand Down Expand Up @@ -188,15 +192,28 @@ export function EstimatedExecutionPrice(props: EstimatedExecutionPriceProps) {
<>The fill price of this order is close or at the market price and is expected to fill soon</>
) : (
<>
Market price needs to go {marketPriceNeedsToGoDown ? 'down 📉' : 'up 📈'} by&nbsp;
Current market price is&nbsp;
<b>
<TokenAmount amount={marketPrice} {...rest} round={false} tokenSymbol={marketPrice?.baseCurrency} />
</b>
and needs to go {marketPriceNeedsToGoDown ? 'down 📉' : 'up 📈'} by&nbsp;
<b>
<TokenAmount {...rest} amount={absoluteDifferenceAmount} round={false} />
</b>
&nbsp;
<span>
(<i>{percentageDifferenceInverted?.toFixed(2)}%</i>)
</span>
&nbsp;to execute your order.
to execute your order at&nbsp;
<b>
<TokenAmount
amount={executesAtPrice}
{...rest}
round={false}
tokenSymbol={executesAtPrice?.baseCurrency}
/>
</b>
.
</>
)}
</styledEl.ExecuteInformationTooltip>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'
import orderPresignaturePending from '@cowprotocol/assets/cow-swap/order-presignature-pending.svg'
import { ZERO_FRACTION } from '@cowprotocol/common-const'
import { useTimeAgo } from '@cowprotocol/common-hooks'
import { getAddress, getEtherscanLink, formatDateWithTimezone } from '@cowprotocol/common-utils'
import { formatDateWithTimezone, getAddress, getEtherscanLink } from '@cowprotocol/common-utils'
import { SupportedChainId } from '@cowprotocol/cow-sdk'
import { TokenLogo } from '@cowprotocol/tokens'
import { Command, UiOrderType } from '@cowprotocol/types'
import { UI, TokenAmount, Loader, HoverTooltip } from '@cowprotocol/ui'
import { PercentDisplay, percentIsAlmostHundred } from '@cowprotocol/ui'
import { HoverTooltip, Loader, PercentDisplay, percentIsAlmostHundred, TokenAmount, UI } from '@cowprotocol/ui'
import { useIsSafeWallet } from '@cowprotocol/wallet'
import { Currency, CurrencyAmount, Percent, Price } from '@uniswap/sdk-core'

import { Clock, Zap, Check, X } from 'react-feather'
import { Check, Clock, X, Zap } from 'react-feather'
import SVG from 'react-inlinesvg'

import { OrderStatus } from 'legacy/state/orders/actions'
Expand All @@ -21,9 +20,9 @@ import { PendingOrderPrices } from 'modules/orders/state/pendingOrdersPricesAtom
import { getIsEthFlowOrder } from 'modules/swap/containers/EthFlowStepper'

import {
PENDING_EXECUTION_THRESHOLD_PERCENTAGE,
GOOD_PRICE_THRESHOLD_PERCENTAGE,
FAIR_PRICE_THRESHOLD_PERCENTAGE,
GOOD_PRICE_THRESHOLD_PERCENTAGE,
PENDING_EXECUTION_THRESHOLD_PERCENTAGE,
} from 'common/constants/common'
import { useSafeMemo } from 'common/hooks/useSafeMemo'
import { RateInfo } from 'common/pure/RateInfo'
Expand Down Expand Up @@ -158,7 +157,7 @@ export function OrderRow({
const executedPriceInverted = isInverted ? executedPrice?.invert() : executedPrice
const spotPriceInverted = isInverted ? spotPrice?.invert() : spotPrice

const priceDiffs = usePricesDifference(prices, spotPrice)
const priceDiffs = usePricesDifference(prices, spotPrice, isInverted)
const feeDifference = useFeeAmountDifference(rateInfoParams, prices)

const isExecutedPriceZero = executedPriceInverted !== undefined && executedPriceInverted?.equalTo(ZERO_FRACTION)
Expand Down Expand Up @@ -289,6 +288,8 @@ export function OrderRow({
percentageDifference={priceDiffs?.percentage}
amountDifference={priceDiffs?.amount}
percentageFee={feeDifference}
marketPrice={spotPriceInverted}
executesAtPrice={executionPriceInverted}
amountFee={feeAmount}
canShowWarning={getUiOrderType(order) !== UiOrderType.SWAP && !isUnfillable}
isUnfillable={withWarning}
Expand Down Expand Up @@ -623,20 +624,22 @@ export function OrderRow({
/**
* Helper hook to prepare the parameters to calculate price difference
*/
function usePricesDifference(prices: OrderRowProps['prices'], spotPrice: OrderRowProps['spotPrice']): PriceDifference {
function usePricesDifference(
prices: OrderRowProps['prices'],
spotPrice: OrderRowProps['spotPrice'],
isInverted: boolean,
): PriceDifference {
const { estimatedExecutionPrice } = prices || {}

return useSafeMemo(() => {
if (!spotPrice || !estimatedExecutionPrice) return null

// Calculate price difference using original (non-inverted) prices
// The percentage should stay the same regardless of display inversion
return calculatePriceDifference({
referencePrice: spotPrice,
targetPrice: estimatedExecutionPrice,
isInverted: false,
})
}, [estimatedExecutionPrice, spotPrice]) // Remove isInverted from dependencies since it shouldn't affect the calculation
return useSafeMemo(
() =>
calculatePriceDifference({
referencePrice: spotPrice,
targetPrice: estimatedExecutionPrice,
isInverted,
}),
[estimatedExecutionPrice, spotPrice, isInverted],
)
}

/**
Expand Down
Loading