Commit 509b307b authored by Moody Salem's avatar Moody Salem

show some price impact in the interface

parent 1e5519de
import { CurrencyAmount, Percent, Price } from '@uniswap/sdk-core'
import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk'
import React, { useContext } from 'react'
import { ThemeContext } from 'styled-components'
import { useUserSlippageTolerance } from '../../state/user/hooks'
import { TYPE } from '../../theme'
import { computeRealizedLPFeeAmount } from '../../utils/prices'
import { AutoColumn } from '../Column'
......@@ -12,10 +14,26 @@ export interface AdvancedSwapDetailsProps {
trade?: V2Trade | V3Trade
}
function computePriceImpact(midPrice: Price, inputAmount: CurrencyAmount, outputAmount: CurrencyAmount): Percent {
const exactQuote = midPrice.raw.multiply(inputAmount.raw)
// calculate slippage := (exactQuote - outputAmount) / exactQuote
const slippage = exactQuote.subtract(outputAmount.raw).divide(exactQuote)
return new Percent(slippage.numerator, slippage.denominator)
}
function computePriceImpactWithMaximumSlippage(trade: V2Trade | V3Trade, allowedSlippage: Percent): Percent {
return computePriceImpact(
trade.route.midPrice,
trade.maximumAmountIn(allowedSlippage),
trade.minimumAmountOut(allowedSlippage)
)
}
export function AdvancedSwapDetails({ trade }: AdvancedSwapDetailsProps) {
const theme = useContext(ThemeContext)
const realizedLPFee = computeRealizedLPFeeAmount(trade)
const [allowedSlippage] = useUserSlippageTolerance()
return !trade ? null : (
<AutoColumn gap="8px">
......@@ -40,6 +58,17 @@ export function AdvancedSwapDetails({ trade }: AdvancedSwapDetailsProps) {
<SwapRoute trade={trade} />
</TYPE.black>
</RowBetween>
<RowBetween>
<RowFixed>
<TYPE.black fontSize={12} fontWeight={400} color={theme.text2}>
Execution price vs. spot price
</TYPE.black>
</RowFixed>
<TYPE.black fontSize={12} color={theme.text1}>
{computePriceImpactWithMaximumSlippage(trade, allowedSlippage).toSignificant(4)}%
</TYPE.black>
</RowBetween>
</AutoColumn>
)
}
......@@ -8,7 +8,8 @@ import styled, { ThemeContext } from 'styled-components'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import { TYPE } from '../../theme'
import { ButtonPrimary } from '../Button'
import { computeFiatValuePriceImpact, isAddress, shortenAddress } from '../../utils'
import { isAddress, shortenAddress } from '../../utils'
import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact'
import { AutoColumn } from '../Column'
import { FiatValue } from '../CurrencyInputPanel/FiatValue'
import CurrencyLogo from '../CurrencyLogo'
......
import { Percent } from '@uniswap/sdk-core'
import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade, FeeAmount } from '@uniswap/v3-sdk'
import React, { Fragment, memo, useContext } from 'react'
import { ChevronLeft, ChevronRight } from 'react-feather'
import { ChevronRight } from 'react-feather'
import { Flex } from 'rebass'
import { ThemeContext } from 'styled-components'
import { TYPE } from '../../theme'
import { unwrappedToken } from 'utils/wrappedCurrency'
function LabeledArrow({ fee }: { fee: FeeAmount }) {
function LabeledArrow({}: { fee: FeeAmount }) {
const theme = useContext(ThemeContext)
// todo: improve the rendering of this labeled arrow
return (
<>
<ChevronLeft size={12} color={theme.text2} />
<span style={{ fontSize: 12, marginTop: 2 }}>{new Percent(fee, 1_000_000).toSignificant()}%</span>
<ChevronRight size={12} color={theme.text2} />
</>
)
// todo: render the fee in the label
return <ChevronRight size={12} color={theme.text2} />
}
export default memo(function SwapRoute({ trade }: { trade: V2Trade | V3Trade }) {
......
{
"v3CoreFactoryAddress": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
"weth9Address": "0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6",
"multicall2Address": "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696",
"proxyAdminAddress": "0xB753548F6E010e7e680BA186F9Ca1BdAB2E90cf2",
"tickLensAddress": "0xbfd8137f7d1516D3ea5cA83523914859ec47F573",
"quoterAddress": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
"swapRouter": "0xE592427A0AEce92De3Edee1F18E0157C05861564",
"nftDescriptorLibraryAddress": "0x42B24A95702b9986e82d421cC3568932790A48Ec",
"nonfungibleTokenPositionDescriptorAddress": "0x91ae842A5Ffd8d12023116943e72A606179294f3",
"descriptorProxyAddress": "0xEe6A57eC80ea46401049E92587E52f5Ec1c24785",
"nonfungibleTokenPositionManagerAddress": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
"v3MigratorAddress": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
}
import { ChainId } from '@uniswap/sdk-core'
import goerli from './goerli.json'
import ropsten from './ropsten.json'
import rinkeby from './rinkeby.json'
import kovan from './kovan.json'
import mainnet from './mainnet.json'
import { FACTORY_ADDRESS } from '@uniswap/v3-sdk'
function constructAddressMap(
key: keyof typeof goerli | keyof typeof ropsten | keyof typeof rinkeby | keyof typeof mainnet
): { [chainId in ChainId]: string } {
function constructSameAddressMap(address: string): { [chainId in ChainId]: string } {
return {
[ChainId.MAINNET]: mainnet[key],
[ChainId.ROPSTEN]: ropsten[key],
[ChainId.KOVAN]: kovan[key],
[ChainId.RINKEBY]: rinkeby[key],
[ChainId.GÖRLI]: goerli[key],
[ChainId.MAINNET]: address,
[ChainId.ROPSTEN]: address,
[ChainId.KOVAN]: address,
[ChainId.RINKEBY]: address,
[ChainId.GÖRLI]: address,
}
}
export const V3_CORE_FACTORY_ADDRESSES = constructAddressMap('v3CoreFactoryAddress')
export const V3_CORE_FACTORY_ADDRESSES = constructSameAddressMap(FACTORY_ADDRESS)
export const QUOTER_ADDRESSES = constructAddressMap('quoterAddress')
export const QUOTER_ADDRESSES = constructSameAddressMap('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6')
export const TICK_LENS_ADDRESSES = constructAddressMap('tickLensAddress')
export const TICK_LENS_ADDRESSES = constructSameAddressMap('0xbfd8137f7d1516D3ea5cA83523914859ec47F573')
export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES = constructAddressMap('nonfungibleTokenPositionManagerAddress')
export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES = constructSameAddressMap(
'0xC36442b4a4522E871399CD717aBDD847Ab11FE88'
)
export const SWAP_ROUTER_ADDRESSES = constructAddressMap('swapRouter')
export const SWAP_ROUTER_ADDRESSES = constructSameAddressMap('0xE592427A0AEce92De3Edee1F18E0157C05861564')
export const V3_MIGRATOR_ADDRESSES = constructAddressMap('v3MigratorAddress')
export const V3_MIGRATOR_ADDRESSES = constructSameAddressMap('0xA5644E29708357803b5A882D272c41cC0dF92B34')
{
"v3CoreFactoryAddress": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
"weth9Address": "0xd0A1E359811322d97991E03f863a0C30C2cF029C",
"multicall2Address": "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696",
"proxyAdminAddress": "0xB753548F6E010e7e680BA186F9Ca1BdAB2E90cf2",
"tickLensAddress": "0xbfd8137f7d1516D3ea5cA83523914859ec47F573",
"quoterAddress": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
"swapRouter": "0xE592427A0AEce92De3Edee1F18E0157C05861564",
"nftDescriptorLibraryAddress": "0x42B24A95702b9986e82d421cC3568932790A48Ec",
"nonfungibleTokenPositionDescriptorAddress": "0x91ae842A5Ffd8d12023116943e72A606179294f3",
"descriptorProxyAddress": "0xEe6A57eC80ea46401049E92587E52f5Ec1c24785",
"nonfungibleTokenPositionManagerAddress": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
"v3MigratorAddress": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
}
{
"v3CoreFactoryAddress": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
"weth9Address": "0xc778417E063141139Fce010982780140Aa0cD5Ab",
"multicall2Address": "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696",
"proxyAdminAddress": "0xB753548F6E010e7e680BA186F9Ca1BdAB2E90cf2",
"tickLensAddress": "0xbfd8137f7d1516D3ea5cA83523914859ec47F573",
"quoterAddress": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
"swapRouter": "0xE592427A0AEce92De3Edee1F18E0157C05861564",
"nftDescriptorLibraryAddress": "0x42B24A95702b9986e82d421cC3568932790A48Ec",
"nonfungibleTokenPositionDescriptorAddress": "0x91ae842A5Ffd8d12023116943e72A606179294f3",
"descriptorProxyAddress": "0xEe6A57eC80ea46401049E92587E52f5Ec1c24785",
"nonfungibleTokenPositionManagerAddress": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
"v3MigratorAddress": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
}
{
"v3CoreFactoryAddress": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
"weth9Address": "0xc778417E063141139Fce010982780140Aa0cD5Ab",
"multicall2Address": "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696",
"proxyAdminAddress": "0xB753548F6E010e7e680BA186F9Ca1BdAB2E90cf2",
"tickLensAddress": "0xbfd8137f7d1516D3ea5cA83523914859ec47F573",
"quoterAddress": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
"swapRouter": "0xE592427A0AEce92De3Edee1F18E0157C05861564",
"nftDescriptorLibraryAddress": "0x42B24A95702b9986e82d421cC3568932790A48Ec",
"nonfungibleTokenPositionDescriptorAddress": "0x91ae842A5Ffd8d12023116943e72A606179294f3",
"descriptorProxyAddress": "0xEe6A57eC80ea46401049E92587E52f5Ec1c24785",
"nonfungibleTokenPositionManagerAddress": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
"v3MigratorAddress": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
}
{
"v3CoreFactoryAddress": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
"weth9Address": "0xc778417E063141139Fce010982780140Aa0cD5Ab",
"multicall2Address": "0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696",
"proxyAdminAddress": "0xB753548F6E010e7e680BA186F9Ca1BdAB2E90cf2",
"tickLensAddress": "0xbfd8137f7d1516D3ea5cA83523914859ec47F573",
"quoterAddress": "0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6",
"swapRouter": "0xE592427A0AEce92De3Edee1F18E0157C05861564",
"nftDescriptorLibraryAddress": "0x42B24A95702b9986e82d421cC3568932790A48Ec",
"nonfungibleTokenPositionDescriptorAddress": "0x91ae842A5Ffd8d12023116943e72A606179294f3",
"descriptorProxyAddress": "0xEe6A57eC80ea46401049E92587E52f5Ec1c24785",
"nonfungibleTokenPositionManagerAddress": "0xC36442b4a4522E871399CD717aBDD847Ab11FE88",
"v3MigratorAddress": "0xA5644E29708357803b5A882D272c41cC0dF92B34"
}
......@@ -48,7 +48,7 @@ import {
} from '../../state/swap/hooks'
import { useExpertModeManager, useUserSingleHopOnly, useUserSlippageTolerance } from '../../state/user/hooks'
import { LinkStyledButton, TYPE } from '../../theme'
import { computeFiatValuePriceImpact } from '../../utils'
import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact'
import { getTradeVersion } from '../../utils/getTradeVersion'
import { isTradeBetter } from '../../utils/isTradeBetter'
import { maxAmountSpend } from '../../utils/maxAmountSpend'
......
......@@ -119,4 +119,3 @@ export function supportedChainId(chainId: number): ChainId | undefined {
export function formattedFeeAmount(feeAmount: FeeAmount): number {
return feeAmount / 10000
}
export { computeFiatValuePriceImpact } from './computeFiatValuePriceImpact'
......@@ -41,7 +41,7 @@ export function computeRealizedLPFeeAmount(trade?: V2Trade | V3Trade | null): Cu
: ONE_HUNDRED_PERCENT.subtract(
trade.route.pools.reduce<Fraction>(
(currentFee: Fraction, pool): Fraction =>
currentFee.multiply(ONE_HUNDRED_PERCENT.subtract(new Fraction(pool.fee, 10_000))),
currentFee.multiply(ONE_HUNDRED_PERCENT.subtract(new Fraction(pool.fee, 1_000_000))),
ONE_HUNDRED_PERCENT
)
)
......
......@@ -4149,10 +4149,10 @@
"@uniswap/v3-core" "1.0.0"
base64-sol "1.0.1"
"@uniswap/v3-sdk@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-1.0.1.tgz#a44f7de0fff2964dcd7bb848ccd55716c78d088e"
integrity sha512-5oOJKnAInJq3uTHNjKj2tw/YQndNW6I4bQglEjGyi8te7IO75lJunMtqwjAKVIDMyoKT7iIR25p4t1ZZLEgiHQ==
"@uniswap/v3-sdk@^1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-1.0.3.tgz#8f47b5f8cc8997992811a242ef202f9a8c4797cf"
integrity sha512-izIrHTAXCeMhfye0nHntoAS0UTbpa8HyGSD++Zmy+kROeb2gSAcpXvnLHzRDIPxq0G4rOH0h05Y5fhHAxaXj5w==
dependencies:
"@ethersproject/abi" "^5.0.12"
"@ethersproject/solidity" "^5.0.9"
......
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