From ac6922233f16588ed3e9b3813f7faac8a62aea2b Mon Sep 17 00:00:00 2001 From: Hung Doan <19758667+hungdoansy@users.noreply.github.com> Date: Wed, 28 Jun 2023 13:41:28 +0700 Subject: [PATCH] Customize Slippage/Price Impact for Linea testnet (#2018) * hide PriceImpact note on Linea testnet * set a custom slippage for linea testnet * chore: use prod env * Update .env.adpr --------- Co-authored-by: Nguyen Van Viet --- src/components/SwapForm/PriceImpactNote.tsx | 6 +++++- src/components/SwapForm/SlippageSetting.tsx | 8 +++++--- src/constants/index.ts | 2 ++ src/state/user/actions.ts | 4 ++++ src/state/user/hooks.tsx | 17 +++++++++++++---- src/state/user/reducer.ts | 9 +++++++++ src/utils/priceImpact.ts | 2 +- src/utils/slippage.ts | 12 ++++++++++++ 8 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/components/SwapForm/PriceImpactNote.tsx b/src/components/SwapForm/PriceImpactNote.tsx index 5e5d4be797..6de7af621c 100644 --- a/src/components/SwapForm/PriceImpactNote.tsx +++ b/src/components/SwapForm/PriceImpactNote.tsx @@ -5,6 +5,8 @@ import styled from 'styled-components' import Row from 'components/Row' import WarningNote from 'components/WarningNote' +import { useActiveWeb3React } from 'hooks' +import { checkAllowBypassPriceImpactRestriction } from 'utils/priceImpact' import { checkPriceImpact } from 'utils/prices' const TextUnderlineColor = styled(Text)` @@ -31,9 +33,11 @@ type Props = { } const PriceImpactNote: FC = ({ isDegenMode, priceImpact }) => { + const { chainId } = useActiveWeb3React() const priceImpactResult = checkPriceImpact(priceImpact) + const shouldHide = checkAllowBypassPriceImpactRestriction(chainId) - if (typeof priceImpact !== 'number') { + if (typeof priceImpact !== 'number' || shouldHide) { return null } diff --git a/src/components/SwapForm/SlippageSetting.tsx b/src/components/SwapForm/SlippageSetting.tsx index 2f3109b526..d567b9c4a8 100644 --- a/src/components/SwapForm/SlippageSetting.tsx +++ b/src/components/SwapForm/SlippageSetting.tsx @@ -6,11 +6,11 @@ import styled from 'styled-components' import { ReactComponent as DropdownSVG } from 'assets/svg/down.svg' import SlippageControl from 'components/SlippageControl' import { MouseoverTooltip, TextDashed } from 'components/Tooltip' -import { DEFAULT_SLIPPAGE, DEFAULT_SLIPPAGE_STABLE_PAIR_SWAP } from 'constants/index' +import { useActiveWeb3React } from 'hooks' import useTheme from 'hooks/useTheme' import { useSlippageSettingByPage } from 'state/user/hooks' import { ExternalLink } from 'theme' -import { checkWarningSlippage, formatSlippage } from 'utils/slippage' +import { checkWarningSlippage, formatSlippage, getDefaultSlippage } from 'utils/slippage' const DropdownIcon = styled(DropdownSVG)` transition: transform 300ms; @@ -28,9 +28,11 @@ type Props = { } const SlippageSetting = ({ isStablePairSwap, rightComponent, tooltip, isCrossChain }: Props) => { const theme = useTheme() + const { chainId } = useActiveWeb3React() const [expanded, setExpanded] = useState(false) const { setRawSlippage, rawSlippage, isSlippageControlPinned } = useSlippageSettingByPage(isCrossChain) + const defaultRawSlippage = getDefaultSlippage(chainId, isStablePairSwap) const isWarningSlippage = checkWarningSlippage(rawSlippage, isStablePairSwap) if (!isSlippageControlPinned) { @@ -126,7 +128,7 @@ const SlippageSetting = ({ isStablePairSwap, rightComponent, tooltip, isCrossCha rawSlippage={rawSlippage} setRawSlippage={setRawSlippage} isWarning={isWarningSlippage} - defaultRawSlippage={isStablePairSwap ? DEFAULT_SLIPPAGE_STABLE_PAIR_SWAP : DEFAULT_SLIPPAGE} + defaultRawSlippage={defaultRawSlippage} /> diff --git a/src/constants/index.ts b/src/constants/index.ts index 5960916962..86c59970c5 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -189,8 +189,10 @@ export const EPSILON = 0.000000000008854 export const MAX_NORMAL_SLIPPAGE_IN_BIPS = 1999 export const MAX_DEGEN_SLIPPAGE_IN_BIPS = 5000 export const DEFAULT_SLIPPAGES = [5, 10, 50, 100] + export const DEFAULT_SLIPPAGE = 50 export const DEFAULT_SLIPPAGE_STABLE_PAIR_SWAP = 5 +export const DEFAULT_SLIPPAGE_TESTNET = 1000 export const AGGREGATOR_WAITING_TIME = 1700 // 1700 means that we at least show '.' '..' '...' '.' '..' '...' diff --git a/src/state/user/actions.ts b/src/state/user/actions.ts index e0ffd7c2b2..85e1ab2571 100644 --- a/src/state/user/actions.ts +++ b/src/state/user/actions.ts @@ -28,6 +28,10 @@ export const updateUserLocale = createAction<{ userLocale: SupportedLocale }>('u export const updateUserSlippageTolerance = createAction<{ userSlippageTolerance: number }>( 'user/updateUserSlippageTolerance', ) +export const updateUserSlippageToleranceForLineaTestnet = createAction<{ userSlippageTolerance: number }>( + 'user/updateUserSlippageToleranceForLineaTestnet', +) + export const updateUserDeadline = createAction<{ userDeadline: number }>('user/updateUserDeadline') export const addSerializedToken = createAction<{ serializedToken: SerializedToken }>('user/addSerializedToken') export const removeSerializedToken = createAction<{ chainId: number; address: string }>('user/removeSerializedToken') diff --git a/src/state/user/hooks.tsx b/src/state/user/hooks.tsx index 643444d800..0e837616af 100644 --- a/src/state/user/hooks.tsx +++ b/src/state/user/hooks.tsx @@ -3,7 +3,7 @@ import { useCallback, useMemo } from 'react' import { useDispatch, useSelector } from 'react-redux' import { useGetParticipantInfoQuery } from 'services/kyberAISubscription' -import { TERM_FILES_PATH } from 'constants/index' +import { DEFAULT_SLIPPAGE_TESTNET, TERM_FILES_PATH } from 'constants/index' import { SupportedLocale } from 'constants/locales' import { PINNED_PAIRS } from 'constants/tokens' import { useActiveWeb3React } from 'hooks' @@ -46,6 +46,7 @@ import { updateUserDegenMode, updateUserLocale, updateUserSlippageTolerance, + updateUserSlippageToleranceForLineaTestnet, } from 'state/user/actions' import { CROSS_CHAIN_SETTING_DEFAULT, @@ -154,15 +155,23 @@ export function useDegenModeManager(): [boolean, () => void] { export function useUserSlippageTolerance(): [number, (slippage: number) => void] { const dispatch = useDispatch() + const { chainId } = useActiveWeb3React() + const isLineaTestnet = chainId === ChainId.LINEA_TESTNET const userSlippageTolerance = useSelector(state => { - return state.user.userSlippageTolerance + return isLineaTestnet + ? state.user.userSlippageToleranceForLineaTestnet || DEFAULT_SLIPPAGE_TESTNET + : state.user.userSlippageTolerance }) const setUserSlippageTolerance = useCallback( (userSlippageTolerance: number) => { - dispatch(updateUserSlippageTolerance({ userSlippageTolerance })) + if (isLineaTestnet) { + dispatch(updateUserSlippageToleranceForLineaTestnet({ userSlippageTolerance })) + } else { + dispatch(updateUserSlippageTolerance({ userSlippageTolerance })) + } }, - [dispatch], + [dispatch, isLineaTestnet], ) return [userSlippageTolerance, setUserSlippageTolerance] diff --git a/src/state/user/reducer.ts b/src/state/user/reducer.ts index 86b35fe3b7..8540379b4d 100644 --- a/src/state/user/reducer.ts +++ b/src/state/user/reducer.ts @@ -6,6 +6,7 @@ import { DEFAULT_DEADLINE_FROM_NOW, DEFAULT_SLIPPAGE, DEFAULT_SLIPPAGE_STABLE_PAIR_SWAP, + DEFAULT_SLIPPAGE_TESTNET, INITIAL_ALLOWED_SLIPPAGE, MAX_NORMAL_SLIPPAGE_IN_BIPS, } from 'constants/index' @@ -41,6 +42,7 @@ import { updateUserDegenMode, updateUserLocale, updateUserSlippageTolerance, + updateUserSlippageToleranceForLineaTestnet, } from './actions' const currentTimestamp = () => new Date().getTime() @@ -72,6 +74,8 @@ interface UserState { // user defined slippage tolerance in bips, used in all txns userSlippageTolerance: number + userSlippageToleranceForLineaTestnet: number + // deadline set by user in minutes, used in all txns userDeadline: number @@ -176,6 +180,7 @@ const initialState: UserState = { userDegenModeAutoDisableTimestamp: 0, userLocale: null, userSlippageTolerance: INITIAL_ALLOWED_SLIPPAGE, + userSlippageToleranceForLineaTestnet: DEFAULT_SLIPPAGE_TESTNET, userDeadline: DEFAULT_DEADLINE_FROM_NOW, tokens: {}, pairs: {}, @@ -265,6 +270,10 @@ export default createReducer(initialState, builder => state.userSlippageTolerance = action.payload.userSlippageTolerance state.timestamp = currentTimestamp() }) + .addCase(updateUserSlippageToleranceForLineaTestnet, (state, action) => { + state.userSlippageToleranceForLineaTestnet = action.payload.userSlippageTolerance + state.timestamp = currentTimestamp() + }) .addCase(updateUserDeadline, (state, action) => { state.userDeadline = action.payload.userDeadline state.timestamp = currentTimestamp() diff --git a/src/utils/priceImpact.ts b/src/utils/priceImpact.ts index f8f3168813..530464eec9 100644 --- a/src/utils/priceImpact.ts +++ b/src/utils/priceImpact.ts @@ -14,6 +14,6 @@ export const checkShouldDisableByPriceImpact = ( : !isDegenMode && (priceImpactResult.isVeryHigh || priceImpactResult.isInvalid) } -const checkAllowBypassPriceImpactRestriction = (chainId: ChainId) => { +export const checkAllowBypassPriceImpactRestriction = (chainId: ChainId) => { return CHAINS_BYPASS_PRICE_IMPACT.includes(chainId) } diff --git a/src/utils/slippage.ts b/src/utils/slippage.ts index 6490d98621..8a6df00584 100644 --- a/src/utils/slippage.ts +++ b/src/utils/slippage.ts @@ -1,9 +1,21 @@ +import { ChainId } from '@kyberswap/ks-sdk-core' + +import { DEFAULT_SLIPPAGE, DEFAULT_SLIPPAGE_STABLE_PAIR_SWAP, DEFAULT_SLIPPAGE_TESTNET } from 'constants/index' + export enum SLIPPAGE_STATUS { NORMAL, LOW, HIGH, } +export const getDefaultSlippage = (chainId: ChainId, isStablePairSwap: boolean): number => { + if (chainId === ChainId.LINEA_TESTNET) { + return DEFAULT_SLIPPAGE_TESTNET + } + + return isStablePairSwap ? DEFAULT_SLIPPAGE_STABLE_PAIR_SWAP : DEFAULT_SLIPPAGE +} + export const checkRangeSlippage = (slippage: number, isStablePairSwap: boolean): SLIPPAGE_STATUS => { if (isStablePairSwap) { if (slippage >= 100) {