Skip to content

Commit a90c00b

Browse files
committed
feat: add hard confirm for high impact swaps
1 parent 9f4e1a4 commit a90c00b

File tree

6 files changed

+69
-19
lines changed

6 files changed

+69
-19
lines changed

src/components/transactions/Switch/BaseSwitchModalContent.tsx

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { normalize, normalizeBN } from '@aave/math-utils';
22
import { OrderStatus, SupportedChainId, WRAPPED_NATIVE_CURRENCIES } from '@cowprotocol/cow-sdk';
33
import { SwitchVerticalIcon } from '@heroicons/react/outline';
44
import { Trans } from '@lingui/macro';
5-
import { Box, CircularProgress, IconButton, SvgIcon, Typography } from '@mui/material';
5+
import { Box, Checkbox, CircularProgress, IconButton, SvgIcon, Typography } from '@mui/material';
66
import { useQueryClient } from '@tanstack/react-query';
77
import { debounce } from 'lodash';
88
import React, { useEffect, useMemo, useState } from 'react';
@@ -54,15 +54,23 @@ export type SwitchDetailsParams = Parameters<
5454
NonNullable<SwitchModalCustomizableProps['switchDetails']>
5555
>[0];
5656

57-
const shouldShowWarning = (destValueInUsd: number, srcValueInUsd: number) => {
57+
const valueLostPercentage = (destValueInUsd: number, srcValueInUsd: number) => {
5858
const receivingPercentage = destValueInUsd / srcValueInUsd;
5959
const valueLostPercentage = receivingPercentage ? 1 - receivingPercentage : 0;
60+
return valueLostPercentage;
61+
};
62+
63+
const shouldShowWarning = (lostValue: number, srcValueInUsd: number) => {
64+
if (srcValueInUsd > 500000) return lostValue > 0.03;
65+
if (srcValueInUsd > 100000) return lostValue > 0.04;
66+
if (srcValueInUsd > 10000) return lostValue > 0.05;
67+
if (srcValueInUsd > 1000) return lostValue > 0.07;
68+
69+
return lostValue > 0.05;
70+
};
6071

61-
if (destValueInUsd > 500000) return valueLostPercentage > 0.03;
62-
if (destValueInUsd > 100000) return valueLostPercentage > 0.04;
63-
if (destValueInUsd > 10000) return valueLostPercentage > 0.05;
64-
if (destValueInUsd > 1000) return valueLostPercentage > 0.07;
65-
return valueLostPercentage > 0.1;
72+
const shouldRequireConfirmation = (lostValue: number) => {
73+
return lostValue > 0.2;
6674
};
6775

6876
export const getFilteredTokensForSwitch = (chainId: number): TokenInfoWithBalance[] => {
@@ -153,6 +161,7 @@ export const BaseSwitchModalContent = ({
153161
const switchProvider = useSwitchProvider({ chainId: selectedChainId });
154162
const [slippage, setSlippage] = useState(switchProvider == 'cowprotocol' ? '2' : '0.10');
155163
const [showGasStation, setShowGasStation] = useState(switchProvider == 'paraswap');
164+
const [highPriceImpactConfirmed, setHighPriceImpactConfirmed] = useState(false);
156165
const selectedNetworkConfig = getNetworkConfig(selectedChainId);
157166
const isWrongNetwork = useIsWrongNetwork(selectedChainId);
158167

@@ -186,6 +195,7 @@ export const BaseSwitchModalContent = ({
186195

187196
const handleInputChange = (value: string) => {
188197
setTxError(undefined);
198+
setHighPriceImpactConfirmed(false);
189199
if (value === '-1') {
190200
// Max Selected
191201
setInputAmount(selectedInputToken.balance);
@@ -462,12 +472,17 @@ export const BaseSwitchModalContent = ({
462472
})
463473
: null;
464474

465-
const showWarning = switchRates
466-
? shouldShowWarning(
467-
Number(switchRates.destUSD) * (1 - safeSlippage),
468-
Number(switchRates.srcUSD)
475+
const lostValue = switchRates
476+
? valueLostPercentage(
477+
Number(switchRates?.destUSD) * (1 - safeSlippage),
478+
Number(switchRates?.srcUSD)
469479
)
470-
: undefined;
480+
: 0;
481+
482+
const showWarning = switchRates
483+
? shouldShowWarning(lostValue, Number(switchRates?.srcUSD))
484+
: false;
485+
const requireConfirmation = switchRates ? shouldRequireConfirmation(lostValue) : false;
471486

472487
const isSwappingSafetyModuleToken = SAFETY_MODULE_TOKENS.includes(
473488
selectedInputToken.symbol.toLowerCase()
@@ -657,13 +672,43 @@ export const BaseSwitchModalContent = ({
657672
/>
658673
{txError && <ParaswapErrorDisplay txError={txError} />}
659674

660-
{!!showWarning && (
661-
<Warning severity="warning" icon={false} sx={{ mt: 2, mb: 2 }}>
675+
{showWarning && (
676+
<Warning
677+
severity="warning"
678+
icon={false}
679+
sx={{
680+
mt: 2,
681+
mb: 2,
682+
display: 'flex',
683+
flexDirection: 'column',
684+
alignItems: 'center',
685+
}}
686+
>
662687
<Typography variant="caption">
663688
<Trans>
664689
High price impact. This route may return less due to low liquidity.
665690
</Trans>
666691
</Typography>
692+
{requireConfirmation && (
693+
<Box
694+
sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center', mt: 2 }}
695+
>
696+
<Typography variant="caption">
697+
<Trans>
698+
I confirm the swap with a potential {(lostValue * 100).toFixed(0)}% value
699+
loss
700+
</Trans>
701+
</Typography>
702+
<Checkbox
703+
checked={highPriceImpactConfirmed}
704+
onChange={() => {
705+
setHighPriceImpactConfirmed(!highPriceImpactConfirmed);
706+
}}
707+
size="small"
708+
data-cy={'high-price-impact-checkbox'}
709+
/>
710+
</Box>
711+
)}
667712
</Warning>
668713
)}
669714

@@ -697,7 +742,8 @@ export const BaseSwitchModalContent = ({
697742
Number(debounceInputAmount) > Number(selectedInputToken.balance) ||
698743
!user ||
699744
slippageValidation?.severity === ValidationSeverity.ERROR ||
700-
isSwappingSafetyModuleToken
745+
isSwappingSafetyModuleToken ||
746+
(requireConfirmation && !highPriceImpactConfirmed)
701747
}
702748
chainId={selectedChainId}
703749
switchRates={switchRates}

src/locales/el/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/en/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/en/messages.po

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,10 @@ msgstr "Liquidation at"
11791179
msgid "Costs & Fees"
11801180
msgstr "Costs & Fees"
11811181

1182+
#: src/components/transactions/Switch/BaseSwitchModalContent.tsx
1183+
msgid "I confirm the swap with a potential {0}% value loss"
1184+
msgstr "I confirm the swap with a potential {0}% value loss"
1185+
11821186
#: src/components/transactions/SavingsGho/SavingsGhoModalDepositContent.tsx
11831187
msgid "deposited"
11841188
msgstr "deposited"

src/locales/es/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/locales/fr/messages.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)