feat: uniswapX opt-out update (#7368)

This commit is contained in:
eddie 2023-09-22 09:38:47 -07:00 committed by GitHub
parent fbc7e64032
commit 0a31428d7a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 32 additions and 8 deletions

@ -8,8 +8,8 @@ import { isUniswapXSupportedChain } from 'constants/chains'
import { useUniswapXDefaultEnabled } from 'featureFlags/flags/uniswapXDefault' import { useUniswapXDefaultEnabled } from 'featureFlags/flags/uniswapXDefault'
import { useAppDispatch } from 'state/hooks' import { useAppDispatch } from 'state/hooks'
import { RouterPreference } from 'state/routing/types' import { RouterPreference } from 'state/routing/types'
import { useRouterPreference, useUserDisabledUniswapX } from 'state/user/hooks' import { useRouterPreference, useUserOptedOutOfUniswapX } from 'state/user/hooks'
import { updateDisabledUniswapX } from 'state/user/reducer' import { updateDisabledUniswapX, updateOptedOutOfUniswapX } from 'state/user/reducer'
import styled from 'styled-components' import styled from 'styled-components'
import { Divider, ExternalLink, ThemedText } from 'theme/components' import { Divider, ExternalLink, ThemedText } from 'theme/components'
@ -27,9 +27,9 @@ export default function RouterPreferenceSettings() {
const [routerPreference, setRouterPreference] = useRouterPreference() const [routerPreference, setRouterPreference] = useRouterPreference()
const uniswapXEnabled = chainId && isUniswapXSupportedChain(chainId) const uniswapXEnabled = chainId && isUniswapXSupportedChain(chainId)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const userDisabledUniswapX = useUserDisabledUniswapX() const userOptedOutOfUniswapX = useUserOptedOutOfUniswapX()
const isUniswapXDefaultEnabled = useUniswapXDefaultEnabled() const isUniswapXDefaultEnabled = useUniswapXDefaultEnabled()
const isUniswapXOverrideEnabled = isUniswapXDefaultEnabled && !userDisabledUniswapX const isUniswapXOverrideEnabled = isUniswapXDefaultEnabled && !userOptedOutOfUniswapX
const uniswapXInEffect = const uniswapXInEffect =
routerPreference === RouterPreference.X || routerPreference === RouterPreference.X ||
@ -61,8 +61,13 @@ export default function RouterPreferenceSettings() {
isActive={uniswapXInEffect} isActive={uniswapXInEffect}
toggle={() => { toggle={() => {
if (uniswapXInEffect) { if (uniswapXInEffect) {
// We need to remember if a user disables Uniswap X, so we don't show the opt-in flow again. if (isUniswapXDefaultEnabled) {
dispatch(updateDisabledUniswapX({ disabledUniswapX: true })) // We need to remember if a opts out of UniswapX, so we don't request UniswapX quotes.
dispatch(updateOptedOutOfUniswapX({ optedOutOfUniswapX: true }))
} else {
// We need to remember if a user disables Uniswap X, so we don't show the opt-in flow again.
dispatch(updateDisabledUniswapX({ disabledUniswapX: true }))
}
} }
setRouterPreference(uniswapXInEffect ? RouterPreference.API : RouterPreference.X) setRouterPreference(uniswapXInEffect ? RouterPreference.API : RouterPreference.X)
}} }}

@ -7,7 +7,7 @@ import { useUniswapXSyntheticQuoteEnabled } from 'featureFlags/flags/uniswapXUse
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'
import { currencyAddressForSwapQuote } from 'state/routing/utils' import { currencyAddressForSwapQuote } from 'state/routing/utils'
import { useUserDisabledUniswapX } from 'state/user/hooks' import { useUserDisabledUniswapX, useUserOptedOutOfUniswapX } from 'state/user/hooks'
/** /**
* Returns query arguments for the Routing API query or undefined if the * Returns query arguments for the Routing API query or undefined if the
@ -35,6 +35,7 @@ export function useRoutingAPIArguments({
}): GetQuoteArgs | SkipToken { }): GetQuoteArgs | SkipToken {
const uniswapXForceSyntheticQuotes = useUniswapXSyntheticQuoteEnabled() const uniswapXForceSyntheticQuotes = useUniswapXSyntheticQuoteEnabled()
const userDisabledUniswapX = useUserDisabledUniswapX() const userDisabledUniswapX = useUserDisabledUniswapX()
const userOptedOutOfUniswapX = useUserOptedOutOfUniswapX()
const uniswapXEthOutputEnabled = useUniswapXEthOutputEnabled() const uniswapXEthOutputEnabled = useUniswapXEthOutputEnabled()
const uniswapXExactOutputEnabled = useUniswapXExactOutputEnabled() const uniswapXExactOutputEnabled = useUniswapXExactOutputEnabled()
const isUniswapXDefaultEnabled = useUniswapXDefaultEnabled() const isUniswapXDefaultEnabled = useUniswapXDefaultEnabled()
@ -59,6 +60,7 @@ export function useRoutingAPIArguments({
needsWrapIfUniswapX: tokenIn.isNative, needsWrapIfUniswapX: tokenIn.isNative,
uniswapXForceSyntheticQuotes, uniswapXForceSyntheticQuotes,
userDisabledUniswapX, userDisabledUniswapX,
userOptedOutOfUniswapX,
uniswapXEthOutputEnabled, uniswapXEthOutputEnabled,
uniswapXExactOutputEnabled, uniswapXExactOutputEnabled,
isUniswapXDefaultEnabled, isUniswapXDefaultEnabled,
@ -75,6 +77,7 @@ export function useRoutingAPIArguments({
uniswapXExactOutputEnabled, uniswapXExactOutputEnabled,
uniswapXForceSyntheticQuotes, uniswapXForceSyntheticQuotes,
userDisabledUniswapX, userDisabledUniswapX,
userOptedOutOfUniswapX,
uniswapXEthOutputEnabled, uniswapXEthOutputEnabled,
isUniswapXDefaultEnabled, isUniswapXDefaultEnabled,
inputTax, inputTax,

@ -88,6 +88,7 @@ interface ExpectedUserState {
hideBaseWalletBanner: boolean hideBaseWalletBanner: boolean
showSurveyPopup?: boolean showSurveyPopup?: boolean
disabledUniswapX?: boolean disabledUniswapX?: boolean
optedOutOfUniswapX?: boolean
} }
assert<Equals<UserState, ExpectedUserState>>() assert<Equals<UserState, ExpectedUserState>>()

@ -73,7 +73,8 @@ function getRoutingAPIConfig(args: GetQuoteArgs): RoutingConfig {
// UniswapX doesn't support native out, exact-out, or non-mainnet trades (yet), // UniswapX doesn't support native out, exact-out, or non-mainnet trades (yet),
// so even if the user has selected UniswapX as their router preference, force them to receive a Classic quote. // so even if the user has selected UniswapX as their router preference, force them to receive a Classic quote.
if ( if (
(args.userDisabledUniswapX && routerPreference !== RouterPreference.X) || // If the user has opted out of UniswapX during the opt-out transition period, we should respect that preference and only request classic quotes.
(args.userOptedOutOfUniswapX && routerPreference !== RouterPreference.X) ||
(tokenOutIsNative && !uniswapXEthOutputEnabled) || (tokenOutIsNative && !uniswapXEthOutputEnabled) ||
(!uniswapXExactOutputEnabled && tradeType === TradeType.EXACT_OUTPUT) || (!uniswapXExactOutputEnabled && tradeType === TradeType.EXACT_OUTPUT) ||
!isUniswapXSupportedChain(tokenInChainId) || !isUniswapXSupportedChain(tokenInChainId) ||

@ -45,7 +45,10 @@ export interface GetQuoteArgs {
uniswapXForceSyntheticQuotes: boolean uniswapXForceSyntheticQuotes: boolean
uniswapXEthOutputEnabled: boolean uniswapXEthOutputEnabled: boolean
uniswapXExactOutputEnabled: boolean uniswapXExactOutputEnabled: boolean
// legacy field indicating the user disabled UniswapX during the opt-in period, or dismissed the UniswapX opt-in modal.
userDisabledUniswapX: boolean userDisabledUniswapX: boolean
// temporary field indicating the user disabled UniswapX during the transition to the opt-out model
userOptedOutOfUniswapX: boolean
isUniswapXDefaultEnabled: boolean isUniswapXDefaultEnabled: boolean
inputTax: Percent inputTax: Percent
outputTax: Percent outputTax: Percent

@ -221,6 +221,10 @@ export function useUserDisabledUniswapX(): boolean {
return useAppSelector((state) => state.user.disabledUniswapX) ?? false return useAppSelector((state) => state.user.disabledUniswapX) ?? false
} }
export function useUserOptedOutOfUniswapX(): boolean {
return useAppSelector((state) => state.user.optedOutOfUniswapX) ?? false
}
/** /**
* Given two tokens return the liquidity token that represents its liquidity shares * Given two tokens return the liquidity token that represents its liquidity shares
* @param tokenA one of the two tokens * @param tokenA one of the two tokens

@ -47,7 +47,10 @@ export interface UserState {
timestamp: number timestamp: number
hideBaseWalletBanner: boolean hideBaseWalletBanner: boolean
// legacy field indicating the user disabled UniswapX during the opt-in period, or dismissed the UniswapX opt-in modal.
disabledUniswapX?: boolean disabledUniswapX?: boolean
// temporary field indicating the user disabled UniswapX during the transition to the opt-out model
optedOutOfUniswapX?: boolean
// undefined means has not gone through A/B split yet // undefined means has not gone through A/B split yet
showSurveyPopup?: boolean showSurveyPopup?: boolean
} }
@ -105,6 +108,9 @@ const userSlice = createSlice({
updateDisabledUniswapX(state, action) { updateDisabledUniswapX(state, action) {
state.disabledUniswapX = action.payload.disabledUniswapX state.disabledUniswapX = action.payload.disabledUniswapX
}, },
updateOptedOutOfUniswapX(state, action) {
state.optedOutOfUniswapX = action.payload.optedOutOfUniswapX
},
addSerializedToken(state, { payload: { serializedToken } }) { addSerializedToken(state, { payload: { serializedToken } }) {
if (!state.tokens) { if (!state.tokens) {
state.tokens = {} state.tokens = {}
@ -138,5 +144,6 @@ export const {
updateUserSlippageTolerance, updateUserSlippageTolerance,
updateHideBaseWalletBanner, updateHideBaseWalletBanner,
updateDisabledUniswapX, updateDisabledUniswapX,
updateOptedOutOfUniswapX,
} = userSlice.actions } = userSlice.actions
export default userSlice.reducer export default userSlice.reducer