show v3 quotes
This commit is contained in:
parent
bb17c57a84
commit
ccbd5dfcf7
@ -1,5 +1,6 @@
|
||||
import { TradeType } from '@uniswap/sdk-core'
|
||||
import { Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
||||
import React, { useContext } from 'react'
|
||||
import styled, { ThemeContext } from 'styled-components'
|
||||
import { Field } from '../../state/swap/actions'
|
||||
@ -12,17 +13,7 @@ import { RowBetween, RowFixed } from '../Row'
|
||||
import FormattedPriceImpact from './FormattedPriceImpact'
|
||||
import SwapRoute from './SwapRoute'
|
||||
|
||||
const InfoLink = styled(ExternalLink)`
|
||||
width: 100%;
|
||||
border: 1px solid ${({ theme }) => theme.bg3};
|
||||
padding: 6px 6px;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: ${({ theme }) => theme.text1};
|
||||
`
|
||||
|
||||
function TradeSummary({ trade, allowedSlippage }: { trade: Trade; allowedSlippage: number }) {
|
||||
function TradeSummary({ trade, allowedSlippage }: { trade: V2Trade | V3Trade; allowedSlippage: number }) {
|
||||
const theme = useContext(ThemeContext)
|
||||
const { priceImpactWithoutFee, realizedLPFee } = computeTradePriceBreakdown(trade)
|
||||
const isExactIn = trade.tradeType === TradeType.EXACT_INPUT
|
||||
@ -75,7 +66,7 @@ function TradeSummary({ trade, allowedSlippage }: { trade: Trade; allowedSlippag
|
||||
}
|
||||
|
||||
export interface AdvancedSwapDetailsProps {
|
||||
trade?: Trade
|
||||
trade?: V2Trade | V3Trade
|
||||
}
|
||||
|
||||
export function AdvancedSwapDetails({ trade }: AdvancedSwapDetailsProps) {
|
||||
@ -83,7 +74,10 @@ export function AdvancedSwapDetails({ trade }: AdvancedSwapDetailsProps) {
|
||||
|
||||
const [allowedSlippage] = useUserSlippageTolerance()
|
||||
|
||||
const showRoute = Boolean(trade && trade.route.path.length > 2)
|
||||
const showRoute = Boolean(
|
||||
(trade && trade instanceof V2Trade && trade.route.pairs.length > 2) ||
|
||||
(trade instanceof V3Trade && trade.route.pools.length > 2)
|
||||
)
|
||||
|
||||
return (
|
||||
<AutoColumn gap="0px">
|
||||
@ -103,16 +97,6 @@ export function AdvancedSwapDetails({ trade }: AdvancedSwapDetailsProps) {
|
||||
</RowBetween>
|
||||
</>
|
||||
)}
|
||||
{!showRoute && (
|
||||
<AutoColumn style={{ padding: '12px 16px 0 16px' }}>
|
||||
<InfoLink
|
||||
href={'https://info.uniswap.org/pair/' + trade.route.pairs[0].liquidityToken.address}
|
||||
target="_blank"
|
||||
>
|
||||
View pair analytics ↗
|
||||
</InfoLink>
|
||||
</AutoColumn>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</AutoColumn>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { currencyEquals } from '@uniswap/sdk-core'
|
||||
import { Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
||||
import React, { useCallback, useMemo } from 'react'
|
||||
import TransactionConfirmationModal, {
|
||||
ConfirmationModalContent,
|
||||
@ -10,10 +11,10 @@ import SwapModalHeader from './SwapModalHeader'
|
||||
|
||||
/**
|
||||
* Returns true if the trade requires a confirmation of details before we can submit it
|
||||
* @param tradeA trade A
|
||||
* @param tradeB trade B
|
||||
* @param args either a pair of V2 trades or a pair of V3 trades
|
||||
*/
|
||||
function tradeMeaningfullyDiffers(tradeA: Trade, tradeB: Trade): boolean {
|
||||
function tradeMeaningfullyDiffers(...args: [V2Trade, V2Trade] | [V3Trade, V3Trade]): boolean {
|
||||
const [tradeA, tradeB] = args
|
||||
return (
|
||||
tradeA.tradeType !== tradeB.tradeType ||
|
||||
!currencyEquals(tradeA.inputAmount.currency, tradeB.inputAmount.currency) ||
|
||||
@ -37,8 +38,8 @@ export default function ConfirmSwapModal({
|
||||
txHash,
|
||||
}: {
|
||||
isOpen: boolean
|
||||
trade: Trade | undefined
|
||||
originalTrade: Trade | undefined
|
||||
trade: V2Trade | V3Trade | undefined
|
||||
originalTrade: V2Trade | V3Trade | undefined
|
||||
attemptingTxn: boolean
|
||||
txHash: string | undefined
|
||||
recipient: string | null
|
||||
@ -49,7 +50,15 @@ export default function ConfirmSwapModal({
|
||||
onDismiss: () => void
|
||||
}) {
|
||||
const showAcceptChanges = useMemo(
|
||||
() => Boolean(trade && originalTrade && tradeMeaningfullyDiffers(trade, originalTrade)),
|
||||
() =>
|
||||
Boolean(
|
||||
(trade instanceof V2Trade &&
|
||||
originalTrade instanceof V2Trade &&
|
||||
tradeMeaningfullyDiffers(trade, originalTrade)) ||
|
||||
(trade instanceof V3Trade &&
|
||||
originalTrade instanceof V3Trade &&
|
||||
tradeMeaningfullyDiffers(trade, originalTrade))
|
||||
),
|
||||
[originalTrade, trade]
|
||||
)
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
||||
import { TradeType } from '@uniswap/sdk-core'
|
||||
import React, { useContext, useMemo, useState } from 'react'
|
||||
import { Repeat } from 'react-feather'
|
||||
@ -26,7 +27,7 @@ export default function SwapModalFooter({
|
||||
swapErrorMessage,
|
||||
disabledConfirm,
|
||||
}: {
|
||||
trade: Trade
|
||||
trade: V2Trade | V3Trade
|
||||
allowedSlippage: number
|
||||
onConfirm: () => void
|
||||
swapErrorMessage: string | undefined
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { TradeType } from '@uniswap/sdk-core'
|
||||
import { Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
||||
import React, { useContext, useMemo } from 'react'
|
||||
import { ArrowDown, AlertTriangle } from 'react-feather'
|
||||
import { Text } from 'rebass'
|
||||
@ -21,7 +22,7 @@ export default function SwapModalHeader({
|
||||
showAcceptChanges,
|
||||
onAcceptChanges,
|
||||
}: {
|
||||
trade: Trade
|
||||
trade: V2Trade | V3Trade
|
||||
allowedSlippage: number
|
||||
recipient: string | null
|
||||
showAcceptChanges: boolean
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
||||
import React, { Fragment, memo, useContext } from 'react'
|
||||
import { ChevronRight } from 'react-feather'
|
||||
import { Flex } from 'rebass'
|
||||
@ -6,11 +7,12 @@ import { ThemeContext } from 'styled-components'
|
||||
import { TYPE } from '../../theme'
|
||||
import { unwrappedToken } from 'utils/wrappedCurrency'
|
||||
|
||||
export default memo(function SwapRoute({ trade }: { trade: Trade }) {
|
||||
export default memo(function SwapRoute({ trade }: { trade: V2Trade | V3Trade }) {
|
||||
const tokenPath = trade instanceof V2Trade ? trade.route.path : trade.route.tokenPath
|
||||
const theme = useContext(ThemeContext)
|
||||
return (
|
||||
<Flex flexWrap="wrap" width="100%" justifyContent="flex-end" alignItems="center">
|
||||
{trade.route.path.map((token, i, path) => {
|
||||
{tokenPath.map((token, i, path) => {
|
||||
const isLastItem: boolean = i === path.length - 1
|
||||
const currency = unwrappedToken(token)
|
||||
return (
|
||||
|
@ -1,5 +1,7 @@
|
||||
import JSBI from 'jsbi'
|
||||
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import { JSBI, Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
||||
import React, { useCallback, useContext, useEffect, useMemo, useState } from 'react'
|
||||
import { ArrowDown } from 'react-feather'
|
||||
import ReactGA from 'react-ga'
|
||||
@ -22,6 +24,7 @@ import ProgressSteps from '../../components/ProgressSteps'
|
||||
import SwapHeader from '../../components/swap/SwapHeader'
|
||||
|
||||
import { INITIAL_ALLOWED_SLIPPAGE } from '../../constants'
|
||||
import useToggledVersion, { Version } from '../../hooks/useToggledVersion'
|
||||
import { getTradeVersion } from '../../utils/getTradeVersion'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useCurrency, useAllTokens } from '../../hooks/Tokens'
|
||||
@ -90,6 +93,7 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
const { independentField, typedValue, recipient } = useSwapState()
|
||||
const {
|
||||
v2Trade,
|
||||
v3Trade,
|
||||
currencyBalances,
|
||||
parsedAmount,
|
||||
currencies,
|
||||
@ -104,13 +108,13 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
)
|
||||
const showWrap: boolean = wrapType !== WrapType.NOT_APPLICABLE
|
||||
const { address: recipientAddress } = useENSAddress(recipient)
|
||||
// const toggledVersion = useToggledVersion()
|
||||
const toggledVersion = useToggledVersion()
|
||||
const trade = showWrap
|
||||
? undefined
|
||||
: v2Trade /*{
|
||||
: {
|
||||
[Version.v2]: v2Trade,
|
||||
[Version.v3]: v3Trade,
|
||||
}[toggledVersion]*/
|
||||
}[toggledVersion]
|
||||
|
||||
const parsedAmounts = showWrap
|
||||
? {
|
||||
@ -148,7 +152,7 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
// modal and loading
|
||||
const [{ showConfirm, tradeToConfirm, swapErrorMessage, attemptingTxn, txHash }, setSwapState] = useState<{
|
||||
showConfirm: boolean
|
||||
tradeToConfirm: Trade | undefined
|
||||
tradeToConfirm: V2Trade | V3Trade | undefined
|
||||
attemptingTxn: boolean
|
||||
swapErrorMessage: string | undefined
|
||||
txHash: string | undefined
|
||||
@ -190,7 +194,11 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
const atMaxAmountInput = Boolean(maxAmountInput && parsedAmounts[Field.INPUT]?.equalTo(maxAmountInput))
|
||||
|
||||
// the callback to execute the swap
|
||||
const { callback: swapCallback, error: swapCallbackError } = useV2SwapCallback(trade, allowedSlippage, recipient)
|
||||
const { callback: swapCallback, error: swapCallbackError } = useV2SwapCallback(
|
||||
trade instanceof V2Trade ? trade : undefined,
|
||||
allowedSlippage,
|
||||
recipient
|
||||
)
|
||||
|
||||
const { priceImpactWithoutFee } = computeTradePriceBreakdown(trade)
|
||||
|
||||
|
@ -89,8 +89,8 @@ export default createReducer(initialState, (builder) =>
|
||||
calls.forEach((call) => {
|
||||
const callKey = toCallKey(call)
|
||||
const current = state.callResults[chainId][callKey]
|
||||
if (!current) return // only should be dispatched if we are already fetching
|
||||
if (current.fetchingBlockNumber === fetchingBlockNumber) {
|
||||
if (!current || typeof current.fetchingBlockNumber !== 'number') return // only should be dispatched if we are already fetching
|
||||
if (current.fetchingBlockNumber <= fetchingBlockNumber) {
|
||||
delete current.fetchingBlockNumber
|
||||
current.data = null
|
||||
current.blockNumber = fetchingBlockNumber
|
||||
|
@ -30,7 +30,7 @@ async function fetchChunk(
|
||||
results: { success: boolean; returnData: string }[]
|
||||
blockNumber: number
|
||||
}> {
|
||||
console.debug('Fetching chunk', multicall2Contract, chunk, minBlockNumber)
|
||||
console.debug('Fetching chunk', chunk, minBlockNumber)
|
||||
let resultsBlockNumber: number
|
||||
let results: { success: boolean; returnData: string }[]
|
||||
try {
|
||||
@ -41,7 +41,7 @@ async function fetchChunk(
|
||||
resultsBlockNumber = blockNumber.toNumber()
|
||||
results = returnData
|
||||
} catch (error) {
|
||||
console.debug('Failed to fetch chunk inside retry', error)
|
||||
console.debug('Failed to fetch chunk', error)
|
||||
throw error
|
||||
}
|
||||
if (resultsBlockNumber < minBlockNumber) {
|
||||
@ -205,12 +205,12 @@ export default function Updater(): null {
|
||||
|
||||
// dispatch any errored calls
|
||||
if (erroredCalls.length > 0) {
|
||||
console.debug('Errored calls', erroredCalls)
|
||||
console.debug('Calls errored in fetch', erroredCalls)
|
||||
dispatch(
|
||||
errorFetchingMulticallResults({
|
||||
calls: erroredCalls,
|
||||
chainId,
|
||||
fetchingBlockNumber: latestBlockNumber,
|
||||
fetchingBlockNumber: fetchBlockNumber,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
@ -14,36 +14,43 @@ const INPUT_FRACTION_AFTER_FEE = ONE_HUNDRED_PERCENT.subtract(BASE_FEE)
|
||||
|
||||
// computes price breakdown for the trade
|
||||
export function computeTradePriceBreakdown(
|
||||
trade?: V2Trade | null
|
||||
trade?: V2Trade | V3Trade | null
|
||||
): { priceImpactWithoutFee: Percent | undefined; realizedLPFee: CurrencyAmount | undefined | null } {
|
||||
// for each hop in our trade, take away the x*y=k price impact from 0.3% fees
|
||||
// e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03))
|
||||
const realizedLPFee = !trade
|
||||
? undefined
|
||||
: ONE_HUNDRED_PERCENT.subtract(
|
||||
trade.route.pairs.reduce<Fraction>(
|
||||
(currentFee: Fraction): Fraction => currentFee.multiply(INPUT_FRACTION_AFTER_FEE),
|
||||
ONE_HUNDRED_PERCENT
|
||||
if (trade instanceof V2Trade) {
|
||||
// for each hop in our trade, take away the x*y=k price impact from 0.3% fees
|
||||
// e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03))
|
||||
const realizedLPFee = !trade
|
||||
? undefined
|
||||
: ONE_HUNDRED_PERCENT.subtract(
|
||||
trade.route.pairs.reduce<Fraction>(
|
||||
(currentFee: Fraction): Fraction => currentFee.multiply(INPUT_FRACTION_AFTER_FEE),
|
||||
ONE_HUNDRED_PERCENT
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
// remove lp fees from price impact
|
||||
const priceImpactWithoutFeeFraction = trade && realizedLPFee ? trade.priceImpact.subtract(realizedLPFee) : undefined
|
||||
// remove lp fees from price impact
|
||||
const priceImpactWithoutFeeFraction = trade && realizedLPFee ? trade.priceImpact.subtract(realizedLPFee) : undefined
|
||||
|
||||
// the x*y=k impact
|
||||
const priceImpactWithoutFeePercent = priceImpactWithoutFeeFraction
|
||||
? new Percent(priceImpactWithoutFeeFraction?.numerator, priceImpactWithoutFeeFraction?.denominator)
|
||||
: undefined
|
||||
// the x*y=k impact
|
||||
const priceImpactWithoutFeePercent = priceImpactWithoutFeeFraction
|
||||
? new Percent(priceImpactWithoutFeeFraction?.numerator, priceImpactWithoutFeeFraction?.denominator)
|
||||
: undefined
|
||||
|
||||
// the amount of the input that accrues to LPs
|
||||
const realizedLPFeeAmount =
|
||||
realizedLPFee &&
|
||||
trade &&
|
||||
(trade.inputAmount instanceof TokenAmount
|
||||
? new TokenAmount(trade.inputAmount.token, realizedLPFee.multiply(trade.inputAmount.raw).quotient)
|
||||
: CurrencyAmount.ether(realizedLPFee.multiply(trade.inputAmount.raw).quotient))
|
||||
// the amount of the input that accrues to LPs
|
||||
const realizedLPFeeAmount =
|
||||
realizedLPFee &&
|
||||
trade &&
|
||||
(trade.inputAmount instanceof TokenAmount
|
||||
? new TokenAmount(trade.inputAmount.token, realizedLPFee.multiply(trade.inputAmount.raw).quotient)
|
||||
: CurrencyAmount.ether(realizedLPFee.multiply(trade.inputAmount.raw).quotient))
|
||||
|
||||
return { priceImpactWithoutFee: priceImpactWithoutFeePercent, realizedLPFee: realizedLPFeeAmount }
|
||||
return { priceImpactWithoutFee: priceImpactWithoutFeePercent, realizedLPFee: realizedLPFeeAmount }
|
||||
} else {
|
||||
return {
|
||||
priceImpactWithoutFee: undefined,
|
||||
realizedLPFee: undefined,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// computes the minimum amount out and maximum amount in for a trade given a user specified allowed slippage in bips
|
||||
|
Loading…
Reference in New Issue
Block a user