Commit bb51be54 authored by Tina's avatar Tina Committed by GitHub

feat: Support UniswapX exact out trades (#7225)

* add feature flag for uniswapx exact out trades

* dont route PRICE lookups through uniswapx

* add e2e test
parent ce8105bf
...@@ -79,7 +79,7 @@ describe('UniswapX Orders', () => { ...@@ -79,7 +79,7 @@ describe('UniswapX Orders', () => {
cy.visit(`/swap/?inputCurrency=${USDC_MAINNET.address}&outputCurrency=${DAI.address}`) 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 // Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300') cy.get('#swap-currency-input .token-amount-input').type('300')
cy.contains('Try it now').click() cy.contains('Try it now').click()
...@@ -98,6 +98,25 @@ describe('UniswapX Orders', () => { ...@@ -98,6 +98,25 @@ describe('UniswapX Orders', () => {
cy.contains('Swapped') 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', () => { it('renders proper view if uniswapx order expires', () => {
// Setup a swap // Setup a swap
cy.get('#swap-currency-input .token-amount-input').type('300') cy.get('#swap-currency-input .token-amount-input').type('300')
......
...@@ -6,6 +6,7 @@ import { useMultichainUXFlag } from 'featureFlags/flags/multichainUx' ...@@ -6,6 +6,7 @@ import { useMultichainUXFlag } from 'featureFlags/flags/multichainUx'
import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc' import { TraceJsonRpcVariant, useTraceJsonRpcFlag } from 'featureFlags/flags/traceJsonRpc'
import { UniswapXVariant, useUniswapXFlag } from 'featureFlags/flags/uniswapx' import { UniswapXVariant, useUniswapXFlag } from 'featureFlags/flags/uniswapx'
import { useUniswapXEthOutputFlag } from 'featureFlags/flags/uniswapXEthOutput' import { useUniswapXEthOutputFlag } from 'featureFlags/flags/uniswapXEthOutput'
import { useUniswapXExactOutputFlag } from 'featureFlags/flags/uniswapXExactOutput'
import { useUniswapXSyntheticQuoteFlag } from 'featureFlags/flags/uniswapXUseSyntheticQuote' import { useUniswapXSyntheticQuoteFlag } from 'featureFlags/flags/uniswapXUseSyntheticQuote'
import { useUpdateAtom } from 'jotai/utils' import { useUpdateAtom } from 'jotai/utils'
import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react' import { Children, PropsWithChildren, ReactElement, ReactNode, useCallback, useState } from 'react'
...@@ -231,6 +232,12 @@ export default function FeatureFlagModal() { ...@@ -231,6 +232,12 @@ export default function FeatureFlagModal() {
featureFlag={FeatureFlag.uniswapXEthOutputEnabled} featureFlag={FeatureFlag.uniswapXEthOutputEnabled}
label="Enable eth output for UniswapX orders" label="Enable eth output for UniswapX orders"
/> />
<FeatureFlagOption
variant={BaseVariant}
value={useUniswapXExactOutputFlag()}
featureFlag={FeatureFlag.uniswapXExactOutputEnabled}
label="Enable exact output for UniswapX orders"
/>
<FeatureFlagOption <FeatureFlagOption
variant={BaseVariant} variant={BaseVariant}
value={useCurrencyConversionFlag()} value={useCurrencyConversionFlag()}
......
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 { ...@@ -14,6 +14,7 @@ export enum FeatureFlag {
uniswapXSyntheticQuote = 'uniswapx_synthetic_quote', uniswapXSyntheticQuote = 'uniswapx_synthetic_quote',
forceUniswapXOn = 'uniswapx_force_on', // forces routing-api's feature flag for uniswapx to turn on as well forceUniswapXOn = 'uniswapx_force_on', // forces routing-api's feature flag for uniswapx to turn on as well
uniswapXEthOutputEnabled = 'uniswapx_eth_output_enabled', uniswapXEthOutputEnabled = 'uniswapx_eth_output_enabled',
uniswapXExactOutputEnabled = 'uniswapx_exact_output_enabled',
multichainUX = 'multichain_ux', multichainUX = 'multichain_ux',
currencyConversion = 'currency_conversion', currencyConversion = 'currency_conversion',
fotAdjustedmentsEnabled = 'fot_adjustments_enabled', fotAdjustedmentsEnabled = 'fot_adjustments_enabled',
......
...@@ -4,6 +4,7 @@ import { useForceUniswapXOn } from 'featureFlags/flags/forceUniswapXOn' ...@@ -4,6 +4,7 @@ import { useForceUniswapXOn } from 'featureFlags/flags/forceUniswapXOn'
import { useFotAdjustmentsEnabled } from 'featureFlags/flags/fotAdjustments' import { useFotAdjustmentsEnabled } from 'featureFlags/flags/fotAdjustments'
import { useUniswapXEnabled } from 'featureFlags/flags/uniswapx' import { useUniswapXEnabled } from 'featureFlags/flags/uniswapx'
import { useUniswapXEthOutputEnabled } from 'featureFlags/flags/uniswapXEthOutput' import { useUniswapXEthOutputEnabled } from 'featureFlags/flags/uniswapXEthOutput'
import { useUniswapXExactOutputEnabled } from 'featureFlags/flags/uniswapXExactOutput'
import { useUniswapXSyntheticQuoteEnabled } from 'featureFlags/flags/uniswapXUseSyntheticQuote' import { useUniswapXSyntheticQuoteEnabled } from 'featureFlags/flags/uniswapXUseSyntheticQuote'
import { useMemo } from 'react' import { useMemo } from 'react'
import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from 'state/routing/types' import { GetQuoteArgs, INTERNAL_ROUTER_PREFERENCE_PRICE, RouterPreference } from 'state/routing/types'
...@@ -35,6 +36,7 @@ export function useRoutingAPIArguments({ ...@@ -35,6 +36,7 @@ export function useRoutingAPIArguments({
const forceUniswapXOn = useForceUniswapXOn() const forceUniswapXOn = useForceUniswapXOn()
const userDisabledUniswapX = useUserDisabledUniswapX() const userDisabledUniswapX = useUserDisabledUniswapX()
const uniswapXEthOutputEnabled = useUniswapXEthOutputEnabled() const uniswapXEthOutputEnabled = useUniswapXEthOutputEnabled()
const uniswapXExactOutputEnabled = useUniswapXExactOutputEnabled()
const fotAdjustmentsEnabled = useFotAdjustmentsEnabled() const fotAdjustmentsEnabled = useFotAdjustmentsEnabled()
return useMemo( return useMemo(
...@@ -60,6 +62,7 @@ export function useRoutingAPIArguments({ ...@@ -60,6 +62,7 @@ export function useRoutingAPIArguments({
forceUniswapXOn, forceUniswapXOn,
userDisabledUniswapX, userDisabledUniswapX,
uniswapXEthOutputEnabled, uniswapXEthOutputEnabled,
uniswapXExactOutputEnabled,
fotAdjustmentsEnabled, fotAdjustmentsEnabled,
}, },
[ [
...@@ -70,6 +73,7 @@ export function useRoutingAPIArguments({ ...@@ -70,6 +73,7 @@ export function useRoutingAPIArguments({
tokenOut, tokenOut,
tradeType, tradeType,
uniswapXEnabled, uniswapXEnabled,
uniswapXExactOutputEnabled,
uniswapXForceSyntheticQuotes, uniswapXForceSyntheticQuotes,
forceUniswapXOn, forceUniswapXOn,
userDisabledUniswapX, userDisabledUniswapX,
......
...@@ -51,6 +51,7 @@ function getRoutingAPIConfig(args: GetQuoteArgs): RoutingConfig { ...@@ -51,6 +51,7 @@ function getRoutingAPIConfig(args: GetQuoteArgs): RoutingConfig {
tokenInChainId, tokenInChainId,
uniswapXForceSyntheticQuotes, uniswapXForceSyntheticQuotes,
uniswapXEthOutputEnabled, uniswapXEthOutputEnabled,
uniswapXExactOutputEnabled,
routerPreference, routerPreference,
} = args } = args
...@@ -76,8 +77,9 @@ function getRoutingAPIConfig(args: GetQuoteArgs): RoutingConfig { ...@@ -76,8 +77,9 @@ function getRoutingAPIConfig(args: GetQuoteArgs): RoutingConfig {
!args.uniswapXEnabled || !args.uniswapXEnabled ||
(args.userDisabledUniswapX && routerPreference !== RouterPreference.X) || (args.userDisabledUniswapX && routerPreference !== RouterPreference.X) ||
(tokenOutIsNative && !uniswapXEthOutputEnabled) || (tokenOutIsNative && !uniswapXEthOutputEnabled) ||
tradeType === TradeType.EXACT_OUTPUT || (!uniswapXExactOutputEnabled && tradeType === TradeType.EXACT_OUTPUT) ||
!isUniswapXSupportedChain(tokenInChainId) !isUniswapXSupportedChain(tokenInChainId) ||
routerPreference === INTERNAL_ROUTER_PREFERENCE_PRICE
) { ) {
return [classic] return [classic]
} }
......
...@@ -45,6 +45,7 @@ export interface GetQuoteArgs { ...@@ -45,6 +45,7 @@ export interface GetQuoteArgs {
uniswapXEnabled: boolean uniswapXEnabled: boolean
uniswapXForceSyntheticQuotes: boolean uniswapXForceSyntheticQuotes: boolean
uniswapXEthOutputEnabled: boolean uniswapXEthOutputEnabled: boolean
uniswapXExactOutputEnabled: boolean
forceUniswapXOn: boolean forceUniswapXOn: boolean
userDisabledUniswapX: boolean userDisabledUniswapX: boolean
fotAdjustmentsEnabled: boolean fotAdjustmentsEnabled: boolean
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment