Skip to content

Commit

Permalink
Price Impact UI (#259)
Browse files Browse the repository at this point in the history
* Transaction rate fix on low liquidity pools

* Build fix and prettier

* Swap value USD API change for useTxRates()

* Data for price impact

* Price impact UI

* Added tooltip

* Only show for tokenB available

Co-authored-by: Bao <[email protected]>
  • Loading branch information
neural-machine and baoskee authored Sep 14, 2022
1 parent 988982c commit 168c134
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ export const TokenToTokenRates = ({
tokenBSymbol,
})

const { isShowing, conversionRate, conversionRateInDollar, dollarValue } =
useTxRates({
tokenASymbol,
tokenBSymbol,
tokenAAmount,
tokenToTokenPrice: oneTokenToTokenPrice * tokenAAmount,
isLoading,
})
const {
isShowing,
conversionRate,
conversionRateInDollar,
tokenBSwapValueUSD,
} = useTxRates({
tokenASymbol,
tokenBSymbol,
tokenAAmount,
tokenToTokenPrice: oneTokenToTokenPrice * tokenAAmount,
isLoading,
})

return (
<StyledDivForGrid active={isShowing}>
Expand All @@ -37,7 +41,7 @@ export const TokenToTokenRates = ({
</Text>
<Text variant="caption" color="disabled">
$
{dollarValueFormatterWithDecimals(dollarValue * 2, {
{dollarValueFormatterWithDecimals(tokenBSwapValueUSD * 2, {
includeCommaSeparation: true,
})}
</Text>
Expand Down
85 changes: 71 additions & 14 deletions features/swap/components/TransactionTips.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
ArrowUpIcon,
Button,
Column,
dollarValueFormatterWithDecimals,
Expand All @@ -8,6 +9,7 @@ import {
Inline,
styled,
Text,
Tooltip,
} from 'junoblocks'
import React, { useState } from 'react'
import { useRecoilValue } from 'recoil'
Expand Down Expand Up @@ -36,14 +38,19 @@ export const TransactionTips = ({
tokenAmount: tokenA?.amount || 1,
})

const { isShowing, conversionRate, conversionRateInDollar, dollarValue } =
useTxRates({
tokenASymbol: tokenA?.tokenSymbol,
tokenBSymbol: tokenB?.tokenSymbol,
tokenAAmount: tokenA?.amount || 1,
tokenToTokenPrice,
isLoading: isPriceLoading,
})
const {
isShowing,
conversionRate,
conversionRateInDollar,
tokenASwapValueUSD,
tokenBSwapValueUSD,
} = useTxRates({
tokenASymbol: tokenA?.tokenSymbol,
tokenBSymbol: tokenB?.tokenSymbol,
tokenAAmount: tokenA?.amount || 1,
tokenToTokenPrice,
isLoading: isPriceLoading,
})

const switchTokensButton = (
<Button
Expand Down Expand Up @@ -72,9 +79,23 @@ export const TransactionTips = ({
</>
)

const formattedDollarValue = dollarValueFormatterWithDecimals(dollarValue, {
includeCommaSeparation: true,
})
const priceImpact =
(tokenBSwapValueUSD - tokenASwapValueUSD) / tokenASwapValueUSD
const formattedPriceImpact = Math.abs(Math.round(priceImpact * 10000) / 100)
const errorThreshold = priceImpact < -0.05

const tokenAFormattedSwapValue = dollarValueFormatterWithDecimals(
tokenASwapValueUSD,
{
includeCommaSeparation: true,
}
)
const tokenBFormattedSwapValue = dollarValueFormatterWithDecimals(
tokenBSwapValueUSD,
{
includeCommaSeparation: true,
}
)

if (size === 'small') {
return (
Expand All @@ -93,7 +114,7 @@ export const TransactionTips = ({
{transactionRates}
</Text>
<Text variant="caption" color="disabled" wrap={false}>
Swap estimate: ${formattedDollarValue}
Swap estimate: ${tokenBFormattedSwapValue}
</Text>
</Column>
)}
Expand All @@ -112,8 +133,44 @@ export const TransactionTips = ({
</Text>
)}
</StyledDivForRateWrapper>

<Text variant="legend">${formattedDollarValue}</Text>
<Inline justifyContent={'flex-end'} gap={8} css={{ cursor: 'pointer' }}>
{tokenB?.tokenSymbol && (
<Tooltip label="Price impact due to the amount of liquity available in the pool.">
<Inline
css={{
backgroundColor: errorThreshold
? '$backgroundColors$error'
: '$backgroundColors$secondary',
padding: '$2 $4 $2 $2',
borderRadius: 4,
}}
>
<ArrowUpIcon
color={errorThreshold ? 'error' : 'secondary'}
css={{
transform: priceImpact < 0 ? 'rotate(180deg)' : undefined,
}}
size="medium"
/>
<Text
variant="legend"
wrap={false}
css={{
color: errorThreshold
? '$textColors$error'
: '$textColors$secondary',
}}
>
{formattedPriceImpact}%
</Text>
</Inline>
</Tooltip>
)}
<Column gap={4}>
<Text variant="legend">${tokenAFormattedSwapValue}</Text>
<Text variant="legend">${tokenBFormattedSwapValue}</Text>
</Column>
</Inline>
</StyledDivForWrapper>
)
}
Expand Down
34 changes: 9 additions & 25 deletions features/swap/hooks/useTxRates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,21 @@ function calculateTokenToTokenConversionRate({
return tokenToTokenPrice / tokenAAmount
}

function calculateTokenToTokenConversionDollarRate({
conversionRate,
tokenADollarPrice,
oneTokenToTokenPrice,
tokenAAmount,
}) {
if (tokenAAmount === 0) {
return tokenADollarPrice
}

return (tokenADollarPrice * conversionRate) / oneTokenToTokenPrice
}

export const useTxRates = ({
tokenASymbol,
tokenBSymbol,
tokenAAmount,
tokenToTokenPrice,
isLoading,
}) => {
const [tokenADollarPrice, fetchingTokenDollarPrice] =
const [tokenADollarValue, fetchingTokenDollarPrice] =
useTokenDollarValue(tokenASymbol)

const [oneTokenToTokenPrice] = usePriceForOneToken({
tokenASymbol: tokenASymbol,
tokenBSymbol: tokenBSymbol,
})

const dollarValue = (tokenADollarPrice || 0) * (tokenAAmount || 0)

const shouldShowRates =
(tokenASymbol &&
tokenBSymbol &&
Expand All @@ -66,23 +51,22 @@ export const useTxRates = ({
)
)

const [tokenBDollarValue] = useTokenDollarValue(tokenBSymbol)
const conversionRateInDollar = usePersistance(
isLoading || fetchingTokenDollarPrice || !shouldShowRates
? undefined
: protectAgainstNaN(
calculateTokenToTokenConversionDollarRate({
tokenAAmount,
conversionRate,
tokenADollarPrice,
oneTokenToTokenPrice,
})
)
: protectAgainstNaN(conversionRate * tokenBDollarValue)
)

const tokenASwapValueUSD = (tokenADollarValue || 0) * (tokenAAmount || 0)
const tokenBSwapValueUSD =
(tokenBDollarValue || 0) * (tokenAAmount * conversionRate || 0)

return {
isShowing: Boolean(shouldShowRates),
conversionRate,
conversionRateInDollar,
dollarValue,
tokenASwapValueUSD,
tokenBSwapValueUSD,
}
}

0 comments on commit 168c134

Please sign in to comment.