Commit 323edc0f authored by Moody Salem's avatar Moody Salem

consistently use the worst price and amounts in the swap view

parent fc258fdf
import { currencyEquals } from '@uniswap/sdk-core' import { currencyEquals, Percent } 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 React, { useCallback, useMemo } from 'react' import React, { useCallback, useMemo } from 'react'
...@@ -86,10 +86,12 @@ export default function ConfirmSwapModal({ ...@@ -86,10 +86,12 @@ export default function ConfirmSwapModal({
) : null ) : null
}, [allowedSlippage, onConfirm, showAcceptChanges, swapErrorMessage, trade]) }, [allowedSlippage, onConfirm, showAcceptChanges, swapErrorMessage, trade])
const slippageTolerancePercent = new Percent(allowedSlippage, 10_000)
// text to show while loading // text to show while loading
const pendingText = `Swapping ${trade?.inputAmount?.toSignificant(6)} ${ const pendingText = `Swapping ${trade?.maximumAmountIn(slippageTolerancePercent)?.toSignificant(6)} ${
trade?.inputAmount?.currency?.symbol trade?.inputAmount?.currency?.symbol
} for ${trade?.outputAmount?.toSignificant(6)} ${trade?.outputAmount?.currency?.symbol}` } for ${trade?.minimumAmountOut(slippageTolerancePercent)?.toSignificant(6)} ${trade?.outputAmount?.currency?.symbol}`
const confirmationContent = useCallback( const confirmationContent = useCallback(
() => () =>
......
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 { TradeType } from '@uniswap/sdk-core' import { Percent, TradeType } from '@uniswap/sdk-core'
import React, { useContext, useMemo, useState } from 'react' import React, { useContext, useMemo, useState } from 'react'
import { Repeat } from 'react-feather' import { Repeat } from 'react-feather'
import { Text } from 'rebass' import { Text } from 'rebass'
import { ThemeContext } from 'styled-components' import { ThemeContext } from 'styled-components'
import { Field } from '../../state/swap/actions'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { import { computeTradePriceBreakdown, formatExecutionPrice, warningSeverity } from '../../utils/prices'
computeSlippageAdjustedAmounts,
computeTradePriceBreakdown,
formatExecutionPrice,
warningSeverity,
} from '../../utils/prices'
import { ButtonError } from '../Button' import { ButtonError } from '../Button'
import { AutoColumn } from '../Column' import { AutoColumn } from '../Column'
import QuestionHelper from '../QuestionHelper' import QuestionHelper from '../QuestionHelper'
import { AutoRow, RowBetween, RowFixed } from '../Row' import { AutoRow, RowBetween, RowFixed } from '../Row'
import FormattedPriceImpact from './FormattedPriceImpact'
import { StyledBalanceMaxMini, SwapCallbackError } from './styleds' import { StyledBalanceMaxMini, SwapCallbackError } from './styleds'
export default function SwapModalFooter({ export default function SwapModalFooter({
...@@ -35,11 +28,10 @@ export default function SwapModalFooter({ ...@@ -35,11 +28,10 @@ export default function SwapModalFooter({
}) { }) {
const [showInverted, setShowInverted] = useState<boolean>(false) const [showInverted, setShowInverted] = useState<boolean>(false)
const theme = useContext(ThemeContext) const theme = useContext(ThemeContext)
const slippageAdjustedAmounts = useMemo(() => computeSlippageAdjustedAmounts(trade, allowedSlippage), [ const slippageTolerancePercent = new Percent(allowedSlippage, 10_000)
allowedSlippage, const maximumAmountIn = trade.maximumAmountIn(slippageTolerancePercent)
trade, const minimumAmountOut = trade.minimumAmountOut(slippageTolerancePercent)
]) const { priceImpactWithoutFee } = useMemo(() => computeTradePriceBreakdown(trade), [trade])
const { priceImpactWithoutFee, realizedLPFee } = useMemo(() => computeTradePriceBreakdown(trade), [trade])
const severity = warningSeverity(priceImpactWithoutFee) const severity = warningSeverity(priceImpactWithoutFee)
return ( return (
...@@ -61,53 +53,12 @@ export default function SwapModalFooter({ ...@@ -61,53 +53,12 @@ export default function SwapModalFooter({
paddingLeft: '10px', paddingLeft: '10px',
}} }}
> >
{formatExecutionPrice(trade, showInverted)} {formatExecutionPrice(trade, showInverted, slippageTolerancePercent)}
<StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}> <StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}>
<Repeat size={14} /> <Repeat size={14} />
</StyledBalanceMaxMini> </StyledBalanceMaxMini>
</Text> </Text>
</RowBetween> </RowBetween>
<RowBetween>
<RowFixed>
<TYPE.black fontSize={14} fontWeight={400} color={theme.text2}>
{trade.tradeType === TradeType.EXACT_INPUT ? 'Minimum received' : 'Maximum sold'}
</TYPE.black>
<QuestionHelper text="Your transaction will revert if there is a large, unfavorable price movement before it is confirmed." />
</RowFixed>
<RowFixed>
<TYPE.black fontSize={14}>
{trade.tradeType === TradeType.EXACT_INPUT
? slippageAdjustedAmounts[Field.OUTPUT]?.toSignificant(4) ?? '-'
: slippageAdjustedAmounts[Field.INPUT]?.toSignificant(4) ?? '-'}
</TYPE.black>
<TYPE.black fontSize={14} marginLeft={'4px'}>
{trade.tradeType === TradeType.EXACT_INPUT
? trade.outputAmount.currency.symbol
: trade.inputAmount.currency.symbol}
</TYPE.black>
</RowFixed>
</RowBetween>
<RowBetween>
<RowFixed>
<TYPE.black color={theme.text2} fontSize={14} fontWeight={400}>
Price Impact
</TYPE.black>
<QuestionHelper text="The difference between the market price and your price due to trade size." />
</RowFixed>
<FormattedPriceImpact priceImpact={priceImpactWithoutFee} />
</RowBetween>
<RowBetween>
<RowFixed>
<TYPE.black fontSize={14} fontWeight={400} color={theme.text2}>
Liquidity Provider Fee
</TYPE.black>
<QuestionHelper text="A portion of each trade goes to liquidity providers as a protocol incentive." />
</RowFixed>
<TYPE.black fontSize={14}>
{realizedLPFee ? realizedLPFee?.toSignificant(6) + ' ' + trade.inputAmount.currency.symbol : '-'}
</TYPE.black>
</RowBetween>
</AutoColumn> </AutoColumn>
<AutoRow> <AutoRow>
......
import { TradeType } from '@uniswap/sdk-core' import { Percent, TradeType } 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 React, { useContext, useMemo } from 'react' import React, { useContext } from 'react'
import { ArrowDown, AlertTriangle } from 'react-feather' import { ArrowDown, AlertTriangle } from 'react-feather'
import { Text } from 'rebass' import { Text } from 'rebass'
import { ThemeContext } from 'styled-components' import { ThemeContext } from 'styled-components'
import { Field } from '../../state/swap/actions'
import { TYPE } from '../../theme' import { TYPE } from '../../theme'
import { ButtonPrimary } from '../Button' import { ButtonPrimary } from '../Button'
import { isAddress, shortenAddress } from '../../utils' import { isAddress, shortenAddress } from '../../utils'
import { computeSlippageAdjustedAmounts, computeTradePriceBreakdown, warningSeverity } from '../../utils/prices'
import { AutoColumn } from '../Column' import { AutoColumn } from '../Column'
import CurrencyLogo from '../CurrencyLogo' import CurrencyLogo from '../CurrencyLogo'
import { RowBetween, RowFixed } from '../Row' import { RowBetween, RowFixed } from '../Row'
...@@ -28,12 +26,9 @@ export default function SwapModalHeader({ ...@@ -28,12 +26,9 @@ export default function SwapModalHeader({
showAcceptChanges: boolean showAcceptChanges: boolean
onAcceptChanges: () => void onAcceptChanges: () => void
}) { }) {
const slippageAdjustedAmounts = useMemo(() => computeSlippageAdjustedAmounts(trade, allowedSlippage), [ const slippageTolerancePercent = new Percent(allowedSlippage, 10_000)
trade, const maximumAmountIn = trade.maximumAmountIn(slippageTolerancePercent)
allowedSlippage, const minimumAmountOut = trade.minimumAmountOut(slippageTolerancePercent)
])
const { priceImpactWithoutFee } = useMemo(() => computeTradePriceBreakdown(trade), [trade])
const priceImpactSeverity = warningSeverity(priceImpactWithoutFee)
const theme = useContext(ThemeContext) const theme = useContext(ThemeContext)
...@@ -47,7 +42,7 @@ export default function SwapModalHeader({ ...@@ -47,7 +42,7 @@ export default function SwapModalHeader({
fontWeight={500} fontWeight={500}
color={showAcceptChanges && trade.tradeType === TradeType.EXACT_OUTPUT ? theme.primary1 : ''} color={showAcceptChanges && trade.tradeType === TradeType.EXACT_OUTPUT ? theme.primary1 : ''}
> >
{trade.inputAmount.toSignificant(6)} {maximumAmountIn.toSignificant(6)}
</TruncatedText> </TruncatedText>
</RowFixed> </RowFixed>
<RowFixed gap={'0px'}> <RowFixed gap={'0px'}>
...@@ -62,18 +57,8 @@ export default function SwapModalHeader({ ...@@ -62,18 +57,8 @@ export default function SwapModalHeader({
<RowBetween align="flex-end"> <RowBetween align="flex-end">
<RowFixed gap={'0px'}> <RowFixed gap={'0px'}>
<CurrencyLogo currency={trade.outputAmount.currency} size={'24px'} style={{ marginRight: '12px' }} /> <CurrencyLogo currency={trade.outputAmount.currency} size={'24px'} style={{ marginRight: '12px' }} />
<TruncatedText <TruncatedText fontSize={24} fontWeight={500}>
fontSize={24} {minimumAmountOut.toSignificant(6)}
fontWeight={500}
color={
priceImpactSeverity > 2
? theme.red1
: showAcceptChanges && trade.tradeType === TradeType.EXACT_INPUT
? theme.primary1
: ''
}
>
{trade.outputAmount.toSignificant(6)}
</TruncatedText> </TruncatedText>
</RowFixed> </RowFixed>
<RowFixed gap={'0px'}> <RowFixed gap={'0px'}>
...@@ -103,7 +88,7 @@ export default function SwapModalHeader({ ...@@ -103,7 +88,7 @@ export default function SwapModalHeader({
<TYPE.italic textAlign="left" style={{ width: '100%' }}> <TYPE.italic textAlign="left" style={{ width: '100%' }}>
{`Output is estimated. You will receive at least `} {`Output is estimated. You will receive at least `}
<b> <b>
{slippageAdjustedAmounts[Field.OUTPUT]?.toSignificant(6)} {trade.outputAmount.currency.symbol} {minimumAmountOut.toSignificant(6)} {trade.outputAmount.currency.symbol}
</b> </b>
{' or the transaction will revert.'} {' or the transaction will revert.'}
</TYPE.italic> </TYPE.italic>
...@@ -111,7 +96,7 @@ export default function SwapModalHeader({ ...@@ -111,7 +96,7 @@ export default function SwapModalHeader({
<TYPE.italic textAlign="left" style={{ width: '100%' }}> <TYPE.italic textAlign="left" style={{ width: '100%' }}>
{`Input is estimated. You will sell at most `} {`Input is estimated. You will sell at most `}
<b> <b>
{slippageAdjustedAmounts[Field.INPUT]?.toSignificant(6)} {trade.inputAmount.currency.symbol} {maximumAmountIn.toSignificant(6)} {trade.inputAmount.currency.symbol}
</b> </b>
{' or the transaction will revert.'} {' or the transaction will revert.'}
</TYPE.italic> </TYPE.italic>
......
...@@ -8,7 +8,7 @@ import { StyledBalanceMaxMini } from './styleds' ...@@ -8,7 +8,7 @@ import { StyledBalanceMaxMini } from './styleds'
import Switch from '../../assets/svg/switch.svg' import Switch from '../../assets/svg/switch.svg'
interface TradePriceProps { interface TradePriceProps {
price?: Price price: Price
showInverted: boolean showInverted: boolean
setShowInverted: (showInverted: boolean) => void setShowInverted: (showInverted: boolean) => void
} }
...@@ -23,10 +23,10 @@ const StyledPriceContainer = styled.div` ...@@ -23,10 +23,10 @@ const StyledPriceContainer = styled.div`
export default function TradePrice({ price, showInverted, setShowInverted }: TradePriceProps) { export default function TradePrice({ price, showInverted, setShowInverted }: TradePriceProps) {
const theme = useContext(ThemeContext) const theme = useContext(ThemeContext)
const formattedPrice = showInverted ? price?.toSignificant(6) : price?.invert()?.toSignificant(6) const formattedPrice = showInverted ? price.toSignificant(6) : price.invert()?.toSignificant(6)
const label = showInverted ? `${price?.quoteCurrency?.symbol}` : `${price?.baseCurrency?.symbol} ` const label = showInverted ? `${price.quoteCurrency?.symbol}` : `${price.baseCurrency?.symbol} `
const labelInverted = showInverted ? `${price?.baseCurrency?.symbol} ` : `${price?.quoteCurrency?.symbol}` const labelInverted = showInverted ? `${price.baseCurrency?.symbol} ` : `${price.quoteCurrency?.symbol}`
const flipPrice = useCallback(() => setShowInverted(!showInverted), [setShowInverted, showInverted]) const flipPrice = useCallback(() => setShowInverted(!showInverted), [setShowInverted, showInverted])
return ( return (
......
...@@ -233,8 +233,7 @@ export function useSwapCallback( ...@@ -233,8 +233,7 @@ export function useSwapCallback(
: recipientAddressOrName : recipientAddressOrName
}` }`
const withVersion = const withVersion = tradeVersion === Version.v3 ? withRecipient : `${withRecipient} on ${tradeVersion}`
tradeVersion === Version.v2 ? withRecipient : `${withRecipient} on ${(tradeVersion as any).toUpperCase()}`
addTransaction(response, { addTransaction(response, {
summary: withVersion, summary: withVersion,
......
...@@ -391,11 +391,10 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -391,11 +391,10 @@ export default function Swap({ history }: RouteComponentProps) {
setShowInverted={setShowInverted} setShowInverted={setShowInverted}
/> />
) : null} ) : null}
{toggledVersion === Version.v3 && v3TradeState === V3TradeState.VALID && isTradeBetter(v3Trade, v2Trade) ? ( {v3TradeState !== V3TradeState.VALID ? null : toggledVersion === Version.v3 &&
isTradeBetter(v3Trade, v2Trade) ? (
<BetterTradeLink version={Version.v2} /> <BetterTradeLink version={Version.v2} />
) : toggledVersion === Version.v2 && ) : toggledVersion === Version.v2 && isTradeBetter(v2Trade, v3Trade) ? (
v3TradeState === V3TradeState.VALID &&
isTradeBetter(v2Trade, v3Trade) ? (
<BetterTradeLink version={Version.v3} /> <BetterTradeLink version={Version.v3} />
) : null} ) : null}
<BottomGrouping> <BottomGrouping>
......
...@@ -18,6 +18,7 @@ export function isTradeBetter( ...@@ -18,6 +18,7 @@ export function isTradeBetter(
!currencyEquals(tradeA.inputAmount.currency, tradeB.inputAmount.currency) || !currencyEquals(tradeA.inputAmount.currency, tradeB.inputAmount.currency) ||
!currencyEquals(tradeB.outputAmount.currency, tradeB.outputAmount.currency) !currencyEquals(tradeB.outputAmount.currency, tradeB.outputAmount.currency)
) { ) {
console.error('Comparing incomparable trades', tradeA, tradeB)
return false return false
} }
......
import JSBI from 'jsbi' import JSBI from 'jsbi'
import { BLOCKED_PRICE_IMPACT_NON_EXPERT } from '../constants' import { BLOCKED_PRICE_IMPACT_NON_EXPERT, ZERO_PERCENT } from '../constants'
import { CurrencyAmount, Fraction, Percent, TokenAmount } from '@uniswap/sdk-core' import { CurrencyAmount, Fraction, Percent, TokenAmount } 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'
...@@ -104,15 +104,19 @@ export function warningSeverity(priceImpact: Percent | undefined): 0 | 1 | 2 | 3 ...@@ -104,15 +104,19 @@ export function warningSeverity(priceImpact: Percent | undefined): 0 | 1 | 2 | 3
return 0 return 0
} }
export function formatExecutionPrice(trade: V2Trade | V3Trade | undefined, inverted: boolean | undefined): string { export function formatExecutionPrice(
trade: V2Trade | V3Trade | undefined,
inverted: boolean | undefined,
slippageTolerance: Percent = ZERO_PERCENT
): string {
if (!trade) { if (!trade) {
return '' return ''
} }
return inverted return inverted
? `${trade.executionPrice.invert().toSignificant(6)} ${trade.inputAmount.currency.symbol} / ${ ? `${trade.worstExecutionPrice(slippageTolerance).invert().toSignificant(6)} ${
trade.outputAmount.currency.symbol trade.inputAmount.currency.symbol
}` } / ${trade.outputAmount.currency.symbol}`
: `${trade.executionPrice.toSignificant(6)} ${trade.outputAmount.currency.symbol} / ${ : `${trade.worstExecutionPrice(slippageTolerance).toSignificant(6)} ${trade.outputAmount.currency.symbol} / ${
trade.inputAmount.currency.symbol trade.inputAmount.currency.symbol
}` }`
} }
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