diff --git a/cypress/e2e/swap/settings.test.ts b/cypress/e2e/swap/settings.test.ts index 6538cb5d58..9d878bbe7b 100644 --- a/cypress/e2e/swap/settings.test.ts +++ b/cypress/e2e/swap/settings.test.ts @@ -6,7 +6,7 @@ describe('Swap settings', () => { cy.contains('Settings').should('not.exist') cy.get(getTestSelector('open-settings-dialog-button')).click() cy.get(getTestSelector('mobile-settings-menu')).should('not.exist') - cy.contains('Max slippage').should('exist') + cy.contains('Max. slippage').should('exist') cy.contains('Transaction deadline').should('exist') cy.contains('UniswapX').should('exist') cy.contains('Local routing').should('exist') @@ -26,7 +26,7 @@ describe('Swap settings', () => { cy.get(getTestSelector('mobile-settings-menu')) .should('exist') .within(() => { - cy.contains('Max slippage').should('exist') + cy.contains('Max. slippage').should('exist') cy.contains('UniswapX').should('exist') cy.contains('Local routing').should('exist') cy.contains('Transaction deadline').should('exist') diff --git a/src/components/Settings/MaxSlippageSettings/index.test.tsx b/src/components/Settings/MaxSlippageSettings/index.test.tsx index bfafb16955..ef520fc626 100644 --- a/src/components/Settings/MaxSlippageSettings/index.test.tsx +++ b/src/components/Settings/MaxSlippageSettings/index.test.tsx @@ -46,7 +46,7 @@ describe('MaxSlippageSettings', () => { fireEvent.change(getSlippageInput(), { target: { value: '0.5' } }) - expect(screen.queryAllByText('0.50%').length).toEqual(1) + expect(screen.queryAllByText('0.5%').length).toEqual(1) }) it('updates input value on blur with the slippage in store', () => { renderSlippageSettings() @@ -56,7 +56,7 @@ describe('MaxSlippageSettings', () => { fireEvent.change(input, { target: { value: '0.5' } }) fireEvent.blur(input) - expect(input.value).toBe('0.50') + expect(input.value).toBe('0.5') }) it('clears errors on blur and overwrites incorrect value with the latest correct value', () => { renderSlippageSettings() @@ -68,7 +68,7 @@ describe('MaxSlippageSettings', () => { fireEvent.change(input, { target: { value: '500' } }) fireEvent.blur(input) - expect(input.value).toBe('50.00') + expect(input.value).toBe('50') }) it('does not allow to enter more than 2 digits after the decimal point', () => { renderSlippageSettings() diff --git a/src/components/Settings/MaxSlippageSettings/index.tsx b/src/components/Settings/MaxSlippageSettings/index.tsx index 6710372d25..f65251befa 100644 --- a/src/components/Settings/MaxSlippageSettings/index.tsx +++ b/src/components/Settings/MaxSlippageSettings/index.tsx @@ -8,6 +8,7 @@ import { useUserSlippageTolerance } from 'state/user/hooks' import { SlippageTolerance } from 'state/user/types' import styled from 'styled-components' import { CautionTriangle, ThemedText } from 'theme/components' +import { useFormatter } from 'utils/formatNumbers' import { Input, InputContainer } from '../Input' @@ -37,15 +38,23 @@ const NUMBER_WITH_MAX_TWO_DECIMAL_PLACES = /^(?:\d*\.\d{0,2}|\d+)$/ const MINIMUM_RECOMMENDED_SLIPPAGE = new Percent(5, 10_000) const MAXIMUM_RECOMMENDED_SLIPPAGE = new Percent(1, 100) +function useFormatSlippageInput() { + const { formatSlippage } = useFormatter() + + return (slippage: Percent) => formatSlippage(slippage).slice(0, -1) // remove % sign +} + export default function MaxSlippageSettings({ autoSlippage }: { autoSlippage: Percent }) { const [userSlippageTolerance, setUserSlippageTolerance] = useUserSlippageTolerance() + const { formatSlippage } = useFormatter() + const formatSlippageInput = useFormatSlippageInput() // In order to trigger `custom` mode, we need to set `userSlippageTolerance` to a value that is not `auto`. // To do so, we use `autoSlippage` value. However, since users are likely to change that value, // we render it as a placeholder instead of a value. const defaultSlippageInputValue = userSlippageTolerance !== SlippageTolerance.Auto && !userSlippageTolerance.equalTo(autoSlippage) - ? userSlippageTolerance.toFixed(2) + ? formatSlippageInput(userSlippageTolerance) : '' // If user has previously entered a custom slippage, we want to show that value in the input field @@ -101,7 +110,7 @@ export default function MaxSlippageSettings({ autoSlippage }: { autoSlippage: Pe header={ - Max slippage + Max. slippage Auto ) : ( - `${userSlippageTolerance.toFixed(2)}%` + formatSlippage(userSlippageTolerance) )} } @@ -149,7 +158,7 @@ export default function MaxSlippageSettings({ autoSlippage }: { autoSlippage: Pe parseSlippageInput(e.target.value)} onBlur={() => { @@ -167,7 +176,7 @@ export default function MaxSlippageSettings({ autoSlippage }: { autoSlippage: Pe {tooLow ? ( - Slippage below {MINIMUM_RECOMMENDED_SLIPPAGE.toFixed(2)}% may result in a failed transaction + Slippage below {formatSlippage(MINIMUM_RECOMMENDED_SLIPPAGE)} may result in a failed transaction ) : ( Your transaction may be frontrun and result in an unfavorable trade. diff --git a/src/components/Settings/MenuButton/index.tsx b/src/components/Settings/MenuButton/index.tsx index aac9e54698..25f82e7992 100644 --- a/src/components/Settings/MenuButton/index.tsx +++ b/src/components/Settings/MenuButton/index.tsx @@ -5,6 +5,7 @@ import { useUserSlippageTolerance } from 'state/user/hooks' import { SlippageTolerance } from 'state/user/types' import styled from 'styled-components' import { ThemedText } from 'theme/components' +import { useFormatter } from 'utils/formatNumbers' import validateUserSlippageTolerance, { SlippageValidationResult } from 'utils/validateUserSlippageTolerance' const Icon = styled(Settings)` @@ -46,6 +47,7 @@ const IconContainerWithSlippage = styled(IconContainer)<{ displayWarning?: boole const ButtonContent = () => { const [userSlippageTolerance] = useUserSlippageTolerance() + const { formatSlippage } = useFormatter() if (userSlippageTolerance === SlippageTolerance.Auto) { return ( @@ -60,7 +62,7 @@ const ButtonContent = () => { return ( - {userSlippageTolerance.toFixed(2)}% slippage + {formatSlippage(userSlippageTolerance)} slippage diff --git a/src/components/swap/MaxSlippageTooltip.tsx b/src/components/swap/MaxSlippageTooltip.tsx new file mode 100644 index 0000000000..1adef89ebd --- /dev/null +++ b/src/components/swap/MaxSlippageTooltip.tsx @@ -0,0 +1,53 @@ +import { Trans } from '@lingui/macro' +import { Percent, TradeType } from '@uniswap/sdk-core' +import Column from 'components/Column' +import { RowBetween } from 'components/Row' +import { InterfaceTrade } from 'state/routing/types' +import { ExternalLink, Separator, ThemedText } from 'theme/components' +import { NumberType, useFormatter } from 'utils/formatNumbers' + +const ExactInMessage = ({ amount }: { amount: string }) => ( + + If the price moves so that you will receive less than {amount}, your transaction will be reverted. This is the + minimum amount you are guaranteed to receive. + +) + +const ExactOutMessage = ({ amount }: { amount: string }) => ( + + If the price moves so that you will pay more than {amount}, your transaction will be reverted. This is the maximum + amount you are guaranteed to pay. + +) + +function SlippageHeader({ amount, isExactIn }: { amount: string; isExactIn: boolean }) { + return ( + + + {isExactIn ? Receive at least : Pay at most} + + {amount} + + ) +} + +export function MaxSlippageTooltip({ trade, allowedSlippage }: { trade: InterfaceTrade; allowedSlippage: Percent }) { + const isExactIn = trade.tradeType === TradeType.EXACT_INPUT + const amount = isExactIn ? trade.minimumAmountOut(allowedSlippage) : trade.maximumAmountIn(allowedSlippage) + + const formattedAmount = useFormatter().formatCurrencyAmount({ amount, type: NumberType.SwapDetailsAmount }) + const displayAmount = `${formattedAmount} ${amount.currency.symbol}` + + return ( + + + +
+ {isExactIn ? : }{' '} + + Learn more + +
+
+ ) +} diff --git a/src/components/swap/SwapDetailsDropdown.tsx b/src/components/swap/SwapDetailsDropdown.tsx index 6c6ca849f6..6e412449a6 100644 --- a/src/components/swap/SwapDetailsDropdown.tsx +++ b/src/components/swap/SwapDetailsDropdown.tsx @@ -108,11 +108,9 @@ function AdvancedSwapDetails(props: SwapDetailsProps & { open: boolean }) { + - - - diff --git a/src/components/swap/SwapLineItem.tsx b/src/components/swap/SwapLineItem.tsx index 58548de130..8b500822ea 100644 --- a/src/components/swap/SwapLineItem.tsx +++ b/src/components/swap/SwapLineItem.tsx @@ -11,12 +11,15 @@ import { useIsMobile } from 'nft/hooks' import React, { PropsWithChildren, useEffect, useState } from 'react' import { InterfaceTrade, TradeFillType } from 'state/routing/types' import { isPreviewTrade, isUniswapXTrade } from 'state/routing/utils' +import { useUserSlippageTolerance } from 'state/user/hooks' +import { SlippageTolerance } from 'state/user/types' import styled, { DefaultTheme } from 'styled-components' import { ExternalLink, ThemedText } from 'theme/components' import { NumberType, useFormatter } from 'utils/formatNumbers' import { getPriceImpactColor } from 'utils/prices' import { GasBreakdownTooltip, UniswapXDescription } from './GasBreakdownTooltip' +import { MaxSlippageTooltip } from './MaxSlippageTooltip' import SwapRoute from './SwapRoute' export enum SwapLineItemType { @@ -25,9 +28,9 @@ export enum SwapLineItemType { INPUT_TOKEN_FEE_ON_TRANSFER, OUTPUT_TOKEN_FEE_ON_TRANSFER, PRICE_IMPACT, + MAX_SLIPPAGE, MAXIMUM_INPUT, MINIMUM_OUTPUT, - EXPECTED_OUTPUT, ROUTING_INFO, } @@ -43,6 +46,18 @@ const ColorWrapper = styled.span<{ textColor?: keyof DefaultTheme }>` ${({ textColor, theme }) => textColor && `color: ${theme[textColor]};`} ` +const AutoBadge = styled(ThemedText.LabelMicro).attrs({ fontWeight: 535 })` + background: ${({ theme }) => theme.surface3}; + border-radius: 8px; + color: ${({ theme }) => theme.neutral2}; + height: 20px; + padding: 0 6px; + + ::after { + content: '${t`Auto`}'; + } +` + function FOTTooltipContent() { return ( <> @@ -91,7 +106,8 @@ type LineItemData = { function useLineItem(props: SwapLineItemProps): LineItemData | undefined { const { trade, syncing, allowedSlippage, type } = props - const { formatNumber } = useFormatter() + const { formatNumber, formatSlippage } = useFormatter() + const isAutoSlippage = useUserSlippageTolerance()[0] === SlippageTolerance.Auto const isUniswapX = isUniswapXTrade(trade) const isPreview = isPreviewTrade(trade) @@ -132,10 +148,20 @@ function useLineItem(props: SwapLineItemProps): LineItemData | undefined { TooltipBody: () => The impact your trade has on the market price of this pool., Value: () => (isPreview ? : ), } + case SwapLineItemType.MAX_SLIPPAGE: + return { + Label: () => Max. slippage, + TooltipBody: () => , + Value: () => ( + + {isAutoSlippage && } {formatSlippage(allowedSlippage)} + + ), + } case SwapLineItemType.MAXIMUM_INPUT: if (trade.tradeType === TradeType.EXACT_INPUT) return return { - Label: () => Maximum input, + Label: () => Pay at most, TooltipBody: () => ( The maximum amount you are guaranteed to spend. If the price slips any further, your transaction will @@ -148,7 +174,7 @@ function useLineItem(props: SwapLineItemProps): LineItemData | undefined { case SwapLineItemType.MINIMUM_OUTPUT: if (trade.tradeType === TradeType.EXACT_OUTPUT) return return { - Label: () => Minimum output, + Label: () => Receive at least, TooltipBody: () => ( The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will @@ -158,18 +184,6 @@ function useLineItem(props: SwapLineItemProps): LineItemData | undefined { Value: () => , loaderWidth: 70, } - case SwapLineItemType.EXPECTED_OUTPUT: - return { - Label: () => Expected output, - TooltipBody: () => ( - - The amount you expect to receive at the current market price. You may receive less or more if the market - price changes while your transaction is pending. - - ), - Value: () => , - loaderWidth: 65, - } case SwapLineItemType.ROUTING_INFO: if (isPreview) return { Label: () => Order routing, Value: () => } return { diff --git a/src/components/swap/SwapModalFooter.tsx b/src/components/swap/SwapModalFooter.tsx index 76e4e69183..86f5155c9d 100644 --- a/src/components/swap/SwapModalFooter.tsx +++ b/src/components/swap/SwapModalFooter.tsx @@ -74,10 +74,11 @@ export default function SwapModalFooter({ - - + + + {showAcceptChanges ? ( diff --git a/src/components/swap/__snapshots__/SwapDetailsDropdown.test.tsx.snap b/src/components/swap/__snapshots__/SwapDetailsDropdown.test.tsx.snap index 50660d221c..9531da7d20 100644 --- a/src/components/swap/__snapshots__/SwapDetailsDropdown.test.tsx.snap +++ b/src/components/swap/__snapshots__/SwapDetailsDropdown.test.tsx.snap @@ -43,6 +43,24 @@ exports[`SwapDetailsDropdown.tsx renders a trade 1`] = ` gap: 4px; } +.c21 { + width: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + padding: 0; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + gap: 8px; +} + .c4 { -webkit-box-pack: justify; -webkit-justify-content: space-between; @@ -138,6 +156,18 @@ exports[`SwapDetailsDropdown.tsx renders a trade 1`] = ` color: #7D7D7D; } +.c22 { + background: #22222212; + border-radius: 8px; + color: #7D7D7D; + height: 20px; + padding: 0 6px; +} + +.c22::after { + content: 'Auto'; +} + .c8 { background-color: transparent; border: none; @@ -329,7 +359,7 @@ exports[`SwapDetailsDropdown.tsx renders a trade 1`] = ` class="c9 c19 css-142zc9n" data-testid="swap-li-label" > - Minimum output + Max. slippage
- 0.00000000000000098 DEF -
- - - -
-
- Expected output -
-
-
-
- 0.000000000000001 DEF +
+
+ 2% +
diff --git a/src/components/swap/__snapshots__/SwapLineItem.test.tsx.snap b/src/components/swap/__snapshots__/SwapLineItem.test.tsx.snap index 111ab24d81..77a6e7bb58 100644 --- a/src/components/swap/__snapshots__/SwapLineItem.test.tsx.snap +++ b/src/components/swap/__snapshots__/SwapLineItem.test.tsx.snap @@ -263,6 +263,24 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = ` justify-content: flex-start; } +.c7 { + width: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + padding: 0; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + gap: 8px; +} + .c2 { -webkit-box-pack: justify; -webkit-justify-content: space-between; @@ -274,11 +292,36 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = ` color: #222222; } -.c9 { +.c8 { color: #7D7D7D; } -.c7 { +.c14 { + -webkit-text-decoration: none; + text-decoration: none; + cursor: pointer; + -webkit-transition-duration: 125ms; + transition-duration: 125ms; + color: #FC72FF; + stroke: #FC72FF; + font-weight: 500; +} + +.c14:hover { + opacity: 0.6; +} + +.c14:active { + opacity: 0.4; +} + +.c13 { + width: 100%; + height: 1px; + background-color: #22222212; +} + +.c10 { z-index: 1070; pointer-events: none; visibility: hidden; @@ -293,13 +336,13 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = ` height: inherit; } -.c10 { +.c15 { width: 8px; height: 8px; z-index: 9998; } -.c10::before { +.c15::before { position: absolute; width: 8px; height: 8px; @@ -313,43 +356,43 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = ` background: #FFFFFF; } -.c10.arrow-top { +.c15.arrow-top { bottom: -4px; } -.c10.arrow-top::before { +.c15.arrow-top::before { border-top: none; border-left: none; } -.c10.arrow-bottom { +.c15.arrow-bottom { top: -4px; } -.c10.arrow-bottom::before { +.c15.arrow-bottom::before { border-bottom: none; border-right: none; } -.c10.arrow-left { +.c15.arrow-left { right: -4px; } -.c10.arrow-left::before { +.c15.arrow-left::before { border-bottom: none; border-left: none; } -.c10.arrow-right { +.c15.arrow-right { left: -4px; } -.c10.arrow-right::before { +.c15.arrow-right::before { border-right: none; border-top: none; } -.c8 { +.c11 { max-width: 256px; width: calc(100vw - 16px); cursor: default; @@ -366,6 +409,21 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = ` box-shadow: 0 4px 8px 0 rgba(47,128,237,0.1); } +.c12 { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + gap: 4px; +} + .c6 { text-align: right; overflow-wrap: break-word; @@ -376,6 +434,18 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = ` color: #7D7D7D; } +.c9 { + background: #22222212; + border-radius: 8px; + color: #7D7D7D; + height: 20px; + padding: 0 6px; +} + +.c9::after { + content: 'Auto'; +} + @supports (-webkit-background-clip:text) and (-webkit-text-fill-color:transparent) { } @@ -387,7 +457,7 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Minimum output + Max. slippage
- 0.0000000000000009 DEF +
+
+ 2% +
- The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert. +
+
+
+ Receive at least +
+
+ 0.0000000000000009 DEF +
+
+
+
+ If the price moves so that you will receive less than 0.0000000000000009 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive. + + Learn more + +
+
@@ -566,7 +674,7 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Expected output + Receive at least
- 0.000000000000001 DEF + 0.0000000000000009 DEF
@@ -589,7 +697,7 @@ exports[`SwapLineItem.tsx dutch order eth input 1`] = `
- The amount you expect to receive at the current market price. You may receive less or more if the market price changes while your transaction is pending. + The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert.
@@ -1455,7 +1633,7 @@ exports[`SwapLineItem.tsx exact input 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Minimum output + Max. slippage
- 0.00000000000000098 DEF +
+
+ 2% +
- The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert. +
+
+
+ Receive at least +
+
+ 0.00000000000000098 DEF +
+
+
+
+ If the price moves so that you will receive less than 0.00000000000000098 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive. + + Learn more + +
+
@@ -1630,7 +1846,7 @@ exports[`SwapLineItem.tsx exact input 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Expected output + Receive at least
- 0.000000000000001 DEF + 0.00000000000000098 DEF
@@ -1653,7 +1869,7 @@ exports[`SwapLineItem.tsx exact input 1`] = `
- The amount you expect to receive at the current market price. You may receive less or more if the market price changes while your transaction is pending. + The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert.
@@ -2794,7 +3080,7 @@ exports[`SwapLineItem.tsx exact input api 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Minimum output + Max. slippage
- 0.00000000000000098 DEF +
+
+ 2% +
- The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert. +
+
+
+ Receive at least +
+
+ 0.00000000000000098 DEF +
+
+
+
+ If the price moves so that you will receive less than 0.00000000000000098 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive. + + Learn more + +
+
@@ -2969,7 +3293,7 @@ exports[`SwapLineItem.tsx exact input api 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Expected output + Receive at least
- 0.000000000000001 DEF + 0.00000000000000098 DEF
@@ -2992,7 +3316,7 @@ exports[`SwapLineItem.tsx exact input api 1`] = `
- The amount you expect to receive at the current market price. You may receive less or more if the market price changes while your transaction is pending. + The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert.
@@ -4133,7 +4527,7 @@ exports[`SwapLineItem.tsx exact output 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Maximum input + Max. slippage
- 0.00000000000000102 ABC +
+
+ 2% +
- The maximum amount you are guaranteed to spend. If the price slips any further, your transaction will revert. +
+
+
+ Pay at most +
+
+ 0.00000000000000102 ABC +
+
+
+
+ If the price moves so that you will pay more than 0.00000000000000102 ABC, your transaction will be reverted. This is the maximum amount you are guaranteed to pay. + + Learn more + +
+
@@ -4308,7 +4740,7 @@ exports[`SwapLineItem.tsx exact output 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Expected output + Pay at most
- 0.000000000000001 GHI + 0.00000000000000102 ABC
@@ -4331,7 +4763,7 @@ exports[`SwapLineItem.tsx exact output 1`] = `
- The amount you expect to receive at the current market price. You may receive less or more if the market price changes while your transaction is pending. + The maximum amount you are guaranteed to spend. If the price slips any further, your transaction will revert.
@@ -5678,7 +6180,7 @@ exports[`SwapLineItem.tsx fee on buy 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Minimum output + Max. slippage
- 0.000000000000000952 DEF +
+
+ 2% +
- The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert. +
+
+
+ Receive at least +
+
+ 0.000000000000000952 DEF +
+
+
+
+ If the price moves so that you will receive less than 0.000000000000000952 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive. + + Learn more + +
+
@@ -5853,7 +6393,7 @@ exports[`SwapLineItem.tsx fee on buy 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Expected output + Receive at least
- 0.00000000000000097 DEF + 0.000000000000000952 DEF
@@ -5876,7 +6416,7 @@ exports[`SwapLineItem.tsx fee on buy 1`] = `
- The amount you expect to receive at the current market price. You may receive less or more if the market price changes while your transaction is pending. + The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert.
@@ -7223,7 +7833,7 @@ exports[`SwapLineItem.tsx fee on sell 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Minimum output + Max. slippage
- 0.000000000000000952 DEF +
+
+ 2% +
- The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert. +
+
+
+ Receive at least +
+
+ 0.000000000000000952 DEF +
+
+
+
+ If the price moves so that you will receive less than 0.000000000000000952 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive. + + Learn more + +
+
@@ -7398,7 +8046,7 @@ exports[`SwapLineItem.tsx fee on sell 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Expected output + Receive at least
- 0.00000000000000097 DEF + 0.000000000000000952 DEF
@@ -7421,7 +8069,7 @@ exports[`SwapLineItem.tsx fee on sell 1`] = `
- The amount you expect to receive at the current market price. You may receive less or more if the market price changes while your transaction is pending. + The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert.
@@ -8566,7 +9284,7 @@ exports[`SwapLineItem.tsx preview exact in 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Minimum output + Max. slippage
- 0.00000000000000098 DEF +
+
+ 2% +
- The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert. +
+
+
+ Receive at least +
+
+ 0.00000000000000098 DEF +
+
+
+
+ If the price moves so that you will receive less than 0.00000000000000098 DEF, your transaction will be reverted. This is the minimum amount you are guaranteed to receive. + + Learn more + +
+
@@ -8741,7 +9497,7 @@ exports[`SwapLineItem.tsx preview exact in 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Expected output + Receive at least
- 0.000000000000001 DEF + 0.00000000000000098 DEF
@@ -8764,7 +9520,7 @@ exports[`SwapLineItem.tsx preview exact in 1`] = `
- The amount you expect to receive at the current market price. You may receive less or more if the market price changes while your transaction is pending. + The minimum amount you are guaranteed to receive. If the price slips any further, your transaction will revert.
- Minimum output + Max. slippage
.c0 { @@ -9103,7 +9859,7 @@ exports[`SwapLineItem.tsx syncing 1`] = ` will-change: background-position; border-radius: 12px; height: 15px; - width: 65px; + width: 70px; } .c4 { @@ -9118,13 +9874,13 @@ exports[`SwapLineItem.tsx syncing 1`] = ` class="c3 c4 css-142zc9n" data-testid="swap-li-label" > - Expected output + Receive at least
.c0 { diff --git a/src/components/swap/__snapshots__/SwapModalFooter.test.tsx.snap b/src/components/swap/__snapshots__/SwapModalFooter.test.tsx.snap index 61af8963a5..3b67ae5e5b 100644 --- a/src/components/swap/__snapshots__/SwapModalFooter.test.tsx.snap +++ b/src/components/swap/__snapshots__/SwapModalFooter.test.tsx.snap @@ -26,6 +26,24 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] = } .c10 { + width: 100%; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + padding: 0; + -webkit-align-items: center; + -webkit-box-align: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: start; + -webkit-justify-content: flex-start; + -ms-flex-pack: start; + justify-content: flex-start; + gap: 8px; +} + +.c13 { width: 100%; display: -webkit-box; display: -webkit-flex; @@ -54,6 +72,10 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] = color: #222222; } +.c11 { + color: #7D7D7D; +} + .c0 { display: -webkit-box; display: -webkit-flex; @@ -89,6 +111,18 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] = color: #7D7D7D; } +.c12 { + background: #22222212; + border-radius: 8px; + color: #7D7D7D; + height: 20px; + padding: 0 6px; +} + +.c12::after { + content: 'Auto'; +} + .c1 { padding: 0 8px; } @@ -143,7 +177,35 @@ exports[`SwapModalFooter.tsx matches base snapshot, test trade exact input 1`] = class="c5 c8 css-142zc9n" data-testid="swap-li-label" > - Minimum output + Max. slippage + +
+
+
+
+
+ 2% +
+
+
+
+
+
+
+ Receive at least
gas cost icon - Minimum output + Max. slippage +
+
+
+
+
+
+ 2% +
+
+
+
+
+
+
+ Receive at least
{ expect(formatSlippage(undefined)).toBe('-') }) - it('correctly formats a percent with 3 significant digits', () => { + it('correctly formats a percent with no trailing digits', () => { const { formatSlippage } = renderHook(() => useFormatter()).result.current expect(formatSlippage(new Percent(1, 100000))).toBe('0.001%') - expect(formatSlippage(new Percent(1, 1000))).toBe('0.100%') - expect(formatSlippage(new Percent(1, 100))).toBe('1.000%') - expect(formatSlippage(new Percent(1, 10))).toBe('10.000%') - expect(formatSlippage(new Percent(1, 1))).toBe('100.000%') + expect(formatSlippage(new Percent(1, 1000))).toBe('0.1%') + expect(formatSlippage(new Percent(1, 100))).toBe('1%') + expect(formatSlippage(new Percent(1, 10))).toBe('10%') + expect(formatSlippage(new Percent(1, 1))).toBe('100%') }) - it('correctly formats a percent with 3 significant digits with french locale', () => { + it('correctly formats a percent with french locale', () => { mocked(useActiveLocale).mockReturnValue('fr-FR') const { formatSlippage } = renderHook(() => useFormatter()).result.current expect(formatSlippage(new Percent(1, 100000))).toBe('0,001%') - expect(formatSlippage(new Percent(1, 1000))).toBe('0,100%') - expect(formatSlippage(new Percent(1, 100))).toBe('1,000%') - expect(formatSlippage(new Percent(1, 10))).toBe('10,000%') - expect(formatSlippage(new Percent(1, 1))).toBe('100,000%') + expect(formatSlippage(new Percent(1, 1000))).toBe('0,1%') + expect(formatSlippage(new Percent(1, 100))).toBe('1%') + expect(formatSlippage(new Percent(1, 10))).toBe('10%') + expect(formatSlippage(new Percent(1, 1))).toBe('100%') }) }) diff --git a/src/utils/formatNumbers.ts b/src/utils/formatNumbers.ts index bf98667940..22ff6290c4 100644 --- a/src/utils/formatNumbers.ts +++ b/src/utils/formatNumbers.ts @@ -472,7 +472,6 @@ function formatSlippage(slippage: Percent | undefined, locale: SupportedLocale = if (!slippage) return '-' return `${Number(slippage.toFixed(3)).toLocaleString(locale, { - minimumFractionDigits: 3, maximumFractionDigits: 3, useGrouping: false, })}%`