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