diff --git a/src/assets/translations/en/main.json b/src/assets/translations/en/main.json
index 60f38fdc016..0a2e5aab12e 100644
--- a/src/assets/translations/en/main.json
+++ b/src/assets/translations/en/main.json
@@ -2226,8 +2226,7 @@
"yourLoans": "Your Loans",
"emptyTitle": "The Land of Zero Loans!",
"emptyBody": "It appears you don't have any loans at the moment. Is this financial zen or just a break before your next big lending adventure? Either way, enjoy the calm!"
- },
- "unsafeBorrow": "This borrow has high slippage (%{slippagePercentage}%). Proceed with caution."
+ }
},
"foxDiscounts": {
"currentFoxPower": "Your FOX Power",
@@ -2332,6 +2331,14 @@
}
}
},
+ "warningAcknowledgement": {
+ "understand": "I understand",
+ "attention": "Attention!",
+ "highSlippageDeposit": "This deposit has high slippage (%{slippagePercentage}%). Proceed with caution.",
+ "highSlippageBorrow": "This borrow has high slippage (%{slippagePercentage}%). Proceed with caution.",
+ "highSlippageTrade": "This trade is impacted by price movement (%{slippagePercentage}%). Proceed with caution.",
+ "unsafeTrade": "This trade may be unsafe or below the recommended minimum size, proceed with caution."
+ },
"watchlist": {
"empty": {
"title": "Start building your watchlist",
diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx
index 4b6452f1cd1..88b85c4c015 100644
--- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx
+++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/MultiHopTradeConfirm.tsx
@@ -1,11 +1,18 @@
import { Card, CardBody, CardHeader, Heading, useDisclosure, usePrevious } from '@chakra-ui/react'
-import { memo, useCallback, useEffect, useMemo } from 'react'
+import { memo, useCallback, useEffect, useMemo, useState } from 'react'
+import { useTranslate } from 'react-polyglot'
import { useHistory } from 'react-router-dom'
import { WithBackButton } from 'components/MultiHopTrade/components/WithBackButton'
+import { usePriceImpact } from 'components/MultiHopTrade/hooks/quoteValidation/usePriceImpact'
import { TradeSlideTransition } from 'components/MultiHopTrade/TradeSlideTransition'
import { TradeRoutePaths } from 'components/MultiHopTrade/types'
import { Text } from 'components/Text'
-import { selectTradeExecutionState } from 'state/slices/tradeQuoteSlice/selectors'
+import { WarningAcknowledgement } from 'components/WarningAcknowledgement/WarningAcknowledgement'
+import { bnOrZero } from 'lib/bignumber/bignumber'
+import {
+ selectActiveQuote,
+ selectTradeExecutionState,
+} from 'state/slices/tradeQuoteSlice/selectors'
import { tradeQuoteSlice } from 'state/slices/tradeQuoteSlice/tradeQuoteSlice'
import { TradeExecutionState } from 'state/slices/tradeQuoteSlice/types'
import { useAppDispatch, useAppSelector } from 'state/store'
@@ -22,10 +29,15 @@ const useDisclosureProps = {
export const MultiHopTradeConfirm = memo(() => {
const dispatch = useAppDispatch()
+ const translate = useTranslate()
const tradeExecutionState = useAppSelector(selectTradeExecutionState)
const previousTradeExecutionState = usePrevious(tradeExecutionState)
const history = useHistory()
+ const [shouldShowWarningAcknowledgement, setShouldShowWarningAcknowledgement] = useState(false)
+ const activeQuote = useAppSelector(selectActiveQuote)
+ const { isModeratePriceImpact, priceImpactPercentage } = usePriceImpact(activeQuote)
+
const { isLoading } = useIsApprovalInitiallyNeeded()
useEffect(() => {
@@ -65,6 +77,18 @@ export const MultiHopTradeConfirm = memo(() => {
[tradeExecutionState],
)
+ const handleTradeConfirm = useCallback(() => {
+ dispatch(tradeQuoteSlice.actions.confirmTrade())
+ }, [dispatch])
+
+ const handleSubmit = useCallback(() => {
+ if (isModeratePriceImpact) {
+ setShouldShowWarningAcknowledgement(true)
+ } else {
+ handleTradeConfirm()
+ }
+ }, [handleTradeConfirm, isModeratePriceImpact])
+
return (
{
variant='dashboard'
maxWidth='500px'
>
-
-
-
-
-
-
-
- {isTradeComplete ? (
-
-
-
- ) : (
- <>
-
-
-
-
- >
- )}
+
+
+
+
+
+
+
+
+ {isTradeComplete ? (
+
+
+
+ ) : (
+ <>
+
+
+
+
+ >
+ )}
+
)
diff --git a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Footer.tsx b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Footer.tsx
index 8062119201f..40ab33beba5 100644
--- a/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Footer.tsx
+++ b/src/components/MultiHopTrade/components/MultiHopTradeConfirm/components/Footer.tsx
@@ -9,39 +9,34 @@ import {
Stack,
} from '@chakra-ui/react'
import { SwapperName } from '@shapeshiftoss/swapper'
-import { useCallback, useMemo } from 'react'
+import type { FC } from 'react'
+import { useMemo } from 'react'
import { useTranslate } from 'react-polyglot'
-import { usePriceImpact } from 'components/MultiHopTrade/hooks/quoteValidation/usePriceImpact'
import { chainSupportsTxHistory } from 'components/MultiHopTrade/utils'
import { Text } from 'components/Text'
import type { TextPropTypes } from 'components/Text/Text'
import { bnOrZero } from 'lib/bignumber/bignumber'
import {
- selectActiveQuote,
selectActiveSwapperName,
selectLastHopBuyAsset,
selectQuoteSellAmountUserCurrency,
selectTotalNetworkFeeUserCurrencyPrecision,
selectTradeExecutionState,
} from 'state/slices/tradeQuoteSlice/selectors'
-import { tradeQuoteSlice } from 'state/slices/tradeQuoteSlice/tradeQuoteSlice'
import { TradeExecutionState } from 'state/slices/tradeQuoteSlice/types'
-import { useAppDispatch, useAppSelector } from 'state/store'
+import { useAppSelector } from 'state/store'
-export const Footer = () => {
+type FooterProps = {
+ handleSubmit: () => void
+}
+
+export const Footer: FC = ({ handleSubmit }) => {
const translate = useTranslate()
- const dispatch = useAppDispatch()
const swapperName = useAppSelector(selectActiveSwapperName)
- const activeQuote = useAppSelector(selectActiveQuote)
const lastHopBuyAsset = useAppSelector(selectLastHopBuyAsset)
const tradeExecutionState = useAppSelector(selectTradeExecutionState)
const networkFeeUserCurrency = useAppSelector(selectTotalNetworkFeeUserCurrencyPrecision)
const sellAmountBeforeFeesUserCurrency = useAppSelector(selectQuoteSellAmountUserCurrency)
- const { isModeratePriceImpact } = usePriceImpact(activeQuote)
-
- const handleConfirm = useCallback(() => {
- dispatch(tradeQuoteSlice.actions.confirmTrade())
- }, [dispatch])
const networkFeeToTradeRatioPercentage = useMemo(
() =>
@@ -140,13 +135,13 @@ export const Footer = () => {
)}
) : null
diff --git a/src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx b/src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx
index cadfc4f5e1e..82789102c73 100644
--- a/src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx
+++ b/src/components/MultiHopTrade/components/TradeInput/TradeInput.tsx
@@ -1,8 +1,5 @@
import { ArrowDownIcon } from '@chakra-ui/icons'
import {
- Alert,
- AlertDescription,
- AlertIcon,
Button,
Card,
CardFooter,
@@ -39,6 +36,7 @@ import { useReceiveAddress } from 'components/MultiHopTrade/hooks/useReceiveAddr
import { TradeSlideTransition } from 'components/MultiHopTrade/TradeSlideTransition'
import { TradeRoutePaths } from 'components/MultiHopTrade/types'
import { Text } from 'components/Text'
+import { WarningAcknowledgement } from 'components/WarningAcknowledgement/WarningAcknowledgement'
import { WalletActions } from 'context/WalletProvider/actions'
import { useErrorHandler } from 'hooks/useErrorToast/useErrorToast'
import { useIsSmartContractAddress } from 'hooks/useIsSmartContractAddress/useIsSmartContractAddress'
@@ -132,6 +130,7 @@ export const TradeInput = memo(({ isCompact }: TradeInputProps) => {
const { showErrorToast } = useErrorHandler()
const [isCompactQuoteListOpen, setIsCompactQuoteListOpen] = useState(false)
const [isConfirmationLoading, setIsConfirmationLoading] = useState(false)
+ const [shouldShowWarningAcknowledgement, setShouldShowWarningAcknowledgement] = useState(false)
const isKeplr = useMemo(() => !!wallet && isKeplrHDWallet(wallet), [wallet])
const buyAssetSearch = useModal('buyTradeAssetSearch')
const sellAssetSearch = useModal('sellTradeAssetSearch')
@@ -377,13 +376,13 @@ export const TradeInput = memo(({ isCompact }: TradeInputProps) => {
wallet,
])
- const [isUnsafeQuoteNoticeDismissed, setIsUnsafeQuoteNoticeDismissed] = useState(
- null,
- )
-
useEffect(() => {
- if (isUnsafeQuote) setIsUnsafeQuoteNoticeDismissed(false)
- }, [isUnsafeQuote])
+ // Reset the trade warning if the active quote has changed, i.e. a better quote has come in and the
+ // user has not yet confirmed the previous one
+ if (shouldShowWarningAcknowledgement) setShouldShowWarningAcknowledgement(false)
+ // We need to ignore changes to shouldShowWarningAcknowledgement or this effect will react to itself
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [activeQuote])
const quoteHasError = useMemo(() => {
if (!isAnyTradeQuoteLoaded) return false
@@ -424,42 +423,6 @@ export const TradeInput = memo(({ isCompact }: TradeInputProps) => {
isTradeQuoteApiQueryPending,
])
- const maybeUnsafeTradeWarning = useMemo(() => {
- if (!isUnsafeQuote) return null
-
- const recommendedMinimumCryptoBaseUnit = (activeQuote as ThorTradeQuote)
- ?.recommendedMinimumCryptoBaseUnit
- if (!recommendedMinimumCryptoBaseUnit) return null
- const recommendedMinimumCryptoPrecision = fromBaseUnit(
- recommendedMinimumCryptoBaseUnit,
- sellAsset.precision,
- )
-
- return (
-
-
-
-
-
- {translate('trade.errors.unsafeQuote', {
- symbol: sellAsset.symbol,
- recommendedMin: recommendedMinimumCryptoPrecision,
- })}
-
-
-
-
- )
- }, [activeQuote, isUnsafeQuote, sellAsset.precision, sellAsset.symbol, translate])
-
- const handleAcknowledgeUnsafeQuote = useCallback(() => {
- // We don't want to *immediately* set this or there will be a "click-through"
- // i.e the regular continue button will render immediately, and click will bubble to it
- setTimeout(() => {
- setIsUnsafeQuoteNoticeDismissed(true)
- }, 100)
- }, [])
-
const handleCloseCompactQuoteList = useCallback(() => setIsCompactQuoteListOpen(false), [])
const handleOpenCompactQuoteList = useCallback(() => {
@@ -524,28 +487,17 @@ export const TradeInput = memo(({ isCompact }: TradeInputProps) => {
>
- {maybeUnsafeTradeWarning}
- {isUnsafeQuote && !isUnsafeQuoteNoticeDismissed ? (
-
- ) : (
-
- )}
+
+
>
),
@@ -568,10 +520,6 @@ export const TradeInput = memo(({ isCompact }: TradeInputProps) => {
priceImpactPercentage,
receiveAddress,
walletSupportsBuyAssetChain,
- maybeUnsafeTradeWarning,
- isUnsafeQuote,
- isUnsafeQuoteNoticeDismissed,
- handleAcknowledgeUnsafeQuote,
quoteHasError,
shouldDisablePreviewButton,
quoteStatusTranslation,
@@ -579,6 +527,10 @@ export const TradeInput = memo(({ isCompact }: TradeInputProps) => {
)
const handleFormSubmit = useMemo(() => handleSubmit(onSubmit), [handleSubmit, onSubmit])
+ const handleTradeQuoteConfirm = useCallback(
+ () => (isUnsafeQuote ? setShouldShowWarningAcknowledgement(true) : handleFormSubmit()),
+ [handleFormSubmit, isUnsafeQuote],
+ )
const sellTradeAssetSelect = useMemo(
() => (
@@ -607,6 +559,21 @@ export const TradeInput = memo(({ isCompact }: TradeInputProps) => {
return !walletSupportsBuyAssetChain
}, [walletSupportsBuyAssetChain])
+ const warningAcknowledgementMessage = (() => {
+ const recommendedMinimumCryptoBaseUnit = (activeQuote as ThorTradeQuote)
+ ?.recommendedMinimumCryptoBaseUnit
+ if (!recommendedMinimumCryptoBaseUnit) return translate('warningAcknowledgement.unsafeTrade')
+ const recommendedMinimumCryptoPrecision = fromBaseUnit(
+ recommendedMinimumCryptoBaseUnit,
+ sellAsset.precision,
+ )
+ const message = translate('trade.errors.unsafeQuote', {
+ symbol: sellAsset.symbol,
+ recommendedMin: recommendedMinimumCryptoPrecision,
+ })
+ return message
+ })()
+
return (
@@ -635,92 +602,99 @@ export const TradeInput = memo(({ isCompact }: TradeInputProps) => {
visibility={isCompactQuoteListOpen ? 'hidden' : undefined}
position={isCompactQuoteListOpen ? 'absolute' : undefined}
>
-
-
-
-
- {translate('navBar.trade')}
-
-
- {activeQuote && (isCompact || isSmallerThanXl) && (
-
- )}
-
+
+
+
+
+
+ {translate('navBar.trade')}
+
+
+ {activeQuote && (isCompact || isSmallerThanXl) && (
+
+ )}
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {ConfirmSummary}
- {ConfirmSummary}
-
+
= ({ children }) => {
+ return (
+
+ {children}
+
+ )
+}
+
+const popoverVariants = {
+ initial: {
+ y: '100%',
+ },
+ animate: {
+ y: 0,
+ transition: {
+ type: 'spring',
+ bounce: 0.2,
+ duration: 0.55,
+ },
+ },
+ exit: {
+ y: '100%',
+ opacity: 0,
+ transition: {
+ duration: 0.2,
+ },
+ },
+}
+
+const popoverStyle: MotionStyle = {
+ backgroundColor: 'var(--chakra-colors-background-surface-overlay-base)',
+ position: 'absolute',
+ borderTopLeftRadius: 'var(--chakra-radii-2xl)',
+ borderTopRightRadius: 'var(--chakra-radii-2xl)',
+ bottom: 0,
+ left: 0,
+ right: 0,
+ zIndex: 5,
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ paddingLeft: '2rem',
+ paddingRight: '2rem',
+ paddingBottom: '2rem',
+ paddingTop: '4rem',
+}
+
+type WarningAcknowledgementProps = {
+ children: React.ReactNode
+ message: string
+ onAcknowledge: () => void
+ shouldShowWarningAcknowledgement: boolean
+ setShouldShowWarningAcknowledgement: (shouldShow: boolean) => void
+}
+
+const cancelHoverProps = { bg: 'rgba(255, 255, 255, 0.2)' }
+const understandHoverProps = { bg: 'red.600' }
+const boxBorderRadius = { base: 'none', md: 'xl' }
+
+export const WarningAcknowledgement = ({
+ children,
+ message,
+ onAcknowledge,
+ shouldShowWarningAcknowledgement,
+ setShouldShowWarningAcknowledgement,
+}: WarningAcknowledgementProps) => {
+ const translate = useTranslate()
+ const [isShowing, setIsShowing] = useState(false)
+
+ const handleAcknowledge = useCallback(() => {
+ setShouldShowWarningAcknowledgement(false)
+ onAcknowledge()
+ }, [onAcknowledge, setShouldShowWarningAcknowledgement])
+
+ const handleCancel = useCallback(() => {
+ setShouldShowWarningAcknowledgement(false)
+ }, [setShouldShowWarningAcknowledgement])
+
+ const handleAnimationComplete = useCallback((def: AnimationDefinition) => {
+ if (def === 'exit') {
+ setIsShowing(false)
+ }
+ }, [])
+
+ useEffect(() => {
+ // enters with overflow: hidden
+ // exit after animation complete return to overflow: visible
+ if (shouldShowWarningAcknowledgement) {
+ setIsShowing(true)
+ }
+ }, [shouldShowWarningAcknowledgement])
+
+ return (
+
+
+ {shouldShowWarningAcknowledgement && (
+
+
+
+
+
+ {message}
+
+
+
+
+
+ )}
+
+
+ {children}
+
+ )
+}
diff --git a/src/pages/Lending/Pool/components/Borrow/BorrowInput.tsx b/src/pages/Lending/Pool/components/Borrow/BorrowInput.tsx
index 714580a7b11..cb00aebdac9 100644
--- a/src/pages/Lending/Pool/components/Borrow/BorrowInput.tsx
+++ b/src/pages/Lending/Pool/components/Borrow/BorrowInput.tsx
@@ -1,8 +1,5 @@
import { ArrowDownIcon } from '@chakra-ui/icons'
import {
- Alert,
- AlertDescription,
- AlertIcon,
Button,
CardFooter,
Collapse,
@@ -25,7 +22,8 @@ import { HelperTooltip } from 'components/HelperTooltip/HelperTooltip'
import { TradeAssetInput } from 'components/MultiHopTrade/components/TradeAssetInput'
import { Row } from 'components/Row/Row'
import { SlideTransition } from 'components/SlideTransition'
-import { RawText, Text } from 'components/Text'
+import { RawText } from 'components/Text'
+import { WarningAcknowledgement } from 'components/WarningAcknowledgement/WarningAcknowledgement'
import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag'
import { useIsSmartContractAddress } from 'hooks/useIsSmartContractAddress/useIsSmartContractAddress'
import { useModal } from 'hooks/useModal/useModal'
@@ -102,17 +100,7 @@ export const BorrowInput = ({
const [fromAddress, setFromAddress] = useState(null)
const [borrowAssetIsFiat, toggleBorrowAssetIsFiat] = useToggle(false)
const [collateralAssetIsFiat, toggleCollateralAssetIsFiat] = useToggle(false)
- const [isUnsafeQuoteNoticeDismissed, setIsUnsafeQuoteNoticeDismissed] = useState(
- null,
- )
-
- const handleAcknowledgeUnsafeQuote = useCallback(() => {
- // We don't want to *immediately* set this or there will be a "click-through"
- // i.e the regular continue button will render immediately, and click will bubble to it
- setTimeout(() => {
- setIsUnsafeQuoteNoticeDismissed(true)
- }, 100)
- }, [])
+ const [shouldShowWarningAcknowledgement, setShouldShowWarningAcknowledgement] = useState(false)
const {
state: { wallet },
@@ -366,10 +354,6 @@ export const BorrowInput = ({
[quoteSlippageDecimalPercentage],
)
- useEffect(() => {
- if (isUnsafeQuote) setIsUnsafeQuoteNoticeDismissed(false)
- }, [isUnsafeQuote])
-
useEffect(() => {
setConfirmedQuote(lendingQuoteData ?? null)
}, [isLendingQuoteSuccess, lendingQuoteData, setConfirmedQuote])
@@ -502,76 +486,160 @@ export const BorrowInput = ({
lendingQuoteError?.message,
])
+ const handleBorrowSubmit = useCallback(
+ () => (isUnsafeQuote ? setShouldShowWarningAcknowledgement(true) : onSubmit()),
+ [isUnsafeQuote, onSubmit],
+ )
+
if (!(collateralAsset && borrowAsset && collateralFeeAsset)) return null
return (
-
-
-
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {translate('common.slippage')}
+
+
+
+
+
+
+
+ {translate('common.gasFee')}
+
+
+
+
+
+
+ {isSweepNeeded && (
+
+
+ {translate('modals.send.consolidate.consolidateFunds')}
+
+
+
+
+
+
+
+ )}
+
+ {translate('common.fees')}
+
+
+
+
+
+
+
+ {translate('bridge.waitTimeLabel')}
+
+
+
+ {prettyMilliseconds(lendingQuoteData?.quoteTotalTimeMs ?? 0)}
+
+
+
+
+
+
-
- {translate('common.slippage')}
-
-
-
-
-
-
-
- {translate('common.gasFee')}
-
-
-
-
-
-
- {isSweepNeeded && (
-
-
- {translate('modals.send.consolidate.consolidateFunds')}
-
-
-
-
-
-
-
- )}
-
- {translate('common.fees')}
-
-
-
-
-
-
-
- {translate('bridge.waitTimeLabel')}
-
-
-
- {prettyMilliseconds(lendingQuoteData?.quoteTotalTimeMs ?? 0)}
-
-
-
-
-
-
-
- {isUnsafeQuote && !isUnsafeQuoteNoticeDismissed ? (
- <>
-
-
-
-
-
- {translate('lending.unsafeBorrow', {
- slippagePercentage: bnOrZero(quoteSlippageDecimalPercentage)
- .times(100)
- .toFixed(2),
- })}
-
-
-
-
-
- >
- ) : (
-
+
+
+
)
}
diff --git a/src/pages/ThorChainLP/components/AddLiquidity/AddLiquidityInput.tsx b/src/pages/ThorChainLP/components/AddLiquidity/AddLiquidityInput.tsx
index 6a94dcec6c6..2d245c12a04 100644
--- a/src/pages/ThorChainLP/components/AddLiquidity/AddLiquidityInput.tsx
+++ b/src/pages/ThorChainLP/components/AddLiquidity/AddLiquidityInput.tsx
@@ -45,6 +45,7 @@ import { Row } from 'components/Row/Row'
import { SlideTransition } from 'components/SlideTransition'
import { RawText, Text } from 'components/Text'
import type { TextPropTypes } from 'components/Text/Text'
+import { WarningAcknowledgement } from 'components/WarningAcknowledgement/WarningAcknowledgement'
import { useBrowserRouter } from 'hooks/useBrowserRouter/useBrowserRouter'
import { useFeatureFlag } from 'hooks/useFeatureFlag/useFeatureFlag'
import { useIsSmartContractAddress } from 'hooks/useIsSmartContractAddress/useIsSmartContractAddress'
@@ -185,6 +186,7 @@ export const AddLiquidityInput: React.FC = ({
const [poolAssetTxFeeCryptoBaseUnit, setPoolAssetTxFeeCryptoBaseUnit] = useState<
string | undefined
>()
+ const [shouldShowWarningAcknowledgement, setShouldShowWarningAcknowledgement] = useState(false)
// Virtual as in, these are the amounts if depositing symetrically. But a user may deposit asymetrically, so these are not the *actual* amounts
// Keeping these as virtual amounts is useful from a UI perspective, as it allows rebalancing to automagically work when switching from sym. type,
@@ -199,17 +201,6 @@ export const AddLiquidityInput: React.FC = ({
useState()
const [slippageDecimalPercentage, setSlippageDecimalPercentage] = useState()
- const [isUnsafeQuoteNoticeDismissed, setIsUnsafeQuoteNoticeDismissed] = useState(
- null,
- )
-
- const handleAcknowledgeUnsafeQuote = useCallback(() => {
- // We don't want to *immediately* set this or there will be a "click-through"
- // i.e the regular continue button will render immediately, and click will bubble to it
- setTimeout(() => {
- setIsUnsafeQuoteNoticeDismissed(true)
- }, 100)
- }, [])
const isUnsafeQuote = useMemo(
() =>
@@ -218,10 +209,6 @@ export const AddLiquidityInput: React.FC = ({
[slippageDecimalPercentage],
)
- useEffect(() => {
- if (isUnsafeQuote) setIsUnsafeQuoteNoticeDismissed(false)
- }, [isUnsafeQuote])
-
const { data: pools } = usePools()
const assets = useAppSelector(selectAssets)
@@ -1515,116 +1502,110 @@ export const AddLiquidityInput: React.FC = ({
virtualRuneDepositAmountFiatUserCurrency,
])
+ const handleDepositSubmit = useCallback(() => {
+ return isUnsafeQuote ? setShouldShowWarningAcknowledgement(true) : handleSubmit()
+ }, [handleSubmit, isUnsafeQuote])
+
if (!poolAsset || !runeAsset) return null
return (
- {renderHeader}
-
- {pairSelect}
-
-
- {translate('pools.depositAmounts')}
-
- {!opportunityId && (
-
- )}
- {tradeAssetInputs}
+
+ {renderHeader}
+
+ {pairSelect}
+
+
+ {translate('pools.depositAmounts')}
+
+ {!opportunityId && (
+
+ )}
+ {tradeAssetInputs}
+
-
-
-
+
+
+
+
+ {translate('common.slippage')}
+
+
+
+
+
+
+
+ {translate('common.gasFee')}
+
+
+
+
+
+
+
+
+
+ {bnOrZero(confirmedQuote?.feeAmountFiatUserCurrency).gt(0) && (
+ {`(${confirmedQuote?.feeBps ?? 0} bps)`}
+ )}
+
+
+
+ {bnOrZero(confirmedQuote?.feeAmountFiatUserCurrency).gt(0) ? (
+ <>
+
+
+ >
+ ) : (
+ <>
+
+
+ >
+ )}
+
+
+
+
+
-
- {translate('common.slippage')}
-
-
-
-
-
-
-
- {translate('common.gasFee')}
-
-
-
-
-
-
-
-
-
- {bnOrZero(confirmedQuote?.feeAmountFiatUserCurrency).gt(0) && (
- {`(${confirmedQuote?.feeBps ?? 0} bps)`}
- )}
-
-
-
- {bnOrZero(confirmedQuote?.feeAmountFiatUserCurrency).gt(0) ? (
- <>
-
-
- >
- ) : (
- <>
-
-
- >
- )}
-
-
-
-
-
-
- {incompleteAlert}
- {maybeOpportunityNotSupportedExplainer}
- {maybeAlert}
- {maybeSymAfterRuneAlert}
- {isUnsafeQuote && !isUnsafeQuoteNoticeDismissed ? (
- <>
-
-
-
-
-
- {translate('pools.unsafeQuote', {
- slippagePercentage: bnOrZero(slippageDecimalPercentage).times(100).toFixed(2),
- })}
-
-
-
-
-
- >
- ) : (
+ {incompleteAlert}
+ {maybeOpportunityNotSupportedExplainer}
+ {maybeAlert}
+ {maybeSymAfterRuneAlert}
+
- )}
-
-
+
+
+
)
}