Commit 9fec8dbe authored by Moody Salem's avatar Moody Salem

show percentage difference in price on swap

parent 549d4e38
import { Pair } from '@uniswap/v2-sdk' import { Pair } from '@uniswap/v2-sdk'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core' import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import React, { useState, useCallback } from 'react' import React, { useState, useCallback, useMemo } from 'react'
import styled from 'styled-components' import styled from 'styled-components'
import { darken } from 'polished' import { darken } from 'polished'
import { useCurrencyBalance } from '../../state/wallet/hooks' import { useCurrencyBalance } from '../../state/wallet/hooks'
import { warningSeverity } from '../../utils/prices'
import CurrencySearchModal from '../SearchModal/CurrencySearchModal' import CurrencySearchModal from '../SearchModal/CurrencySearchModal'
import CurrencyLogo from '../CurrencyLogo' import CurrencyLogo from '../CurrencyLogo'
import DoubleCurrencyLogo from '../DoubleLogo' import DoubleCurrencyLogo from '../DoubleLogo'
...@@ -158,6 +159,7 @@ interface CurrencyInputPanelProps { ...@@ -158,6 +159,7 @@ interface CurrencyInputPanelProps {
hideInput?: boolean hideInput?: boolean
otherCurrency?: Currency | null otherCurrency?: Currency | null
fiatValue?: CurrencyAmount fiatValue?: CurrencyAmount
priceImpact?: Percent
id: string id: string
showCommonBases?: boolean showCommonBases?: boolean
customBalanceText?: string customBalanceText?: string
...@@ -176,6 +178,7 @@ export default function CurrencyInputPanel({ ...@@ -176,6 +178,7 @@ export default function CurrencyInputPanel({
showCommonBases, showCommonBases,
customBalanceText, customBalanceText,
fiatValue, fiatValue,
priceImpact,
hideBalance = false, hideBalance = false,
pair = null, // used for double token logo pair = null, // used for double token logo
hideInput = false, hideInput = false,
...@@ -193,6 +196,15 @@ export default function CurrencyInputPanel({ ...@@ -193,6 +196,15 @@ export default function CurrencyInputPanel({
setModalOpen(false) setModalOpen(false)
}, [setModalOpen]) }, [setModalOpen])
const priceImpactColor = useMemo(() => {
if (!priceImpact) return undefined
if (priceImpact.lessThan('0')) return theme.green1
const severity = warningSeverity(priceImpact)
if (severity < 1) return undefined
if (severity < 2) return theme.yellow1
return theme.red1
}, [priceImpact, theme.green1, theme.red1, theme.yellow1])
return ( return (
<InputPanel id={id} hideInput={hideInput} {...rest}> <InputPanel id={id} hideInput={hideInput} {...rest}>
{locked && ( {locked && (
...@@ -287,6 +299,9 @@ export default function CurrencyInputPanel({ ...@@ -287,6 +299,9 @@ export default function CurrencyInputPanel({
<TYPE.body fontSize={14} color={fiatValue ? theme.text2 : theme.text4}> <TYPE.body fontSize={14} color={fiatValue ? theme.text2 : theme.text4}>
{fiatValue ? '~' : ''}${fiatValue ? Number(fiatValue?.toSignificant(6)).toLocaleString('en') : '-'} {fiatValue ? '~' : ''}${fiatValue ? Number(fiatValue?.toSignificant(6)).toLocaleString('en') : '-'}
{priceImpact ? (
<span style={{ color: priceImpactColor }}> ({priceImpact.multiply(-1).toSignificant(3)}%)</span>
) : null}
</TYPE.body> </TYPE.body>
</RowBetween> </RowBetween>
</FiatRow> </FiatRow>
......
import { CurrencyAmount, Token } from '@uniswap/sdk-core' import { CurrencyAmount, currencyEquals, Percent, Token } from '@uniswap/sdk-core'
import { Trade as V2Trade } from '@uniswap/v2-sdk' import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk' import { Trade as V3Trade } from '@uniswap/v3-sdk'
import { AdvancedSwapDetails } from 'components/swap/AdvancedSwapDetails' import { AdvancedSwapDetails } from 'components/swap/AdvancedSwapDetails'
...@@ -48,7 +48,7 @@ import { useExpertModeManager, useUserSingleHopOnly, useUserSlippageTolerance } ...@@ -48,7 +48,7 @@ import { useExpertModeManager, useUserSingleHopOnly, useUserSlippageTolerance }
import { LinkStyledButton, TYPE } from '../../theme' import { LinkStyledButton, TYPE } from '../../theme'
import { getTradeVersion } from '../../utils/getTradeVersion' import { getTradeVersion } from '../../utils/getTradeVersion'
import { maxAmountSpend } from '../../utils/maxAmountSpend' import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { computeTradePriceBreakdown, warningSeverity } from '../../utils/prices' import { warningSeverity } from '../../utils/prices'
import AppBody from '../AppBody' import AppBody from '../AppBody'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
...@@ -56,6 +56,17 @@ import { isTradeBetter } from '../../utils/isTradeBetter' ...@@ -56,6 +56,17 @@ import { isTradeBetter } from '../../utils/isTradeBetter'
import BetterTradeLink from '../../components/swap/BetterTradeLink' import BetterTradeLink from '../../components/swap/BetterTradeLink'
import SwapHeader from '../../components/swap/SwapHeader' import SwapHeader from '../../components/swap/SwapHeader'
const ONE_HUNDRED_PERCENT = new Percent(100, 100)
function computeFiatValuePriceImpact(
fiatValueInput: CurrencyAmount | undefined | null,
fiatValueOutput: CurrencyAmount | undefined | null
): Percent | undefined {
if (!fiatValueOutput || !fiatValueInput) return undefined
if (!currencyEquals(fiatValueInput.currency, fiatValueOutput.currency)) return undefined
if (JSBI.equal(fiatValueInput.raw, JSBI.BigInt(0))) return undefined
return ONE_HUNDRED_PERCENT.subtract(fiatValueOutput.divide(fiatValueInput)).multiply(100)
}
export default function Swap({ history }: RouteComponentProps) { export default function Swap({ history }: RouteComponentProps) {
const loadedUrlParams = useDefaultsFromURLSearch() const loadedUrlParams = useDefaultsFromURLSearch()
...@@ -135,6 +146,7 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -135,6 +146,7 @@ export default function Swap({ history }: RouteComponentProps) {
const fiatValueInput = useUSDCValue(parsedAmounts[Field.INPUT]) const fiatValueInput = useUSDCValue(parsedAmounts[Field.INPUT])
const fiatValueOutput = useUSDCValue(parsedAmounts[Field.OUTPUT]) const fiatValueOutput = useUSDCValue(parsedAmounts[Field.OUTPUT])
const priceImpact = computeFiatValuePriceImpact(fiatValueInput, fiatValueOutput)
const { onSwitchTokens, onCurrencySelection, onUserInput, onChangeRecipient } = useSwapActionHandlers() const { onSwitchTokens, onCurrencySelection, onUserInput, onChangeRecipient } = useSwapActionHandlers()
const isValid = !swapInputError const isValid = !swapInputError
...@@ -220,8 +232,6 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -220,8 +232,6 @@ export default function Swap({ history }: RouteComponentProps) {
signatureData signatureData
) )
const { priceImpactWithoutFee: priceImpact } = computeTradePriceBreakdown(trade)
const [singleHopOnly] = useUserSingleHopOnly() const [singleHopOnly] = useUserSingleHopOnly()
const handleSwap = useCallback(() => { const handleSwap = useCallback(() => {
...@@ -377,6 +387,7 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -377,6 +387,7 @@ export default function Swap({ history }: RouteComponentProps) {
showMaxButton={false} showMaxButton={false}
hideBalance={false} hideBalance={false}
fiatValue={fiatValueOutput ?? undefined} fiatValue={fiatValueOutput ?? undefined}
priceImpact={priceImpact}
currency={currencies[Field.OUTPUT]} currency={currencies[Field.OUTPUT]}
onCurrencySelect={handleOutputSelect} onCurrencySelect={handleOutputSelect}
otherCurrency={currencies[Field.INPUT]} otherCurrency={currencies[Field.INPUT]}
......
...@@ -92,11 +92,12 @@ const IMPACT_TIERS = [ ...@@ -92,11 +92,12 @@ const IMPACT_TIERS = [
ALLOWED_PRICE_IMPACT_LOW, ALLOWED_PRICE_IMPACT_LOW,
] ]
export function warningSeverity(priceImpact: Percent | undefined): 0 | 1 | 2 | 3 | 4 { type WarningSeverity = 0 | 1 | 2 | 3 | 4
export function warningSeverity(priceImpact: Percent | undefined): WarningSeverity {
if (!priceImpact) return 4 if (!priceImpact) return 4
let impact = IMPACT_TIERS.length let impact: WarningSeverity = IMPACT_TIERS.length as WarningSeverity
for (const impactLevel of IMPACT_TIERS) { for (const impactLevel of IMPACT_TIERS) {
if (impactLevel.lessThan(priceImpact)) return impact as 0 | 1 | 2 | 3 | 4 if (impactLevel.lessThan(priceImpact)) return impact
impact-- impact--
} }
return 0 return 0
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment