feat: read token taxes from backend response (#7532)
* read token taxes from backend * revert env changes * upgrade router-sdk for updated price impact logic * add tax information to trade currencies instead of directly on trade object * consolidate getTradeCurrencies with getSwapCurrenciesWithTaxInfo * delete feature flag for token taxes! * run yarn dedupe again * fix unit tests * update logic for disabling inputs * update snapshot again * fix return value for uniswapx * remove unused constants and update comment * pr review * re-add useSwapTaxes for token descriptor page * add in client-side tax fetching on currency level * revert removing newline * typecheck.... * typecheck... * remove inputTax, outputTax from routing-api arguments because they are now unused * dont pass in tax info to preview trade
This commit is contained in:
parent
76157c057e
commit
ff6d1cc510
@ -202,7 +202,7 @@
|
||||
"@uniswap/merkle-distributor": "^1.0.1",
|
||||
"@uniswap/permit2-sdk": "^1.2.0",
|
||||
"@uniswap/redux-multicall": "^1.1.8",
|
||||
"@uniswap/router-sdk": "^1.6.0",
|
||||
"@uniswap/router-sdk": "^1.7.1",
|
||||
"@uniswap/sdk-core": "4.0.7",
|
||||
"@uniswap/smart-order-router": "^3.15.0",
|
||||
"@uniswap/token-lists": "^1.0.0-beta.33",
|
||||
|
@ -90,7 +90,7 @@ const DescriptionText = styled(ThemedText.LabelMicro)`
|
||||
|
||||
function useOrderAmounts(
|
||||
orderDetails?: UniswapXOrderDetails
|
||||
): Pick<InterfaceTrade, 'inputAmount' | 'postTaxOutputAmount'> | undefined {
|
||||
): Pick<InterfaceTrade, 'inputAmount' | 'outputAmount'> | undefined {
|
||||
const inputCurrency = useCurrency(orderDetails?.swapInfo?.inputCurrencyId, orderDetails?.chainId)
|
||||
const outputCurrency = useCurrency(orderDetails?.swapInfo?.outputCurrencyId, orderDetails?.chainId)
|
||||
|
||||
@ -106,7 +106,7 @@ function useOrderAmounts(
|
||||
if (swapInfo.tradeType === TradeType.EXACT_INPUT) {
|
||||
return {
|
||||
inputAmount: CurrencyAmount.fromRawAmount(inputCurrency, swapInfo.inputCurrencyAmountRaw),
|
||||
postTaxOutputAmount: CurrencyAmount.fromRawAmount(
|
||||
outputAmount: CurrencyAmount.fromRawAmount(
|
||||
outputCurrency,
|
||||
swapInfo.settledOutputCurrencyAmountRaw ?? swapInfo.expectedOutputCurrencyAmountRaw
|
||||
),
|
||||
@ -114,7 +114,7 @@ function useOrderAmounts(
|
||||
} else {
|
||||
return {
|
||||
inputAmount: CurrencyAmount.fromRawAmount(inputCurrency, swapInfo.expectedInputCurrencyAmountRaw),
|
||||
postTaxOutputAmount: CurrencyAmount.fromRawAmount(outputCurrency, swapInfo.outputCurrencyAmountRaw),
|
||||
outputAmount: CurrencyAmount.fromRawAmount(outputCurrency, swapInfo.outputCurrencyAmountRaw),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import { useQuickRouteChains } from 'featureFlags/dynamicConfig/quickRouteChains
|
||||
import { useAndroidGALaunchFlag } from 'featureFlags/flags/androidGALaunch'
|
||||
import { useCurrencyConversionFlag } from 'featureFlags/flags/currencyConversion'
|
||||
import { useFallbackProviderEnabledFlag } from 'featureFlags/flags/fallbackProvider'
|
||||
import { useFotAdjustmentsFlag } from 'featureFlags/flags/fotAdjustments'
|
||||
import { useInfoExploreFlag } from 'featureFlags/flags/infoExplore'
|
||||
import { useInfoLiveViewsFlag } from 'featureFlags/flags/infoLiveViews'
|
||||
import { useInfoPoolPageFlag } from 'featureFlags/flags/infoPoolPage'
|
||||
@ -293,12 +292,6 @@ export default function FeatureFlagModal() {
|
||||
featureFlag={FeatureFlag.multichainUX}
|
||||
label="Updated Multichain UX"
|
||||
/>
|
||||
<FeatureFlagOption
|
||||
variant={BaseVariant}
|
||||
value={useFotAdjustmentsFlag()}
|
||||
featureFlag={FeatureFlag.fotAdjustedmentsEnabled}
|
||||
label="Enable fee-on-transfer UI and slippage adjustments"
|
||||
/>
|
||||
<FeatureFlagOption
|
||||
variant={BaseVariant}
|
||||
value={useProgressIndicatorV2Flag()}
|
||||
|
@ -6,7 +6,7 @@ import { useTheme } from 'styled-components'
|
||||
import { ThemedText } from 'theme/components'
|
||||
import { useFormatter } from 'utils/formatNumbers'
|
||||
|
||||
export function TradeSummary({ trade }: { trade: Pick<InterfaceTrade, 'inputAmount' | 'postTaxOutputAmount'> }) {
|
||||
export function TradeSummary({ trade }: { trade: Pick<InterfaceTrade, 'inputAmount' | 'outputAmount'> }) {
|
||||
const theme = useTheme()
|
||||
const { formatReviewSwapCurrencyAmount } = useFormatter()
|
||||
|
||||
@ -17,9 +17,9 @@ export function TradeSummary({ trade }: { trade: Pick<InterfaceTrade, 'inputAmou
|
||||
{formatReviewSwapCurrencyAmount(trade.inputAmount)} {trade.inputAmount.currency.symbol}
|
||||
</ThemedText.LabelSmall>
|
||||
<ArrowRight color={theme.neutral1} size="12px" />
|
||||
<CurrencyLogo currency={trade.postTaxOutputAmount.currency} size="16px" />
|
||||
<CurrencyLogo currency={trade.outputAmount.currency} size="16px" />
|
||||
<ThemedText.LabelSmall color="neutral1">
|
||||
{formatReviewSwapCurrencyAmount(trade.postTaxOutputAmount)} {trade.postTaxOutputAmount.currency.symbol}
|
||||
{formatReviewSwapCurrencyAmount(trade.outputAmount)} {trade.outputAmount.currency.symbol}
|
||||
</ThemedText.LabelSmall>
|
||||
</Row>
|
||||
)
|
||||
|
@ -24,7 +24,7 @@ export default function SwapModalHeader({
|
||||
allowedSlippage: Percent
|
||||
}) {
|
||||
const fiatValueInput = useUSDPrice(trade.inputAmount)
|
||||
const fiatValueOutput = useUSDPrice(trade.postTaxOutputAmount)
|
||||
const fiatValueOutput = useUSDPrice(trade.outputAmount)
|
||||
|
||||
return (
|
||||
<HeaderContainer gap="sm">
|
||||
@ -40,7 +40,7 @@ export default function SwapModalHeader({
|
||||
<SwapModalHeaderAmount
|
||||
field={Field.OUTPUT}
|
||||
label={<Trans>You receive</Trans>}
|
||||
amount={trade.postTaxOutputAmount}
|
||||
amount={trade.outputAmount}
|
||||
currency={trade.outputAmount.currency}
|
||||
usdAmount={fiatValueOutput.data}
|
||||
isLoading={isPreviewTrade(trade) && trade.tradeType === TradeType.EXACT_INPUT}
|
||||
|
@ -6882,7 +6882,7 @@ exports[`SwapLineItem.tsx fee on buy 1`] = `
|
||||
<span
|
||||
class=""
|
||||
>
|
||||
~-105566.373%
|
||||
~-108834.406%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -7165,14 +7165,14 @@ exports[`SwapLineItem.tsx fee on buy 1`] = `
|
||||
<div
|
||||
class="c3 css-obwv3p"
|
||||
>
|
||||
0.000000000000000952 DEF
|
||||
0.00000000000000098 DEF
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="c13"
|
||||
/>
|
||||
<div>
|
||||
If the price moves so that you will receive less than 0.000000000000000952 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive.
|
||||
If the price moves so that you will receive less than 0.00000000000000098 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive.
|
||||
<a
|
||||
class="c14"
|
||||
href="https://support.uniswap.org/hc/en-us/articles/8643879653261-What-is-Price-Slippage-"
|
||||
@ -7549,7 +7549,7 @@ exports[`SwapLineItem.tsx fee on buy 1`] = `
|
||||
<div
|
||||
class="c3 c6 css-142zc9n"
|
||||
>
|
||||
0.000000000000000952 DEF
|
||||
0.00000000000000098 DEF
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -8761,7 +8761,7 @@ exports[`SwapLineItem.tsx fee on sell 1`] = `
|
||||
<span
|
||||
class=""
|
||||
>
|
||||
~-105566.373%
|
||||
~-108834.406%
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -9044,14 +9044,14 @@ exports[`SwapLineItem.tsx fee on sell 1`] = `
|
||||
<div
|
||||
class="c3 css-obwv3p"
|
||||
>
|
||||
0.000000000000000952 DEF
|
||||
0.00000000000000098 DEF
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="c13"
|
||||
/>
|
||||
<div>
|
||||
If the price moves so that you will receive less than 0.000000000000000952 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive.
|
||||
If the price moves so that you will receive less than 0.00000000000000098 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive.
|
||||
<a
|
||||
class="c14"
|
||||
href="https://support.uniswap.org/hc/en-us/articles/8643879653261-What-is-Price-Slippage-"
|
||||
@ -9428,7 +9428,7 @@ exports[`SwapLineItem.tsx fee on sell 1`] = `
|
||||
<div
|
||||
class="c3 c6 css-142zc9n"
|
||||
>
|
||||
0.000000000000000952 DEF
|
||||
0.00000000000000098 DEF
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,9 +0,0 @@
|
||||
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
|
||||
|
||||
export function useFotAdjustmentsFlag(): BaseVariant {
|
||||
return useBaseFlag(FeatureFlag.fotAdjustedmentsEnabled)
|
||||
}
|
||||
|
||||
export function useFotAdjustmentsEnabled(): boolean {
|
||||
return useFotAdjustmentsFlag() === BaseVariant.Enabled
|
||||
}
|
@ -14,7 +14,6 @@ export enum FeatureFlag {
|
||||
uniswapXExactOutputEnabled = 'uniswapx_exact_output_enabled',
|
||||
multichainUX = 'multichain_ux',
|
||||
currencyConversion = 'currency_conversion',
|
||||
fotAdjustedmentsEnabled = 'fot_dynamic_adjustments_enabled',
|
||||
infoExplore = 'info_explore',
|
||||
infoTDP = 'info_tdp',
|
||||
infoPoolPage = 'info_pool_page',
|
||||
|
@ -84,13 +84,13 @@ export function useSwapCallback(
|
||||
? {
|
||||
tradeType: TradeType.EXACT_INPUT,
|
||||
inputCurrencyAmountRaw: trade.inputAmount.quotient.toString(),
|
||||
expectedOutputCurrencyAmountRaw: trade.postTaxOutputAmount.quotient.toString(),
|
||||
expectedOutputCurrencyAmountRaw: trade.outputAmount.quotient.toString(),
|
||||
minimumOutputCurrencyAmountRaw: trade.minimumAmountOut(allowedSlippage).quotient.toString(),
|
||||
}
|
||||
: {
|
||||
tradeType: TradeType.EXACT_OUTPUT,
|
||||
maximumInputCurrencyAmountRaw: trade.maximumAmountIn(allowedSlippage).quotient.toString(),
|
||||
outputCurrencyAmountRaw: trade.postTaxOutputAmount.quotient.toString(),
|
||||
outputCurrencyAmountRaw: trade.outputAmount.quotient.toString(),
|
||||
expectedInputCurrencyAmountRaw: trade.inputAmount.quotient.toString(),
|
||||
}),
|
||||
}
|
||||
|
@ -73,12 +73,8 @@ export function useUniversalRouterSwapCallback(
|
||||
|
||||
setTraceData('slippageTolerance', options.slippageTolerance.toFixed(2))
|
||||
|
||||
// universal-router-sdk reconstructs V2Trade objects, so rather than updating the trade amounts to account for tax, we adjust the slippage tolerance as a workaround
|
||||
// TODO(WEB-2725): update universal-router-sdk to not reconstruct trades
|
||||
const taxAdjustedSlippageTolerance = options.slippageTolerance.add(trade.totalTaxRate)
|
||||
|
||||
const { calldata: data, value } = SwapRouter.swapERC20CallParameters(trade, {
|
||||
slippageTolerance: taxAdjustedSlippageTolerance,
|
||||
slippageTolerance: options.slippageTolerance,
|
||||
deadlineOrPreviousBlockhash: options.deadline?.toString(),
|
||||
inputTokenPermit: options.permit,
|
||||
fee: options.feeOptions,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { SkipToken, skipToken } from '@reduxjs/toolkit/query/react'
|
||||
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
|
||||
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
|
||||
import { useUniswapXDefaultEnabled } from 'featureFlags/flags/uniswapXDefault'
|
||||
import { useUniswapXEthOutputEnabled } from 'featureFlags/flags/uniswapXEthOutput'
|
||||
import { useUniswapXExactOutputEnabled } from 'featureFlags/flags/uniswapXExactOutput'
|
||||
@ -22,8 +22,6 @@ export function useRoutingAPIArguments({
|
||||
amount,
|
||||
tradeType,
|
||||
routerPreference,
|
||||
inputTax,
|
||||
outputTax,
|
||||
}: {
|
||||
account?: string
|
||||
tokenIn?: Currency
|
||||
@ -31,8 +29,6 @@ export function useRoutingAPIArguments({
|
||||
amount?: CurrencyAmount<Currency>
|
||||
tradeType: TradeType
|
||||
routerPreference: RouterPreference | typeof INTERNAL_ROUTER_PREFERENCE_PRICE
|
||||
inputTax: Percent
|
||||
outputTax: Percent
|
||||
}): GetQuoteArgs | SkipToken {
|
||||
const uniswapXForceSyntheticQuotes = useUniswapXSyntheticQuoteEnabled()
|
||||
const userDisabledUniswapX = useUserDisabledUniswapX()
|
||||
@ -70,8 +66,6 @@ export function useRoutingAPIArguments({
|
||||
uniswapXExactOutputEnabled,
|
||||
isUniswapXDefaultEnabled,
|
||||
sendPortionEnabled,
|
||||
inputTax,
|
||||
outputTax,
|
||||
},
|
||||
[
|
||||
account,
|
||||
@ -87,8 +81,6 @@ export function useRoutingAPIArguments({
|
||||
uniswapXEthOutputEnabled,
|
||||
isUniswapXDefaultEnabled,
|
||||
sendPortionEnabled,
|
||||
inputTax,
|
||||
outputTax,
|
||||
]
|
||||
)
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ export function formatCommonPropertiesForTrade(
|
||||
token_in_symbol: trade.inputAmount.currency.symbol,
|
||||
token_out_symbol: trade.outputAmount.currency.symbol,
|
||||
token_in_amount: formatToDecimal(trade.inputAmount, trade.inputAmount.currency.decimals),
|
||||
token_out_amount: formatToDecimal(trade.postTaxOutputAmount, trade.outputAmount.currency.decimals),
|
||||
token_out_amount: formatToDecimal(trade.outputAmount, trade.outputAmount.currency.decimals),
|
||||
price_impact_basis_points: isClassicTrade(trade)
|
||||
? formatPercentInBasisPointsNumber(computeRealizedPriceImpact(trade))
|
||||
: undefined,
|
||||
@ -64,6 +64,8 @@ export function formatCommonPropertiesForTrade(
|
||||
allowed_slippage: formatPercentNumber(allowedSlippage),
|
||||
method: getQuoteMethod(trade),
|
||||
fee_usd: outputFeeFiatValue,
|
||||
token_out_detected_tax: formatPercentNumber(trade.outputTax),
|
||||
token_in_detected_tax: formatPercentNumber(trade.inputTax),
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,8 +103,6 @@ export const formatSwapQuoteReceivedEventProperties = (
|
||||
trade: InterfaceTrade,
|
||||
allowedSlippage: Percent,
|
||||
swapQuoteLatencyMs: number | undefined,
|
||||
inputTax: Percent,
|
||||
outputTax: Percent,
|
||||
outputFeeFiatValue: number | undefined
|
||||
) => {
|
||||
return {
|
||||
@ -112,7 +112,5 @@ export const formatSwapQuoteReceivedEventProperties = (
|
||||
token_in_amount_max: trade.maximumAmountIn(allowedSlippage).toExact(),
|
||||
token_out_amount_min: trade.minimumAmountOut(allowedSlippage).toExact(),
|
||||
quote_latency_milliseconds: swapQuoteLatencyMs,
|
||||
token_out_detected_tax: formatPercentNumber(outputTax),
|
||||
token_in_detected_tax: formatPercentNumber(inputTax),
|
||||
}
|
||||
}
|
||||
|
@ -292,9 +292,9 @@ export function Swap({
|
||||
parsedAmount,
|
||||
currencies,
|
||||
inputError: swapInputError,
|
||||
outputFeeFiatValue,
|
||||
inputTax,
|
||||
outputTax,
|
||||
outputFeeFiatValue,
|
||||
} = swapInfo
|
||||
|
||||
const [inputTokenHasTax, outputTokenHasTax] = useMemo(
|
||||
@ -323,7 +323,7 @@ export function Swap({
|
||||
}
|
||||
: {
|
||||
[Field.INPUT]: independentField === Field.INPUT ? parsedAmount : trade?.inputAmount,
|
||||
[Field.OUTPUT]: independentField === Field.OUTPUT ? parsedAmount : trade?.postTaxOutputAmount,
|
||||
[Field.OUTPUT]: independentField === Field.OUTPUT ? parsedAmount : trade?.outputAmount,
|
||||
},
|
||||
[independentField, parsedAmount, showWrap, trade]
|
||||
)
|
||||
@ -354,7 +354,7 @@ export function Swap({
|
||||
)
|
||||
|
||||
const fiatValueTradeInput = useUSDPrice(trade?.inputAmount)
|
||||
const fiatValueTradeOutput = useUSDPrice(trade?.postTaxOutputAmount)
|
||||
const fiatValueTradeOutput = useUSDPrice(trade?.outputAmount)
|
||||
const preTaxFiatValueTradeOutput = useUSDPrice(trade?.outputAmount)
|
||||
const [stablecoinPriceImpact, preTaxStablecoinPriceImpact] = useMemo(
|
||||
() =>
|
||||
@ -585,17 +585,10 @@ export function Swap({
|
||||
if (!trade || prevTrade === trade) return // no new swap quote to log
|
||||
|
||||
sendAnalyticsEvent(SwapEventName.SWAP_QUOTE_RECEIVED, {
|
||||
...formatSwapQuoteReceivedEventProperties(
|
||||
trade,
|
||||
allowedSlippage,
|
||||
swapQuoteLatency,
|
||||
inputTax,
|
||||
outputTax,
|
||||
outputFeeFiatValue
|
||||
),
|
||||
...formatSwapQuoteReceivedEventProperties(trade, allowedSlippage, swapQuoteLatency, outputFeeFiatValue),
|
||||
...trace,
|
||||
})
|
||||
}, [prevTrade, trade, trace, allowedSlippage, swapQuoteLatency, inputTax, outputTax, outputFeeFiatValue])
|
||||
}, [prevTrade, trade, trace, allowedSlippage, swapQuoteLatency, outputFeeFiatValue])
|
||||
|
||||
const showDetailsDropdown = Boolean(
|
||||
!showWrap && userHasSpecifiedInputOutput && (trade || routeIsLoading || routeIsSyncing)
|
||||
|
@ -19,7 +19,7 @@ import {
|
||||
URAQuoteResponse,
|
||||
URAQuoteType,
|
||||
} from './types'
|
||||
import { isExactInput, transformRoutesToTrade } from './utils'
|
||||
import { isExactInput, transformQuoteToTrade } from './utils'
|
||||
|
||||
const UNISWAP_API_URL = process.env.REACT_APP_UNISWAP_API_URL
|
||||
if (UNISWAP_API_URL === undefined) {
|
||||
@ -69,6 +69,7 @@ function getRoutingAPIConfig(args: GetQuoteArgs): RoutingConfig {
|
||||
...DEFAULT_QUERY_PARAMS,
|
||||
routingType: URAQuoteType.CLASSIC,
|
||||
recipient: account,
|
||||
enableFeeOnTransferFeeFetching: true,
|
||||
}
|
||||
|
||||
const tokenOutIsNative = Object.values(SwapRouterNativeAssets).includes(tokenOutAddress as SwapRouterNativeAssets)
|
||||
@ -179,7 +180,7 @@ export const routingApi = createApi({
|
||||
}
|
||||
|
||||
const uraQuoteResponse = response.data as URAQuoteResponse
|
||||
const tradeResult = await transformRoutesToTrade(args, uraQuoteResponse, QuoteMethod.ROUTING_API)
|
||||
const tradeResult = await transformQuoteToTrade(args, uraQuoteResponse, QuoteMethod.ROUTING_API)
|
||||
return { data: { ...tradeResult, latencyMs: getQuoteLatencyMeasure(quoteStartMark).duration } }
|
||||
} catch (error: any) {
|
||||
console.warn(
|
||||
@ -194,7 +195,7 @@ export const routingApi = createApi({
|
||||
const router = getRouter(args.tokenInChainId)
|
||||
const quoteResult = await getClientSideQuote(args, router, CLIENT_PARAMS)
|
||||
if (quoteResult.state === QuoteState.SUCCESS) {
|
||||
const trade = await transformRoutesToTrade(args, quoteResult.data, QuoteMethod.CLIENT_SIDE_FALLBACK)
|
||||
const trade = await transformQuoteToTrade(args, quoteResult.data, QuoteMethod.CLIENT_SIDE_FALLBACK)
|
||||
return {
|
||||
data: { ...trade, latencyMs: getQuoteLatencyMeasure(quoteStartMark).duration },
|
||||
}
|
||||
|
@ -51,8 +51,6 @@ export interface GetQuoteArgs {
|
||||
userOptedOutOfUniswapX: boolean
|
||||
isUniswapXDefaultEnabled: boolean
|
||||
sendPortionEnabled: boolean
|
||||
inputTax: Percent
|
||||
outputTax: Percent
|
||||
}
|
||||
|
||||
export type GetQuickQuoteArgs = {
|
||||
@ -69,9 +67,12 @@ export type GetQuickQuoteArgs = {
|
||||
inputTax: Percent
|
||||
outputTax: Percent
|
||||
}
|
||||
// from https://github.com/Uniswap/routing-api/blob/main/lib/handlers/schema.ts
|
||||
|
||||
type TokenInRoute = Pick<Token, 'address' | 'chainId' | 'symbol' | 'decimals'>
|
||||
// from https://github.com/Uniswap/routing-api/blob/main/lib/handlers/schema.ts
|
||||
export type TokenInRoute = Pick<Token, 'address' | 'chainId' | 'symbol' | 'decimals'> & {
|
||||
buyFeeBps?: string
|
||||
sellFeeBps?: string
|
||||
}
|
||||
|
||||
export type V3PoolInRoute = {
|
||||
type: 'v3-pool'
|
||||
@ -201,8 +202,6 @@ export class ClassicTrade extends Trade<Currency, Currency, TradeType> {
|
||||
isUniswapXBetter: boolean | undefined
|
||||
requestId: string | undefined
|
||||
quoteMethod: QuoteMethod
|
||||
inputTax: Percent
|
||||
outputTax: Percent
|
||||
swapFee: SwapFeeInfo | undefined
|
||||
|
||||
constructor({
|
||||
@ -212,8 +211,6 @@ export class ClassicTrade extends Trade<Currency, Currency, TradeType> {
|
||||
requestId,
|
||||
quoteMethod,
|
||||
approveInfo,
|
||||
inputTax,
|
||||
outputTax,
|
||||
swapFee,
|
||||
...routes
|
||||
}: {
|
||||
@ -224,8 +221,6 @@ export class ClassicTrade extends Trade<Currency, Currency, TradeType> {
|
||||
requestId?: string
|
||||
quoteMethod: QuoteMethod
|
||||
approveInfo: ApproveInfo
|
||||
inputTax: Percent
|
||||
outputTax: Percent
|
||||
swapFee?: SwapFeeInfo
|
||||
v2Routes: {
|
||||
routev2: V2Route<Currency, Currency>
|
||||
@ -251,8 +246,6 @@ export class ClassicTrade extends Trade<Currency, Currency, TradeType> {
|
||||
this.requestId = requestId
|
||||
this.quoteMethod = quoteMethod
|
||||
this.approveInfo = approveInfo
|
||||
this.inputTax = inputTax
|
||||
this.outputTax = outputTax
|
||||
this.swapFee = swapFee
|
||||
}
|
||||
|
||||
@ -263,10 +256,6 @@ export class ClassicTrade extends Trade<Currency, Currency, TradeType> {
|
||||
return new Price({ baseAmount: this.inputAmount, quoteAmount: this.postSwapFeeOutputAmount })
|
||||
}
|
||||
|
||||
public get totalTaxRate(): Percent {
|
||||
return this.inputTax.add(this.outputTax)
|
||||
}
|
||||
|
||||
public get postSwapFeeOutputAmount(): CurrencyAmount<Currency> {
|
||||
// Routing api already applies the swap fee to the output amount for exact-in
|
||||
if (this.tradeType === TradeType.EXACT_INPUT) return this.outputAmount
|
||||
@ -275,20 +264,6 @@ export class ClassicTrade extends Trade<Currency, Currency, TradeType> {
|
||||
return this.outputAmount.subtract(swapFeeAmount)
|
||||
}
|
||||
|
||||
public get postTaxOutputAmount() {
|
||||
// Ideally we should calculate the final output amount by ammending the inputAmount based on the input tax and then applying the output tax,
|
||||
// but this isn't currently possible because V2Trade reconstructs the total inputAmount based on the swap routes
|
||||
// TODO(WEB-2761): Amend V2Trade objects in the v2-sdk to have a separate field for post-input tax routes
|
||||
return this.postSwapFeeOutputAmount.multiply(new Fraction(ONE).subtract(this.totalTaxRate))
|
||||
}
|
||||
|
||||
public minimumAmountOut(slippageTolerance: Percent, amountOut = this.outputAmount): CurrencyAmount<Currency> {
|
||||
// Since universal-router-sdk reconstructs V2Trade objects, overriding this method does not actually change the minimumAmountOut that gets submitted on-chain
|
||||
// Our current workaround is to add tax rate to slippage tolerance before we submit the trade to universal-router-sdk in useUniversalRouter.ts
|
||||
// So the purpose of this override is so the UI displays the same minimum amount out as what is submitted on-chain
|
||||
return super.minimumAmountOut(slippageTolerance.add(this.totalTaxRate), amountOut)
|
||||
}
|
||||
|
||||
// gas estimate for maybe approve + swap
|
||||
public get totalGasUseEstimateUSD(): number | undefined {
|
||||
if (this.approveInfo.needsApprove && this.gasUseEstimateUSD) {
|
||||
@ -370,11 +345,6 @@ export class DutchOrderTrade extends IDutchOrderTrade<Currency, Currency, TradeT
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
/** For UniswapX, handling token taxes in the output amount is outsourced to quoters */
|
||||
public get postTaxOutputAmount() {
|
||||
return this.outputAmount
|
||||
}
|
||||
}
|
||||
|
||||
export class PreviewTrade {
|
||||
@ -383,38 +353,19 @@ export class PreviewTrade {
|
||||
public readonly tradeType: TradeType
|
||||
public readonly inputAmount: CurrencyAmount<Currency>
|
||||
public readonly outputAmount: CurrencyAmount<Currency>
|
||||
inputTax: Percent
|
||||
outputTax: Percent
|
||||
|
||||
constructor({
|
||||
inputAmount,
|
||||
outputAmount,
|
||||
tradeType,
|
||||
inputTax,
|
||||
outputTax,
|
||||
}: {
|
||||
inputAmount: CurrencyAmount<Currency>
|
||||
outputAmount: CurrencyAmount<Currency>
|
||||
tradeType: TradeType
|
||||
inputTax: Percent
|
||||
outputTax: Percent
|
||||
}) {
|
||||
this.inputAmount = inputAmount
|
||||
this.outputAmount = outputAmount
|
||||
this.tradeType = tradeType
|
||||
this.inputTax = inputTax
|
||||
this.outputTax = outputTax
|
||||
}
|
||||
|
||||
public get totalTaxRate(): Percent {
|
||||
return this.inputTax.add(this.outputTax)
|
||||
}
|
||||
|
||||
public get postTaxOutputAmount() {
|
||||
// Ideally we should calculate the final output amount by ammending the inputAmount based on the input tax and then applying the output tax,
|
||||
// but this isn't currently possible because V2Trade reconstructs the total inputAmount based on the swap routes
|
||||
// TODO(WEB-2761): Amend V2Trade objects in the v2-sdk to have a separate field for post-input tax routes
|
||||
return this.outputAmount.multiply(new Fraction(ONE).subtract(this.totalTaxRate))
|
||||
}
|
||||
|
||||
// below methods are copied from router-sdk
|
||||
@ -440,6 +391,26 @@ export class PreviewTrade {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sell tax of the input token
|
||||
*/
|
||||
public get inputTax(): Percent {
|
||||
const inputCurrency = this.inputAmount.currency
|
||||
if (inputCurrency.isNative || !inputCurrency.wrapped.sellFeeBps) return ZERO_PERCENT
|
||||
|
||||
return new Percent(inputCurrency.wrapped.sellFeeBps.toNumber(), 10000)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buy tax of the output token
|
||||
*/
|
||||
public get outputTax(): Percent {
|
||||
const outputCurrency = this.outputAmount.currency
|
||||
if (outputCurrency.isNative || !outputCurrency.wrapped.buyFeeBps) return ZERO_PERCENT
|
||||
|
||||
return new Percent(outputCurrency.wrapped.buyFeeBps.toNumber(), 10000)
|
||||
}
|
||||
|
||||
private _executionPrice: Price<Currency, Currency> | undefined
|
||||
/**
|
||||
* The price expressed in terms of output amount/input amount.
|
||||
|
@ -2,7 +2,6 @@ import { skipToken } from '@reduxjs/toolkit/query/react'
|
||||
import { renderHook } from '@testing-library/react'
|
||||
import { CurrencyAmount, TradeType } from '@uniswap/sdk-core'
|
||||
import { AVERAGE_L1_BLOCK_TIME } from 'constants/chainInfo'
|
||||
import { ZERO_PERCENT } from 'constants/misc'
|
||||
import { USDC_MAINNET } from 'constants/tokens'
|
||||
import { useUniswapXDefaultEnabled } from 'featureFlags/flags/uniswapXDefault'
|
||||
import { useUniswapXEthOutputEnabled } from 'featureFlags/flags/uniswapXEthOutput'
|
||||
@ -79,8 +78,6 @@ const MOCK_ARGS: GetQuoteArgs = {
|
||||
uniswapXExactOutputEnabled: false,
|
||||
isUniswapXDefaultEnabled: false,
|
||||
sendPortionEnabled: true,
|
||||
inputTax: ZERO_PERCENT,
|
||||
outputTax: ZERO_PERCENT,
|
||||
}
|
||||
|
||||
describe('#useRoutingAPITrade ExactIn', () => {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { skipToken } from '@reduxjs/toolkit/query/react'
|
||||
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
|
||||
import { AVERAGE_L1_BLOCK_TIME } from 'constants/chainInfo'
|
||||
import { ZERO_PERCENT } from 'constants/misc'
|
||||
import useIsWindowVisible from 'hooks/useIsWindowVisible'
|
||||
import { useRoutingAPIArguments } from 'lib/hooks/routing/useRoutingAPIArguments'
|
||||
import ms from 'ms'
|
||||
@ -65,9 +64,7 @@ export function useRoutingAPITrade<TTradeType extends TradeType>(
|
||||
amountSpecified: CurrencyAmount<Currency> | undefined,
|
||||
otherCurrency: Currency | undefined,
|
||||
routerPreference: RouterPreference | typeof INTERNAL_ROUTER_PREFERENCE_PRICE,
|
||||
account?: string,
|
||||
inputTax = ZERO_PERCENT,
|
||||
outputTax = ZERO_PERCENT
|
||||
account?: string
|
||||
): {
|
||||
state: TradeState
|
||||
trade?: SubmittableTrade
|
||||
@ -90,8 +87,6 @@ export function useRoutingAPITrade<TTradeType extends TradeType>(
|
||||
amount: amountSpecified,
|
||||
tradeType,
|
||||
routerPreference,
|
||||
inputTax,
|
||||
outputTax,
|
||||
})
|
||||
// skip all pricing and quote requests if the window is not focused
|
||||
const isWindowVisible = useIsWindowVisible()
|
||||
|
@ -1,26 +1,69 @@
|
||||
import { ChainId, Token } from '@uniswap/sdk-core'
|
||||
import { ChainId, Currency, Token, TradeType } from '@uniswap/sdk-core'
|
||||
import { nativeOnChain } from 'constants/tokens'
|
||||
|
||||
import { PoolType } from './types'
|
||||
import { GetQuoteArgs, PoolType, RouterPreference, TokenInRoute } from './types'
|
||||
import { computeRoutes } from './utils'
|
||||
|
||||
const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC')
|
||||
const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 6, 'DAI')
|
||||
const MKR = new Token(1, '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2', 6, 'MKR')
|
||||
const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', undefined, false)
|
||||
const USDC_IN_ROUTE = toTokenInRoute(USDC)
|
||||
const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 6, 'DAI', undefined, false)
|
||||
const DAI_IN_ROUTE = toTokenInRoute(DAI)
|
||||
const MKR = new Token(1, '0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2', 6, 'MKR', undefined, false)
|
||||
const MKR_IN_ROUTE = toTokenInRoute(MKR)
|
||||
|
||||
const ETH = nativeOnChain(ChainId.MAINNET)
|
||||
const WETH_IN_ROUTE = toTokenInRoute(ETH.wrapped)
|
||||
|
||||
// helper function to make amounts more readable
|
||||
const amount = (raw: TemplateStringsArray) => (parseInt(raw[0]) * 1e6).toString()
|
||||
|
||||
const BASE_ARGS = {
|
||||
amount: '100',
|
||||
routerPreference: RouterPreference.API,
|
||||
tradeType: TradeType.EXACT_INPUT,
|
||||
needsWrapIfUniswapX: false,
|
||||
uniswapXForceSyntheticQuotes: false,
|
||||
uniswapXEthOutputEnabled: true,
|
||||
uniswapXExactOutputEnabled: true,
|
||||
userDisabledUniswapX: false,
|
||||
userOptedOutOfUniswapX: false,
|
||||
isUniswapXDefaultEnabled: false,
|
||||
sendPortionEnabled: true,
|
||||
}
|
||||
|
||||
function constructArgs(currencyIn: Currency, currencyOut: Currency): GetQuoteArgs {
|
||||
return {
|
||||
...BASE_ARGS,
|
||||
tokenInAddress: currencyIn.isNative ? 'ETH' : currencyIn.address,
|
||||
tokenInChainId: currencyIn.chainId,
|
||||
tokenInDecimals: currencyIn.decimals,
|
||||
tokenInSymbol: currencyIn.symbol,
|
||||
tokenOutAddress: currencyOut.isNative ? 'ETH' : currencyOut.address,
|
||||
tokenOutChainId: currencyOut.chainId,
|
||||
tokenOutDecimals: currencyOut.decimals,
|
||||
tokenOutSymbol: currencyOut.symbol,
|
||||
}
|
||||
}
|
||||
|
||||
function toTokenInRoute(token: Token): TokenInRoute {
|
||||
return {
|
||||
address: token.address,
|
||||
chainId: token.chainId,
|
||||
symbol: token.symbol,
|
||||
decimals: token.decimals,
|
||||
buyFeeBps: token.buyFeeBps?.toString(),
|
||||
sellFeeBps: token.sellFeeBps?.toString(),
|
||||
}
|
||||
}
|
||||
|
||||
describe('#useRoute', () => {
|
||||
it('handles empty edges and nodes', () => {
|
||||
const result = computeRoutes(USDC, DAI, [])
|
||||
const result = computeRoutes(constructArgs(USDC, DAI), [])
|
||||
expect(result).toEqual([])
|
||||
})
|
||||
|
||||
it('handles a single route trade from DAI to USDC from v3', () => {
|
||||
const result = computeRoutes(DAI, USDC, [
|
||||
const result = computeRoutes(constructArgs(DAI, USDC), [
|
||||
[
|
||||
{
|
||||
type: 'v3-pool',
|
||||
@ -31,8 +74,8 @@ describe('#useRoute', () => {
|
||||
sqrtRatioX96: '2437312313659959819381354528',
|
||||
liquidity: '10272714736694327408',
|
||||
tickCurrent: '-69633',
|
||||
tokenIn: DAI,
|
||||
tokenOut: USDC,
|
||||
tokenIn: toTokenInRoute(DAI),
|
||||
tokenOut: toTokenInRoute(USDC),
|
||||
},
|
||||
],
|
||||
])
|
||||
@ -50,21 +93,21 @@ describe('#useRoute', () => {
|
||||
})
|
||||
|
||||
it('handles a single route trade from DAI to USDC from v2', () => {
|
||||
const result = computeRoutes(DAI, USDC, [
|
||||
const result = computeRoutes(constructArgs(DAI, USDC), [
|
||||
[
|
||||
{
|
||||
type: 'v2-pool',
|
||||
address: '0x1f8F72aA9304c8B593d555F12eF6589cC3A579A2',
|
||||
amountIn: amount`1`,
|
||||
amountOut: amount`5`,
|
||||
tokenIn: DAI,
|
||||
tokenOut: USDC,
|
||||
tokenIn: DAI_IN_ROUTE,
|
||||
tokenOut: USDC_IN_ROUTE,
|
||||
reserve0: {
|
||||
token: DAI,
|
||||
token: DAI_IN_ROUTE,
|
||||
quotient: amount`100`,
|
||||
},
|
||||
reserve1: {
|
||||
token: USDC,
|
||||
token: USDC_IN_ROUTE,
|
||||
quotient: amount`200`,
|
||||
},
|
||||
},
|
||||
@ -84,21 +127,21 @@ describe('#useRoute', () => {
|
||||
})
|
||||
|
||||
it('handles a multi-route trade from DAI to USDC', () => {
|
||||
const result = computeRoutes(DAI, USDC, [
|
||||
const result = computeRoutes(constructArgs(DAI, USDC), [
|
||||
[
|
||||
{
|
||||
type: 'v2-pool',
|
||||
address: '0x1f8F72aA9304c8B593d555F12eF6589cC3A579A2',
|
||||
amountIn: amount`5`,
|
||||
amountOut: amount`6`,
|
||||
tokenIn: DAI,
|
||||
tokenOut: USDC,
|
||||
tokenIn: DAI_IN_ROUTE,
|
||||
tokenOut: USDC_IN_ROUTE,
|
||||
reserve0: {
|
||||
token: DAI,
|
||||
token: DAI_IN_ROUTE,
|
||||
quotient: amount`1000`,
|
||||
},
|
||||
reserve1: {
|
||||
token: USDC,
|
||||
token: USDC_IN_ROUTE,
|
||||
quotient: amount`500`,
|
||||
},
|
||||
},
|
||||
@ -110,8 +153,8 @@ describe('#useRoute', () => {
|
||||
amountIn: amount`10`,
|
||||
amountOut: amount`1`,
|
||||
fee: '3000',
|
||||
tokenIn: DAI,
|
||||
tokenOut: MKR,
|
||||
tokenIn: DAI_IN_ROUTE,
|
||||
tokenOut: MKR_IN_ROUTE,
|
||||
sqrtRatioX96: '2437312313659959819381354528',
|
||||
liquidity: '10272714736694327408',
|
||||
tickCurrent: '-69633',
|
||||
@ -122,8 +165,8 @@ describe('#useRoute', () => {
|
||||
amountIn: amount`1`,
|
||||
amountOut: amount`200`,
|
||||
fee: '10000',
|
||||
tokenIn: MKR,
|
||||
tokenOut: USDC,
|
||||
tokenIn: MKR_IN_ROUTE,
|
||||
tokenOut: USDC_IN_ROUTE,
|
||||
sqrtRatioX96: '2437312313659959819381354528',
|
||||
liquidity: '10272714736694327408',
|
||||
tickCurrent: '-69633',
|
||||
@ -151,7 +194,7 @@ describe('#useRoute', () => {
|
||||
})
|
||||
|
||||
it('handles a single route trade with same token pair, different fee tiers', () => {
|
||||
const result = computeRoutes(DAI, USDC, [
|
||||
const result = computeRoutes(constructArgs(DAI, USDC), [
|
||||
[
|
||||
{
|
||||
type: 'v3-pool',
|
||||
@ -159,8 +202,8 @@ describe('#useRoute', () => {
|
||||
amountIn: amount`1`,
|
||||
amountOut: amount`5`,
|
||||
fee: '500',
|
||||
tokenIn: DAI,
|
||||
tokenOut: USDC,
|
||||
tokenIn: DAI_IN_ROUTE,
|
||||
tokenOut: USDC_IN_ROUTE,
|
||||
sqrtRatioX96: '2437312313659959819381354528',
|
||||
liquidity: '10272714736694327408',
|
||||
tickCurrent: '-69633',
|
||||
@ -173,8 +216,8 @@ describe('#useRoute', () => {
|
||||
amountIn: amount`10`,
|
||||
amountOut: amount`50`,
|
||||
fee: '3000',
|
||||
tokenIn: DAI,
|
||||
tokenOut: USDC,
|
||||
tokenIn: DAI_IN_ROUTE,
|
||||
tokenOut: USDC_IN_ROUTE,
|
||||
sqrtRatioX96: '2437312313659959819381354528',
|
||||
liquidity: '10272714736694327408',
|
||||
tickCurrent: '-69633',
|
||||
@ -191,7 +234,7 @@ describe('#useRoute', () => {
|
||||
})
|
||||
|
||||
it('computes mixed routes correctly', () => {
|
||||
const result = computeRoutes(DAI, MKR, [
|
||||
const result = computeRoutes(constructArgs(DAI, MKR), [
|
||||
[
|
||||
{
|
||||
type: PoolType.V3Pool,
|
||||
@ -199,8 +242,8 @@ describe('#useRoute', () => {
|
||||
amountIn: amount`1`,
|
||||
amountOut: amount`5`,
|
||||
fee: '500',
|
||||
tokenIn: DAI,
|
||||
tokenOut: USDC,
|
||||
tokenIn: DAI_IN_ROUTE,
|
||||
tokenOut: USDC_IN_ROUTE,
|
||||
sqrtRatioX96: '2437312313659959819381354528',
|
||||
liquidity: '10272714736694327408',
|
||||
tickCurrent: '-69633',
|
||||
@ -210,14 +253,14 @@ describe('#useRoute', () => {
|
||||
address: 'x2f8F72aA9304c8B593d555F12eF6589cC3A579A2',
|
||||
amountIn: amount`10`,
|
||||
amountOut: amount`50`,
|
||||
tokenIn: USDC,
|
||||
tokenOut: MKR,
|
||||
tokenIn: USDC_IN_ROUTE,
|
||||
tokenOut: MKR_IN_ROUTE,
|
||||
reserve0: {
|
||||
token: USDC,
|
||||
token: USDC_IN_ROUTE,
|
||||
quotient: amount`100`,
|
||||
},
|
||||
reserve1: {
|
||||
token: MKR,
|
||||
token: MKR_IN_ROUTE,
|
||||
quotient: amount`200`,
|
||||
},
|
||||
},
|
||||
@ -236,7 +279,7 @@ describe('#useRoute', () => {
|
||||
it('outputs native ETH as input currency', () => {
|
||||
const WETH = ETH.wrapped
|
||||
|
||||
const result = computeRoutes(ETH, USDC, [
|
||||
const result = computeRoutes(constructArgs(ETH, USDC), [
|
||||
[
|
||||
{
|
||||
type: 'v3-pool',
|
||||
@ -247,8 +290,8 @@ describe('#useRoute', () => {
|
||||
sqrtRatioX96: '2437312313659959819381354528',
|
||||
liquidity: '10272714736694327408',
|
||||
tickCurrent: '-69633',
|
||||
tokenIn: WETH,
|
||||
tokenOut: USDC,
|
||||
tokenIn: WETH_IN_ROUTE,
|
||||
tokenOut: USDC_IN_ROUTE,
|
||||
},
|
||||
],
|
||||
])
|
||||
@ -263,7 +306,7 @@ describe('#useRoute', () => {
|
||||
|
||||
it('outputs native ETH as output currency', () => {
|
||||
const WETH = new Token(1, ETH.wrapped.address, 18, 'WETH')
|
||||
const result = computeRoutes(USDC, ETH, [
|
||||
const result = computeRoutes(constructArgs(USDC, ETH), [
|
||||
[
|
||||
{
|
||||
type: 'v3-pool',
|
||||
@ -274,8 +317,8 @@ describe('#useRoute', () => {
|
||||
sqrtRatioX96: '2437312313659959819381354528',
|
||||
liquidity: '10272714736694327408',
|
||||
tickCurrent: '-69633',
|
||||
tokenIn: USDC,
|
||||
tokenOut: WETH,
|
||||
tokenIn: USDC_IN_ROUTE,
|
||||
tokenOut: WETH_IN_ROUTE,
|
||||
},
|
||||
],
|
||||
])
|
||||
@ -290,21 +333,21 @@ describe('#useRoute', () => {
|
||||
it('outputs native ETH as input currency for v2 routes', () => {
|
||||
const WETH = ETH.wrapped
|
||||
|
||||
const result = computeRoutes(ETH, USDC, [
|
||||
const result = computeRoutes(constructArgs(ETH, USDC), [
|
||||
[
|
||||
{
|
||||
type: 'v2-pool',
|
||||
address: '0x1f8F72aA9304c8B593d555F12eF6589cC3A579A2',
|
||||
amountIn: (1e18).toString(),
|
||||
amountOut: amount`5`,
|
||||
tokenIn: WETH,
|
||||
tokenOut: USDC,
|
||||
tokenIn: WETH_IN_ROUTE,
|
||||
tokenOut: USDC_IN_ROUTE,
|
||||
reserve0: {
|
||||
token: WETH,
|
||||
token: WETH_IN_ROUTE,
|
||||
quotient: amount`100`,
|
||||
},
|
||||
reserve1: {
|
||||
token: USDC,
|
||||
token: USDC_IN_ROUTE,
|
||||
quotient: amount`200`,
|
||||
},
|
||||
},
|
||||
@ -321,21 +364,21 @@ describe('#useRoute', () => {
|
||||
|
||||
it('outputs native ETH as output currency for v2 routes', () => {
|
||||
const WETH = new Token(1, ETH.wrapped.address, 18, 'WETH')
|
||||
const result = computeRoutes(USDC, ETH, [
|
||||
const result = computeRoutes(constructArgs(USDC, ETH), [
|
||||
[
|
||||
{
|
||||
type: 'v2-pool',
|
||||
address: '0x1f8F72aA9304c8B593d555F12eF6589cC3A579A2',
|
||||
amountIn: amount`5`,
|
||||
amountOut: (1e18).toString(),
|
||||
tokenIn: USDC,
|
||||
tokenOut: WETH,
|
||||
tokenIn: USDC_IN_ROUTE,
|
||||
tokenOut: WETH_IN_ROUTE,
|
||||
reserve0: {
|
||||
token: WETH,
|
||||
token: WETH_IN_ROUTE,
|
||||
quotient: amount`100`,
|
||||
},
|
||||
reserve1: {
|
||||
token: USDC,
|
||||
token: USDC_IN_ROUTE,
|
||||
quotient: amount`200`,
|
||||
},
|
||||
},
|
||||
|
@ -26,6 +26,7 @@ import {
|
||||
SubmittableTrade,
|
||||
SwapFeeInfo,
|
||||
SwapRouterNativeAssets,
|
||||
TokenInRoute,
|
||||
TradeFillType,
|
||||
TradeResult,
|
||||
URADutchOrderQuoteData,
|
||||
@ -47,16 +48,9 @@ interface RouteResult {
|
||||
* Transforms a Routing API quote into an array of routes that can be used to
|
||||
* create a `Trade`.
|
||||
*/
|
||||
export function computeRoutes(
|
||||
currencyIn: Currency,
|
||||
currencyOut: Currency,
|
||||
routes: ClassicQuoteData['route']
|
||||
): RouteResult[] | undefined {
|
||||
export function computeRoutes(args: GetQuoteArgs, routes: ClassicQuoteData['route']): RouteResult[] | undefined {
|
||||
if (routes.length === 0) return []
|
||||
|
||||
const tokenIn = routes[0]?.[0]?.tokenIn
|
||||
const tokenOut = routes[0]?.[routes[0]?.length - 1]?.tokenOut
|
||||
if (!tokenIn || !tokenOut) throw new Error('Expected both tokenIn and tokenOut to be present')
|
||||
const [currencyIn, currencyOut] = getTradeCurrencies(args, false, routes)
|
||||
|
||||
try {
|
||||
return routes.map((route) => {
|
||||
@ -121,7 +115,11 @@ function toDutchOrderInfo(orderInfoJSON: DutchOrderInfoJSON): DutchOrderInfo {
|
||||
// Prepares the currencies used for the actual Swap (either UniswapX or Universal Router)
|
||||
// May not match `currencyIn` that the user selected because for ETH inputs in UniswapX, the actual
|
||||
// swap will use WETH.
|
||||
function getTradeCurrencies(args: GetQuoteArgs | GetQuickQuoteArgs, isUniswapXTrade: boolean): [Currency, Currency] {
|
||||
function getTradeCurrencies(
|
||||
args: GetQuoteArgs | GetQuickQuoteArgs,
|
||||
isUniswapXTrade: boolean,
|
||||
routes?: ClassicQuoteData['route']
|
||||
): [Currency, Currency] {
|
||||
const {
|
||||
tokenInAddress,
|
||||
tokenInChainId,
|
||||
@ -136,9 +134,19 @@ function getTradeCurrencies(args: GetQuoteArgs | GetQuickQuoteArgs, isUniswapXTr
|
||||
const tokenInIsNative = Object.values(SwapRouterNativeAssets).includes(tokenInAddress as SwapRouterNativeAssets)
|
||||
const tokenOutIsNative = Object.values(SwapRouterNativeAssets).includes(tokenOutAddress as SwapRouterNativeAssets)
|
||||
|
||||
const serializedTokenIn = routes?.[0]?.[0]?.tokenIn
|
||||
const serializedTokenOut = routes?.[0]?.[routes[0]?.length - 1]?.tokenOut
|
||||
|
||||
const currencyIn = tokenInIsNative
|
||||
? nativeOnChain(tokenInChainId)
|
||||
: parseToken({ address: tokenInAddress, chainId: tokenInChainId, decimals: tokenInDecimals, symbol: tokenInSymbol })
|
||||
: parseToken({
|
||||
address: tokenInAddress,
|
||||
chainId: tokenInChainId,
|
||||
decimals: tokenInDecimals,
|
||||
symbol: tokenInSymbol,
|
||||
buyFeeBps: serializedTokenIn?.buyFeeBps,
|
||||
sellFeeBps: serializedTokenIn?.sellFeeBps,
|
||||
})
|
||||
const currencyOut = tokenOutIsNative
|
||||
? nativeOnChain(tokenOutChainId)
|
||||
: parseToken({
|
||||
@ -146,6 +154,8 @@ function getTradeCurrencies(args: GetQuoteArgs | GetQuickQuoteArgs, isUniswapXTr
|
||||
chainId: tokenOutChainId,
|
||||
decimals: tokenOutDecimals,
|
||||
symbol: tokenOutSymbol,
|
||||
buyFeeBps: serializedTokenOut?.buyFeeBps,
|
||||
sellFeeBps: serializedTokenOut?.sellFeeBps,
|
||||
})
|
||||
|
||||
if (!isUniswapXTrade) {
|
||||
@ -168,8 +178,7 @@ function getSwapFee(data: ClassicQuoteData | URADutchOrderQuoteData): SwapFeeInf
|
||||
}
|
||||
|
||||
function getClassicTradeDetails(
|
||||
currencyIn: Currency,
|
||||
currencyOut: Currency,
|
||||
args: GetQuoteArgs,
|
||||
data: URAQuoteResponse
|
||||
): {
|
||||
gasUseEstimate?: number
|
||||
@ -181,54 +190,43 @@ function getClassicTradeDetails(
|
||||
const classicQuote =
|
||||
data.routing === URAQuoteType.CLASSIC ? data.quote : data.allQuotes.find(isClassicQuoteResponse)?.quote
|
||||
|
||||
if (!classicQuote) return {}
|
||||
if (!classicQuote) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
gasUseEstimate: classicQuote.gasUseEstimate ? parseFloat(classicQuote.gasUseEstimate) : undefined,
|
||||
gasUseEstimateUSD: classicQuote.gasUseEstimateUSD ? parseFloat(classicQuote.gasUseEstimateUSD) : undefined,
|
||||
blockNumber: classicQuote.blockNumber,
|
||||
routes: computeRoutes(currencyIn, currencyOut, classicQuote.route),
|
||||
routes: computeRoutes(args, classicQuote.route),
|
||||
swapFee: getSwapFee(classicQuote),
|
||||
}
|
||||
}
|
||||
|
||||
export function transformQuickRouteToTrade(args: GetQuickQuoteArgs, data: QuickRouteResponse): PreviewTrade {
|
||||
const { amount, tradeType, inputTax, outputTax } = args
|
||||
const { amount, tradeType } = args
|
||||
const [currencyIn, currencyOut] = getTradeCurrencies(args, false)
|
||||
const [rawAmountIn, rawAmountOut] =
|
||||
data.tradeType === 'EXACT_IN' ? [amount, data.quote.amount] : [data.quote.amount, amount]
|
||||
const inputAmount = CurrencyAmount.fromRawAmount(currencyIn, rawAmountIn)
|
||||
const outputAmount = CurrencyAmount.fromRawAmount(currencyOut, rawAmountOut)
|
||||
|
||||
return new PreviewTrade({ inputAmount, outputAmount, tradeType, inputTax, outputTax })
|
||||
return new PreviewTrade({ inputAmount, outputAmount, tradeType })
|
||||
}
|
||||
|
||||
export async function transformRoutesToTrade(
|
||||
export async function transformQuoteToTrade(
|
||||
args: GetQuoteArgs,
|
||||
data: URAQuoteResponse,
|
||||
quoteMethod: QuoteMethod
|
||||
): Promise<TradeResult> {
|
||||
const {
|
||||
tradeType,
|
||||
needsWrapIfUniswapX,
|
||||
routerPreference,
|
||||
account,
|
||||
amount,
|
||||
isUniswapXDefaultEnabled,
|
||||
inputTax,
|
||||
outputTax,
|
||||
} = args
|
||||
const { tradeType, needsWrapIfUniswapX, routerPreference, account, amount, isUniswapXDefaultEnabled } = args
|
||||
|
||||
const showUniswapXTrade =
|
||||
data.routing === URAQuoteType.DUTCH_LIMIT &&
|
||||
(routerPreference === RouterPreference.X || (isUniswapXDefaultEnabled && routerPreference === RouterPreference.API))
|
||||
|
||||
const [currencyIn, currencyOut] = getTradeCurrencies(args, showUniswapXTrade)
|
||||
const { gasUseEstimateUSD, blockNumber, routes, gasUseEstimate, swapFee } = getClassicTradeDetails(
|
||||
currencyIn,
|
||||
currencyOut,
|
||||
data
|
||||
)
|
||||
|
||||
const { gasUseEstimateUSD, blockNumber, routes, gasUseEstimate, swapFee } = getClassicTradeDetails(args, data)
|
||||
|
||||
// If the top-level URA quote type is DUTCH_LIMIT, then UniswapX is better for the user
|
||||
const isUniswapXBetter = data.routing === URAQuoteType.DUTCH_LIMIT
|
||||
@ -272,8 +270,6 @@ export async function transformRoutesToTrade(
|
||||
isUniswapXBetter,
|
||||
requestId: data.quote.requestId,
|
||||
quoteMethod,
|
||||
inputTax,
|
||||
outputTax,
|
||||
swapFee,
|
||||
})
|
||||
|
||||
@ -310,8 +306,10 @@ export async function transformRoutesToTrade(
|
||||
return { state: QuoteState.SUCCESS, trade: classicTrade }
|
||||
}
|
||||
|
||||
function parseToken({ address, chainId, decimals, symbol }: ClassicQuoteData['route'][0][0]['tokenIn']): Token {
|
||||
return new Token(chainId, address, parseInt(decimals.toString()), symbol)
|
||||
function parseToken({ address, chainId, decimals, symbol, buyFeeBps, sellFeeBps }: TokenInRoute): Token {
|
||||
const buyFeeBpsBN = buyFeeBps ? BigNumber.from(buyFeeBps) : undefined
|
||||
const sellFeeBpsBN = sellFeeBps ? BigNumber.from(sellFeeBps) : undefined
|
||||
return new Token(chainId, address, parseInt(decimals.toString()), symbol, undefined, false, buyFeeBpsBN, sellFeeBpsBN)
|
||||
}
|
||||
|
||||
function parsePool({ fee, sqrtRatioX96, liquidity, tickCurrent, tokenIn, tokenOut }: V3PoolInRoute): Pool {
|
||||
|
@ -2,7 +2,6 @@ import { Trans } from '@lingui/macro'
|
||||
import { ChainId, Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import { useConnectionReady } from 'connection/eagerlyConnect'
|
||||
import { useFotAdjustmentsEnabled } from 'featureFlags/flags/fotAdjustments'
|
||||
import useAutoSlippageTolerance from 'hooks/useAutoSlippageTolerance'
|
||||
import { useDebouncedTrade } from 'hooks/useDebouncedTrade'
|
||||
import { useSwapTaxes } from 'hooks/useSwapTaxes'
|
||||
@ -112,15 +111,14 @@ export function useDerivedSwapInfo(state: SwapState, chainId: ChainId | undefine
|
||||
const inputCurrency = useCurrency(inputCurrencyId, chainId)
|
||||
const outputCurrency = useCurrency(outputCurrencyId, chainId)
|
||||
|
||||
const fotAdjustmentsEnabled = useFotAdjustmentsEnabled()
|
||||
const { inputTax, outputTax } = useSwapTaxes(
|
||||
inputCurrency?.isToken && fotAdjustmentsEnabled ? inputCurrency.address : undefined,
|
||||
outputCurrency?.isToken && fotAdjustmentsEnabled ? outputCurrency.address : undefined
|
||||
)
|
||||
|
||||
const recipientLookup = useENS(recipient ?? undefined)
|
||||
const to: string | null = (recipient === null ? account : recipientLookup.address) ?? null
|
||||
|
||||
const { inputTax, outputTax } = useSwapTaxes(
|
||||
inputCurrency?.isToken ? inputCurrency.address : undefined,
|
||||
outputCurrency?.isToken ? outputCurrency.address : undefined
|
||||
)
|
||||
|
||||
const relevantTokenBalances = useCurrencyBalances(
|
||||
account ?? undefined,
|
||||
useMemo(() => [inputCurrency ?? undefined, outputCurrency ?? undefined], [inputCurrency, outputCurrency])
|
||||
@ -137,9 +135,7 @@ export function useDerivedSwapInfo(state: SwapState, chainId: ChainId | undefine
|
||||
parsedAmount,
|
||||
(isExactIn ? outputCurrency : inputCurrency) ?? undefined,
|
||||
undefined,
|
||||
account,
|
||||
inputTax,
|
||||
outputTax
|
||||
account
|
||||
)
|
||||
|
||||
const { data: outputFeeFiatValue } = useUSDPrice(
|
||||
@ -222,9 +218,9 @@ export function useDerivedSwapInfo(state: SwapState, chainId: ChainId | undefine
|
||||
trade,
|
||||
autoSlippage,
|
||||
allowedSlippage,
|
||||
outputFeeFiatValue,
|
||||
inputTax,
|
||||
outputTax,
|
||||
outputFeeFiatValue,
|
||||
}),
|
||||
[
|
||||
allowedSlippage,
|
||||
@ -232,11 +228,11 @@ export function useDerivedSwapInfo(state: SwapState, chainId: ChainId | undefine
|
||||
currencies,
|
||||
currencyBalances,
|
||||
inputError,
|
||||
inputTax,
|
||||
outputFeeFiatValue,
|
||||
outputTax,
|
||||
parsedAmount,
|
||||
trade,
|
||||
inputTax,
|
||||
outputTax,
|
||||
]
|
||||
)
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ import { ChainId, CurrencyAmount, Percent, Token, TradeType } from '@uniswap/sdk
|
||||
// eslint-disable-next-line @typescript-eslint/no-restricted-imports
|
||||
import { V3Route } from '@uniswap/smart-order-router'
|
||||
import { FeeAmount, Pool } from '@uniswap/v3-sdk'
|
||||
import { ZERO_PERCENT } from 'constants/misc'
|
||||
import { nativeOnChain } from 'constants/tokens'
|
||||
import { BigNumber } from 'ethers/lib/ethers'
|
||||
import JSBI from 'jsbi'
|
||||
@ -49,8 +48,6 @@ export const TEST_TRADE_EXACT_INPUT = new ClassicTrade({
|
||||
gasUseEstimateUSD: 1.0,
|
||||
approveInfo: { needsApprove: false },
|
||||
quoteMethod: QuoteMethod.CLIENT_SIDE_FALLBACK,
|
||||
inputTax: ZERO_PERCENT,
|
||||
outputTax: ZERO_PERCENT,
|
||||
})
|
||||
|
||||
export const TEST_TRADE_EXACT_INPUT_API = new ClassicTrade({
|
||||
@ -66,8 +63,6 @@ export const TEST_TRADE_EXACT_INPUT_API = new ClassicTrade({
|
||||
gasUseEstimateUSD: 1.0,
|
||||
approveInfo: { needsApprove: false },
|
||||
quoteMethod: QuoteMethod.ROUTING_API,
|
||||
inputTax: ZERO_PERCENT,
|
||||
outputTax: ZERO_PERCENT,
|
||||
})
|
||||
|
||||
export const TEST_TRADE_EXACT_OUTPUT = new ClassicTrade({
|
||||
@ -82,8 +77,6 @@ export const TEST_TRADE_EXACT_OUTPUT = new ClassicTrade({
|
||||
tradeType: TradeType.EXACT_OUTPUT,
|
||||
quoteMethod: QuoteMethod.CLIENT_SIDE_FALLBACK,
|
||||
approveInfo: { needsApprove: false },
|
||||
inputTax: ZERO_PERCENT,
|
||||
outputTax: ZERO_PERCENT,
|
||||
})
|
||||
|
||||
export const TEST_ALLOWED_SLIPPAGE = new Percent(2, 100)
|
||||
@ -127,11 +120,29 @@ export const TEST_DUTCH_TRADE_ETH_INPUT = new DutchOrderTrade({
|
||||
slippageTolerance: new Percent(5, 100),
|
||||
})
|
||||
|
||||
const SELL_FEE_TOKEN = new Token(
|
||||
1,
|
||||
'0x0000000000000000000000000000000000000001',
|
||||
18,
|
||||
'ABC',
|
||||
'Abc',
|
||||
false,
|
||||
undefined,
|
||||
BigNumber.from(300)
|
||||
)
|
||||
const TEST_POOL_FOT_1 = new Pool(
|
||||
SELL_FEE_TOKEN,
|
||||
TEST_TOKEN_2,
|
||||
FeeAmount.HIGH,
|
||||
'2437312313659959819381354528',
|
||||
'10272714736694327408',
|
||||
-69633
|
||||
)
|
||||
export const TEST_TRADE_FEE_ON_SELL = new ClassicTrade({
|
||||
v3Routes: [
|
||||
{
|
||||
routev3: new V3Route([TEST_POOL_12], TEST_TOKEN_1, TEST_TOKEN_2),
|
||||
inputAmount: toCurrencyAmount(TEST_TOKEN_1, 1000),
|
||||
routev3: new V3Route([TEST_POOL_FOT_1], SELL_FEE_TOKEN, TEST_TOKEN_2),
|
||||
inputAmount: toCurrencyAmount(SELL_FEE_TOKEN, 1000),
|
||||
outputAmount: toCurrencyAmount(TEST_TOKEN_2, 1000),
|
||||
},
|
||||
],
|
||||
@ -140,16 +151,32 @@ export const TEST_TRADE_FEE_ON_SELL = new ClassicTrade({
|
||||
gasUseEstimateUSD: 1.0,
|
||||
approveInfo: { needsApprove: false },
|
||||
quoteMethod: QuoteMethod.ROUTING_API,
|
||||
inputTax: new Percent(3, 100),
|
||||
outputTax: ZERO_PERCENT,
|
||||
})
|
||||
|
||||
const BUY_FEE_TOKEN = new Token(
|
||||
1,
|
||||
'0x0000000000000000000000000000000000000002',
|
||||
18,
|
||||
'DEF',
|
||||
'Def',
|
||||
false,
|
||||
BigNumber.from(300),
|
||||
undefined
|
||||
)
|
||||
const TEST_POOL_FOT_2 = new Pool(
|
||||
TEST_TOKEN_1,
|
||||
BUY_FEE_TOKEN,
|
||||
FeeAmount.HIGH,
|
||||
'2437312313659959819381354528',
|
||||
'10272714736694327408',
|
||||
-69633
|
||||
)
|
||||
export const TEST_TRADE_FEE_ON_BUY = new ClassicTrade({
|
||||
v3Routes: [
|
||||
{
|
||||
routev3: new V3Route([TEST_POOL_12], TEST_TOKEN_1, TEST_TOKEN_2),
|
||||
routev3: new V3Route([TEST_POOL_FOT_2], TEST_TOKEN_1, BUY_FEE_TOKEN),
|
||||
inputAmount: toCurrencyAmount(TEST_TOKEN_1, 1000),
|
||||
outputAmount: toCurrencyAmount(TEST_TOKEN_2, 1000),
|
||||
outputAmount: toCurrencyAmount(BUY_FEE_TOKEN, 1000),
|
||||
},
|
||||
],
|
||||
v2Routes: [],
|
||||
@ -157,14 +184,10 @@ export const TEST_TRADE_FEE_ON_BUY = new ClassicTrade({
|
||||
gasUseEstimateUSD: 1.0,
|
||||
approveInfo: { needsApprove: false },
|
||||
quoteMethod: QuoteMethod.ROUTING_API,
|
||||
inputTax: ZERO_PERCENT,
|
||||
outputTax: new Percent(3, 100),
|
||||
})
|
||||
|
||||
export const PREVIEW_EXACT_IN_TRADE = new PreviewTrade({
|
||||
inputAmount: toCurrencyAmount(TEST_TOKEN_1, 1000),
|
||||
outputAmount: toCurrencyAmount(TEST_TOKEN_2, 1000),
|
||||
tradeType: TradeType.EXACT_INPUT,
|
||||
inputTax: new Percent(0, 100),
|
||||
outputTax: new Percent(0, 100),
|
||||
})
|
||||
|
66
yarn.lock
66
yarn.lock
@ -6112,18 +6112,18 @@
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/redux-multicall/-/redux-multicall-1.1.8.tgz#9cc5090305b10df68fb6162eb1ba7c2c762f5e7f"
|
||||
integrity sha512-LttOBVJuoRNC6N4MHsb5dF2GszLsj1ddPKKccEw1XOX17bGrFdm2A6GwKgES+v+Hj3lluDbQL6atcQtymP21iw==
|
||||
|
||||
"@uniswap/router-sdk@^1.6.0":
|
||||
version "1.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/router-sdk/-/router-sdk-1.6.0.tgz#2f51dbba1b01467244b59500ed0da8aa84323f8c"
|
||||
integrity sha512-onpAzcvEnrsm8tUtu49IrR9EP3n9j0IDpGc0Ee3FDDkVgXrp9cIrAADC+yb56vgLtJFnshbhyIdjXLMIzWe0Gw==
|
||||
"@uniswap/router-sdk@^1.6.0", "@uniswap/router-sdk@^1.7.1":
|
||||
version "1.7.1"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/router-sdk/-/router-sdk-1.7.1.tgz#642d5804299cd50b1a3ba2fa0a87963320fb7f93"
|
||||
integrity sha512-uBN9QX3t5lPLkxlkPoQPZpd0eN+GA0Ab9nq1pcPk/XDFuRnRxxVF629Ecz2SfTVm0gooOPO3aU3ETgyB3vuhYA==
|
||||
dependencies:
|
||||
"@ethersproject/abi" "^5.5.0"
|
||||
"@uniswap/sdk-core" "^4"
|
||||
"@uniswap/swap-router-contracts" "1.1.0"
|
||||
"@uniswap/sdk-core" "^4.0.7"
|
||||
"@uniswap/swap-router-contracts" "^1.1.0"
|
||||
"@uniswap/v2-sdk" "^3.2.0"
|
||||
"@uniswap/v3-sdk" "^3.10.0"
|
||||
|
||||
"@uniswap/sdk-core@4.0.7", "@uniswap/sdk-core@>= 3", "@uniswap/sdk-core@^4", "@uniswap/sdk-core@^4.0.0", "@uniswap/sdk-core@^4.0.2", "@uniswap/sdk-core@^4.0.3", "@uniswap/sdk-core@^4.0.6":
|
||||
"@uniswap/sdk-core@4.0.7", "@uniswap/sdk-core@>= 3", "@uniswap/sdk-core@^4", "@uniswap/sdk-core@^4.0.0", "@uniswap/sdk-core@^4.0.2", "@uniswap/sdk-core@^4.0.3", "@uniswap/sdk-core@^4.0.6", "@uniswap/sdk-core@^4.0.7":
|
||||
version "4.0.7"
|
||||
resolved "https://registry.npmjs.org/@uniswap/sdk-core/-/sdk-core-4.0.7.tgz#90dfd070d7e44494234618af398da158363ae827"
|
||||
integrity sha512-jscx7KUIWzQatcL5PHY6xy0gEL9IGQcL5h/obxzX9foP2KoNk9cq66Ia8I2Kvpa7zBcPOeW1hU0hJNBq6CzcIQ==
|
||||
@ -6163,26 +6163,15 @@
|
||||
node-cache "^5.1.2"
|
||||
stats-lite "^2.2.0"
|
||||
|
||||
"@uniswap/swap-router-contracts@1.1.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/swap-router-contracts/-/swap-router-contracts-1.1.0.tgz#e027b14d4c172f231c53c48e1fd708a78d7d94d8"
|
||||
integrity sha512-GPmpx1lvjXWloB95+YUabr3UHJYr3scnSS8EzaNXnNrIz9nYZ+XQcMaJxOKe85Yi7IfcUQpj0HzD2TW99dtolA==
|
||||
dependencies:
|
||||
"@openzeppelin/contracts" "3.4.1-solc-0.7-2"
|
||||
"@uniswap/v2-core" "1.0.1"
|
||||
"@uniswap/v3-core" "1.0.0"
|
||||
"@uniswap/v3-periphery" "1.3.0"
|
||||
hardhat-watcher "^2.1.1"
|
||||
|
||||
"@uniswap/swap-router-contracts@^1.2.1", "@uniswap/swap-router-contracts@^1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/swap-router-contracts/-/swap-router-contracts-1.3.0.tgz#8d555ca6d74b888d6e02a26ebb806ce315605f1f"
|
||||
integrity sha512-iKvCuRkHXEe0EMjOf8HFUISTIhlxI57kKFllf3C3PUIE0HmwxrayyoflwAz5u/TRsFGYqJ9IjX2UgzLCsrNa5A==
|
||||
"@uniswap/swap-router-contracts@^1.1.0", "@uniswap/swap-router-contracts@^1.2.1", "@uniswap/swap-router-contracts@^1.3.0":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/swap-router-contracts/-/swap-router-contracts-1.3.1.tgz#0ebbb93eb578625618ed9489872de381f9c66fb4"
|
||||
integrity sha512-mh/YNbwKb7Mut96VuEtL+Z5bRe0xVIbjjiryn+iMMrK2sFKhR4duk/86mEz0UO5gSx4pQIw9G5276P5heY/7Rg==
|
||||
dependencies:
|
||||
"@openzeppelin/contracts" "3.4.2-solc-0.7"
|
||||
"@uniswap/v2-core" "1.0.1"
|
||||
"@uniswap/v3-core" "1.0.0"
|
||||
"@uniswap/v3-periphery" "1.4.1"
|
||||
"@uniswap/v2-core" "^1.0.1"
|
||||
"@uniswap/v3-core" "^1.0.0"
|
||||
"@uniswap/v3-periphery" "^1.4.4"
|
||||
dotenv "^14.2.0"
|
||||
hardhat-watcher "^2.1.1"
|
||||
|
||||
@ -6259,34 +6248,21 @@
|
||||
resolved "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz"
|
||||
integrity sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==
|
||||
|
||||
"@uniswap/v3-core@^1.0.1":
|
||||
"@uniswap/v3-core@^1.0.0", "@uniswap/v3-core@^1.0.1":
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/v3-core/-/v3-core-1.0.1.tgz#b6d2bdc6ba3c3fbd610bdc502395d86cd35264a0"
|
||||
integrity sha512-7pVk4hEm00j9tc71Y9+ssYpO6ytkeI0y7WE9P6UcmNzhxPePwyAxImuhVsTqWK9YFvzgtvzJHi64pBl4jUzKMQ==
|
||||
|
||||
"@uniswap/v3-periphery@1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.3.0.tgz#37f0a1ef6025221722e50e9f3f2009c2d5d6e4ec"
|
||||
integrity sha512-HjHdI5RkjBl8zz3bqHShrbULFoZSrjbbrRHoO2vbzn+WRzTa6xY4PWphZv2Tlcb38YEKfKHp6NPl5hVedac8uw==
|
||||
dependencies:
|
||||
"@openzeppelin/contracts" "3.4.1-solc-0.7-2"
|
||||
"@uniswap/lib" "^4.0.1-alpha"
|
||||
"@uniswap/v2-core" "1.0.1"
|
||||
"@uniswap/v3-core" "1.0.0"
|
||||
base64-sol "1.0.1"
|
||||
hardhat-watcher "^2.1.1"
|
||||
|
||||
"@uniswap/v3-periphery@1.4.1", "@uniswap/v3-periphery@^1.0.1", "@uniswap/v3-periphery@^1.1.1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.4.1.tgz#b90f08b7386163c0abfd7258831caef6339c7862"
|
||||
integrity sha512-Ab0ZCKOQrQMKIcpBTezTsEhWfQjItd0TtkCG8mPhoQu+wC67nPaf4hYUhM6wGHeFUmDiYY5MpEQuokB0ENvoTg==
|
||||
"@uniswap/v3-periphery@^1.0.1", "@uniswap/v3-periphery@^1.1.1", "@uniswap/v3-periphery@^1.4.4":
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.4.4.tgz#d2756c23b69718173c5874f37fd4ad57d2f021b7"
|
||||
integrity sha512-S4+m+wh8HbWSO3DKk4LwUCPZJTpCugIsHrWR86m/OrUyvSqGDTXKFfc2sMuGXCZrD1ZqO3rhQsKgdWg3Hbb2Kw==
|
||||
dependencies:
|
||||
"@openzeppelin/contracts" "3.4.2-solc-0.7"
|
||||
"@uniswap/lib" "^4.0.1-alpha"
|
||||
"@uniswap/v2-core" "1.0.1"
|
||||
"@uniswap/v3-core" "1.0.0"
|
||||
"@uniswap/v2-core" "^1.0.1"
|
||||
"@uniswap/v3-core" "^1.0.0"
|
||||
base64-sol "1.0.1"
|
||||
hardhat-watcher "^2.1.1"
|
||||
|
||||
"@uniswap/v3-sdk@^3.10.0":
|
||||
version "3.10.0"
|
||||
|
Loading…
Reference in New Issue
Block a user