feat: Support UniswapX exact out trades (#7225)

* add feature flag for uniswapx exact out trades

* dont route PRICE lookups through uniswapx

* add e2e test
This commit is contained in:
Tina 2023-08-25 15:00:22 -04:00 committed by GitHub
parent ce8105bf08
commit bb51be545b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 46 additions and 3 deletions

@ -79,7 +79,7 @@ describe('UniswapX Orders', () => {
cy.visit(`/swap/?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`)
})
it('can swap using uniswapX', () => {
it('can swap exact-in trades using uniswapX', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')
cy.contains('Try it now').click()
@ -98,6 +98,25 @@ describe('UniswapX Orders', () => {
cy.contains('Swapped')
})
it('can swap exact-out trades using uniswapX', () => {
// Setup a swap
cy.get('#swap-currency-output .token-amount-input').type('300')
cy.contains('Try it now').click()
// Submit uniswapx order signature
cy.get('#swap-button').click()
cy.contains('Confirm swap').click()
cy.wait('@eth_signTypedData_v4')
cy.contains('Swap submitted')
cy.contains('Learn more about swapping with UniswapX')
// Return filled order status from uniswapx api
cy.intercept(OrderStatusEndpoint, { fixture: 'uniswapx/filledStatusResponse.json' })
// Verify swap success
cy.contains('Swapped')
})
it('renders proper view if uniswapx order expires', () => {
// Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300')

@ -6,6 +6,7 @@ import { useMultichainUXFlag } from 'featureFlags/flags/multichainUx'
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
import { UniswapXVariant, useUniswapXFlag } from 'featureFlags/flags/uniswapx'
import { useUniswapXEthOutputFlag } from 'featureFlags/flags/uniswapXEthOutput'
import { useUniswapXExactOutputFlag } from 'featureFlags/flags/uniswapXExactOutput'
import { useUniswapXSyntheticQuoteFlag } from 'featureFlags/flags/uniswapXUseSyntheticQuote'
import { useUpdateAtom } from 'jotai/utils'
import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react'
@ -231,6 +232,12 @@ export default function FeatureFlagModal() {
featureFlag={FeatureFlag.uniswapXEthOutputEnabled}
label="Enable eth output for UniswapX orders"
/>
<FeatureFlagOption
variant={BaseVariant}
value={useUniswapXExactOutputFlag()}
featureFlag={FeatureFlag.uniswapXExactOutputEnabled}
label="Enable exact output for UniswapX orders"
/>
<FeatureFlagOption
variant={BaseVariant}
value={useCurrencyConversionFlag()}

@ -0,0 +1,9 @@
import { BaseVariant, FeatureFlag, useBaseFlag } from '../index'
export function useUniswapXExactOutputFlag(): BaseVariant {
return useBaseFlag(FeatureFlag.uniswapXExactOutputEnabled)
}
export function useUniswapXExactOutputEnabled(): boolean {
return useUniswapXExactOutputFlag() === BaseVariant.Enabled
}

@ -14,6 +14,7 @@ export enum FeatureFlag {
uniswapXSyntheticQuote = 'uniswapx_synthetic_quote',
forceUniswapXOn = 'uniswapx_force_on', // forces routing-api's feature flag for uniswapx to turn on as well
uniswapXEthOutputEnabled = 'uniswapx_eth_output_enabled',
uniswapXExactOutputEnabled = 'uniswapx_exact_output_enabled',
multichainUX = 'multichain_ux',
currencyConversion = 'currency_conversion',
fotAdjustedmentsEnabled = 'fot_adjustments_enabled',

@ -4,6 +4,7 @@ import { useForceUniswapXOn } from 'featureFlags/flags/forceUniswapXOn'
import { useFotAdjustmentsEnabled } from 'featureFlags/flags/fotAdjustments'
import { useUniswapXEnabled } from 'featureFlags/flags/uniswapx'
import { useUniswapXEthOutputEnabled } from 'featureFlags/flags/uniswapXEthOutput'
import { useUniswapXExactOutputEnabled } from 'featureFlags/flags/uniswapXExactOutput'
import { useUniswapXSyntheticQuoteEnabled } from 'featureFlags/flags/uniswapXUseSyntheticQuote'
import { useMemo } from 'react'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from 'state/routing/types'
@ -35,6 +36,7 @@ export function useRoutingAPIArguments({
const forceUniswapXOn = useForceUniswapXOn()
const userDisabledUniswapX = useUserDisabledUniswapX()
const uniswapXEthOutputEnabled = useUniswapXEthOutputEnabled()
const uniswapXExactOutputEnabled = useUniswapXExactOutputEnabled()
const fotAdjustmentsEnabled = useFotAdjustmentsEnabled()
return useMemo(
@ -60,6 +62,7 @@ export function useRoutingAPIArguments({
forceUniswapXOn,
userDisabledUniswapX,
uniswapXEthOutputEnabled,
uniswapXExactOutputEnabled,
fotAdjustmentsEnabled,
},
[
@ -70,6 +73,7 @@ export function useRoutingAPIArguments({
tokenOut,
tradeType,
uniswapXEnabled,
uniswapXExactOutputEnabled,
uniswapXForceSyntheticQuotes,
forceUniswapXOn,
userDisabledUniswapX,

@ -51,6 +51,7 @@ function getRoutingAPIConfig(args: GetQuoteArgs): RoutingConfig {
tokenInChainId,
uniswapXForceSyntheticQuotes,
uniswapXEthOutputEnabled,
uniswapXExactOutputEnabled,
routerPreference,
} = args
@ -76,8 +77,9 @@ function getRoutingAPIConfig(args: GetQuoteArgs): RoutingConfig {
!args.uniswapXEnabled ||
(args.userDisabledUniswapX && routerPreference !== RouterPreference.X) ||
(tokenOutIsNative && !uniswapXEthOutputEnabled) ||
tradeType === TradeType.EXACT_OUTPUT ||
!isUniswapXSupportedChain(tokenInChainId)
(!uniswapXExactOutputEnabled && tradeType === TradeType.EXACT_OUTPUT) ||
!isUniswapXSupportedChain(tokenInChainId) ||
routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE
) {
return [classic]
}

@ -45,6 +45,7 @@ export interface GetQuoteArgs {
uniswapXEnabled: boolean
uniswapXForceSyntheticQuotes: boolean
uniswapXEthOutputEnabled: boolean
uniswapXExactOutputEnabled: boolean
forceUniswapXOn: boolean
userDisabledUniswapX: boolean
fotAdjustmentsEnabled: boolean