Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
I
interface
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
LuckySwap
interface
Commits
0f519911
Unverified
Commit
0f519911
authored
Feb 15, 2022
by
Zach Pomerantz
Committed by
GitHub
Feb 15, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: improved warning ux (#3310)
parent
da8884d8
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
57 additions
and
73 deletions
+57
-73
Input.tsx
src/lib/components/Swap/Input.tsx
+2
-2
Output.tsx
src/lib/components/Swap/Output.tsx
+17
-11
MaxSlippageSelect.tsx
src/lib/components/Swap/Settings/MaxSlippageSelect.tsx
+12
-30
Details.tsx
src/lib/components/Swap/Summary/Details.tsx
+6
-17
index.tsx
src/lib/components/Swap/Summary/index.tsx
+4
-8
useAllowedSlippage.ts
src/lib/hooks/useAllowedSlippage.ts
+10
-1
settings.ts
src/lib/state/settings.ts
+0
-4
prices.ts
src/utils/prices.ts
+6
-0
No files found.
src/lib/components/Swap/Input.tsx
View file @
0f519911
...
@@ -16,7 +16,7 @@ import Row from '../Row'
...
@@ -16,7 +16,7 @@ import Row from '../Row'
import
TokenImg
from
'
../TokenImg
'
import
TokenImg
from
'
../TokenImg
'
import
TokenInput
from
'
./TokenInput
'
import
TokenInput
from
'
./TokenInput
'
export
const
Loading
Span
=
styled
.
span
<
{
$loading
:
boolean
}
>
`
export
const
Loading
Row
=
styled
(
Row
)
<
{
$loading
:
boolean
}
>
`
${
loadingOpacityCss
}
;
${
loadingOpacityCss
}
;
`
`
...
@@ -85,7 +85,7 @@ export default function Input({ disabled, focused }: InputProps) {
...
@@ -85,7 +85,7 @@ export default function Input({ disabled, focused }: InputProps) {
>
>
<
ThemedText
.
Body2
color=
"secondary"
>
<
ThemedText
.
Body2
color=
"secondary"
>
<
Row
>
<
Row
>
<
Loading
Span
$loading=
{
isLoading
}
>
{
inputUSDC
?
`$${inputUSDC.toFixed(2)}`
:
'
-
'
}
</
LoadingSpan
>
<
Loading
Row
$loading=
{
isLoading
}
>
{
inputUSDC
?
`$${inputUSDC.toFixed(2)}`
:
'
-
'
}
</
LoadingRow
>
{
balance
&&
(
{
balance
&&
(
<
Balance
color=
{
inputCurrencyAmount
?.
greaterThan
(
balance
)
?
'
error
'
:
undefined
}
focused=
{
focused
}
>
<
Balance
color=
{
inputCurrencyAmount
?.
greaterThan
(
balance
)
?
'
error
'
:
undefined
}
focused=
{
focused
}
>
Balance:
<
span
style=
{
{
userSelect
:
'
text
'
}
}
>
{
formatCurrencyAmount
(
balance
,
4
,
i18n
.
locale
)
}
</
span
>
Balance:
<
span
style=
{
{
userSelect
:
'
text
'
}
}
>
{
formatCurrencyAmount
(
balance
,
4
,
i18n
.
locale
)
}
</
span
>
...
...
src/lib/components/Swap/Output.tsx
View file @
0f519911
...
@@ -12,10 +12,11 @@ import { PropsWithChildren, useMemo } from 'react'
...
@@ -12,10 +12,11 @@ import { PropsWithChildren, useMemo } from 'react'
import
{
TradeState
}
from
'
state/routing/types
'
import
{
TradeState
}
from
'
state/routing/types
'
import
{
computeFiatValuePriceImpact
}
from
'
utils/computeFiatValuePriceImpact
'
import
{
computeFiatValuePriceImpact
}
from
'
utils/computeFiatValuePriceImpact
'
import
{
formatCurrencyAmount
}
from
'
utils/formatCurrencyAmount
'
import
{
formatCurrencyAmount
}
from
'
utils/formatCurrencyAmount
'
import
{
getPriceImpactWarning
}
from
'
utils/prices
'
import
Column
from
'
../Column
'
import
Column
from
'
../Column
'
import
Row
from
'
../Row
'
import
Row
from
'
../Row
'
import
{
Balance
,
InputProps
,
Loading
Span
}
from
'
./Input
'
import
{
Balance
,
InputProps
,
Loading
Row
}
from
'
./Input
'
import
TokenInput
from
'
./TokenInput
'
import
TokenInput
from
'
./TokenInput
'
export
const
colorAtom
=
atom
<
string
|
undefined
>
(
undefined
)
export
const
colorAtom
=
atom
<
string
|
undefined
>
(
undefined
)
...
@@ -63,16 +64,19 @@ export default function Output({ disabled, focused, children }: PropsWithChildre
...
@@ -63,16 +64,19 @@ export default function Output({ disabled, focused, children }: PropsWithChildre
const
outputUSDC
=
useUSDCValue
(
outputCurrencyAmount
)
const
outputUSDC
=
useUSDCValue
(
outputCurrencyAmount
)
const
priceImpact
=
useMemo
(()
=>
{
const
priceImpact
=
useMemo
(()
=>
{
const
computedChange
=
computeFiatValuePriceImpact
(
inputUSDC
,
outputUSDC
)
const
fiatValuePriceImpact
=
computeFiatValuePriceImpact
(
inputUSDC
,
outputUSDC
)
return
computedChange
?
parseFloat
(
computedChange
.
multiply
(
-
1
)?.
toSignificant
(
3
))
:
undefined
if
(
!
fiatValuePriceImpact
)
return
null
},
[
inputUSDC
,
outputUSDC
])
const
usdc
=
useMemo
(()
=>
{
const
color
=
getPriceImpactWarning
(
fiatValuePriceImpact
)
if
(
outputUSDC
)
{
const
sign
=
fiatValuePriceImpact
.
lessThan
(
0
)
?
'
+
'
:
''
return
`$
${
outputUSDC
.
toFixed
(
2
)}
(
${
priceImpact
&&
priceImpact
>
0
?
'
+
'
:
''
}${
priceImpact
}
%)`
const
displayedPriceImpact
=
parseFloat
(
fiatValuePriceImpact
.
multiply
(
-
1
)?.
toSignificant
(
3
))
}
return
(
return
''
<
ThemedText
.
Body2
color=
{
color
}
>
},
[
priceImpact
,
outputUSDC
])
(
{
sign
}
{
displayedPriceImpact
}
%)
</
ThemedText
.
Body2
>
)
},
[
inputUSDC
,
outputUSDC
])
return
(
return
(
<
DynamicThemeProvider
color=
{
color
}
>
<
DynamicThemeProvider
color=
{
color
}
>
...
@@ -92,7 +96,9 @@ export default function Output({ disabled, focused, children }: PropsWithChildre
...
@@ -92,7 +96,9 @@ export default function Output({ disabled, focused, children }: PropsWithChildre
>
>
<
ThemedText
.
Body2
color=
"secondary"
>
<
ThemedText
.
Body2
color=
"secondary"
>
<
Row
>
<
Row
>
<
LoadingSpan
$loading=
{
isLoading
}
>
{
usdc
}
</
LoadingSpan
>
<
LoadingRow
gap=
{
0.5
}
$loading=
{
isLoading
}
>
{
outputUSDC
?.
toFixed
(
2
)
}
{
priceImpact
}
</
LoadingRow
>
{
balance
&&
(
{
balance
&&
(
<
Balance
focused=
{
focused
}
>
<
Balance
focused=
{
focused
}
>
Balance:
<
span
style=
{
{
userSelect
:
'
text
'
}
}
>
{
formatCurrencyAmount
(
balance
,
4
,
i18n
.
locale
)
}
</
span
>
Balance:
<
span
style=
{
{
userSelect
:
'
text
'
}
}
>
{
formatCurrencyAmount
(
balance
,
4
,
i18n
.
locale
)
}
</
span
>
...
...
src/lib/components/Swap/Settings/MaxSlippageSelect.tsx
View file @
0f519911
import
{
Trans
}
from
'
@lingui/macro
'
import
{
Trans
}
from
'
@lingui/macro
'
import
{
Percent
}
from
'
@uniswap/sdk-core
'
import
{
useAtom
}
from
'
jotai
'
import
{
useAtom
}
from
'
jotai
'
import
Popover
from
'
lib/components/Popover
'
import
Popover
from
'
lib/components/Popover
'
import
{
useTooltip
}
from
'
lib/components/Tooltip
'
import
{
useTooltip
}
from
'
lib/components/Tooltip
'
import
{
toPercent
}
from
'
lib/hooks/useAllowedSlippage
'
import
{
getSlippageWarning
,
toPercent
}
from
'
lib/hooks/useAllowedSlippage
'
import
{
AlertTriangle
,
Check
,
Icon
,
LargeIcon
,
XOctagon
}
from
'
lib/icons
'
import
{
AlertTriangle
,
Check
,
Icon
,
LargeIcon
,
XOctagon
}
from
'
lib/icons
'
import
{
autoSlippageAtom
,
MAX_VALID_SLIPPAGE
,
maxSlippageAtom
,
MIN_HIGH_SLIPPAGE
}
from
'
lib/state/settings
'
import
{
autoSlippageAtom
,
maxSlippageAtom
}
from
'
lib/state/settings
'
import
styled
,
{
Color
,
ThemedText
}
from
'
lib/theme
'
import
styled
,
{
ThemedText
}
from
'
lib/theme
'
import
{
forwardRef
,
memo
,
ReactNode
,
useCallback
,
useMemo
,
useRef
,
useState
}
from
'
react
'
import
{
forwardRef
,
memo
,
ReactNode
,
useCallback
,
useMemo
,
useRef
,
useState
}
from
'
react
'
import
{
BaseButton
,
TextButton
}
from
'
../../Button
'
import
{
BaseButton
,
TextButton
}
from
'
../../Button
'
...
@@ -56,35 +55,18 @@ const Option = forwardRef<HTMLButtonElement, OptionProps>(function Option(
...
@@ -56,35 +55,18 @@ const Option = forwardRef<HTMLButtonElement, OptionProps>(function Option(
)
)
})
})
enum
WarningState
{
const
Warning
=
memo
(
function
Warning
({
state
,
showTooltip
}:
{
state
?:
'
warning
'
|
'
error
'
;
showTooltip
:
boolean
})
{
INVALID_SLIPPAGE
=
1
,
let
icon
:
Icon
|
undefined
HIGH_SLIPPAGE
,
}
function
toWarningState
(
percent
:
Percent
|
undefined
):
WarningState
|
undefined
{
if
(
percent
?.
greaterThan
(
MAX_VALID_SLIPPAGE
))
{
return
WarningState
.
INVALID_SLIPPAGE
}
else
if
(
percent
?.
greaterThan
(
MIN_HIGH_SLIPPAGE
))
{
return
WarningState
.
HIGH_SLIPPAGE
}
return
}
const
Warning
=
memo
(
function
Warning
({
state
,
showTooltip
}:
{
state
:
WarningState
;
showTooltip
:
boolean
})
{
let
icon
:
Icon
let
color
:
Color
let
content
:
ReactNode
let
content
:
ReactNode
let
show
=
showTooltip
let
show
=
showTooltip
switch
(
state
)
{
switch
(
state
)
{
case
WarningState
.
INVALID_SLIPPAGE
:
case
'
error
'
:
icon
=
XOctagon
icon
=
XOctagon
color
=
'
error
'
content
=
invalidSlippage
content
=
invalidSlippage
show
=
true
show
=
true
break
break
case
WarningState
.
HIGH_SLIPPAGE
:
case
'
warning
'
:
icon
=
AlertTriangle
icon
=
AlertTriangle
color
=
'
warning
'
content
=
highSlippage
content
=
highSlippage
break
break
}
}
...
@@ -97,7 +79,7 @@ const Warning = memo(function Warning({ state, showTooltip }: { state: WarningSt
...
@@ -97,7 +79,7 @@ const Warning = memo(function Warning({ state, showTooltip }: { state: WarningSt
offset=
{
16
}
offset=
{
16
}
contained
contained
>
>
<
LargeIcon
icon=
{
icon
}
color=
{
color
}
size=
{
1.25
}
/>
<
LargeIcon
icon=
{
icon
}
color=
{
state
}
size=
{
1.25
}
/>
</
Popover
>
</
Popover
>
)
)
})
})
...
@@ -106,7 +88,7 @@ export default function MaxSlippageSelect() {
...
@@ -106,7 +88,7 @@ export default function MaxSlippageSelect() {
const
[
autoSlippage
,
setAutoSlippage
]
=
useAtom
(
autoSlippageAtom
)
const
[
autoSlippage
,
setAutoSlippage
]
=
useAtom
(
autoSlippageAtom
)
const
[
maxSlippage
,
setMaxSlippage
]
=
useAtom
(
maxSlippageAtom
)
const
[
maxSlippage
,
setMaxSlippage
]
=
useAtom
(
maxSlippageAtom
)
const
maxSlippageInput
=
useMemo
(()
=>
maxSlippage
?.
toString
()
||
''
,
[
maxSlippage
])
const
maxSlippageInput
=
useMemo
(()
=>
maxSlippage
?.
toString
()
||
''
,
[
maxSlippage
])
const
[
warning
,
setWarning
]
=
useState
<
WarningState
|
undefined
>
(
toWarningState
(
toPercent
(
maxSlippage
)))
const
[
warning
,
setWarning
]
=
useState
<
'
warning
'
|
'
error
'
|
undefined
>
(
getSlippageWarning
(
toPercent
(
maxSlippage
)))
const
option
=
useRef
<
HTMLButtonElement
>
(
null
)
const
option
=
useRef
<
HTMLButtonElement
>
(
null
)
const
showTooltip
=
useTooltip
(
option
.
current
)
const
showTooltip
=
useTooltip
(
option
.
current
)
...
@@ -117,10 +99,10 @@ export default function MaxSlippageSelect() {
...
@@ -117,10 +99,10 @@ export default function MaxSlippageSelect() {
const
processValue
=
useCallback
(
const
processValue
=
useCallback
(
(
value
:
number
|
undefined
)
=>
{
(
value
:
number
|
undefined
)
=>
{
const
percent
=
toPercent
(
value
)
const
percent
=
toPercent
(
value
)
const
warning
=
toWarningState
(
percent
)
const
warning
=
getSlippageWarning
(
percent
)
setWarning
(
warning
)
setWarning
(
warning
)
setMaxSlippage
(
value
)
setMaxSlippage
(
value
)
setAutoSlippage
(
!
percent
||
warning
===
WarningState
.
INVALID_SLIPPAGE
)
setAutoSlippage
(
!
percent
||
warning
===
'
error
'
)
},
},
[
setAutoSlippage
,
setMaxSlippage
]
[
setAutoSlippage
,
setMaxSlippage
]
)
)
...
@@ -146,7 +128,7 @@ export default function MaxSlippageSelect() {
...
@@ -146,7 +128,7 @@ export default function MaxSlippageSelect() {
ref=
{
option
}
ref=
{
option
}
tabIndex=
{
-
1
}
tabIndex=
{
-
1
}
>
>
<
Row
color=
{
warning
===
WarningState
.
INVALID_SLIPPAGE
?
'
error
'
:
undefined
}
>
<
Row
color=
{
warning
===
'
error
'
?
'
error
'
:
undefined
}
>
<
DecimalInput
<
DecimalInput
size=
{
Math
.
max
(
maxSlippageInput
.
length
,
3
)
}
size=
{
Math
.
max
(
maxSlippageInput
.
length
,
3
)
}
value=
{
maxSlippageInput
}
value=
{
maxSlippageInput
}
...
...
src/lib/components/Swap/Summary/Details.tsx
View file @
0f519911
...
@@ -2,15 +2,14 @@ import { t } from '@lingui/macro'
...
@@ -2,15 +2,14 @@ import { t } from '@lingui/macro'
import
{
useLingui
}
from
'
@lingui/react
'
import
{
useLingui
}
from
'
@lingui/react
'
import
{
Trade
}
from
'
@uniswap/router-sdk
'
import
{
Trade
}
from
'
@uniswap/router-sdk
'
import
{
Currency
,
Percent
,
TradeType
}
from
'
@uniswap/sdk-core
'
import
{
Currency
,
Percent
,
TradeType
}
from
'
@uniswap/sdk-core
'
import
{
ALLOWED_PRICE_IMPACT_HIGH
,
ALLOWED_PRICE_IMPACT_MEDIUM
}
from
'
constants/misc
'
import
{
useAtomValue
}
from
'
jotai/utils
'
import
{
useAtomValue
}
from
'
jotai/utils
'
import
{
MIN_HIGH_SLIPPAGE
}
from
'
lib/state/settings
'
import
{
getSlippageWarning
}
from
'
lib/hooks/useAllowedSlippage
'
import
{
feeOptionsAtom
}
from
'
lib/state/swap
'
import
{
feeOptionsAtom
}
from
'
lib/state/swap
'
import
styled
,
{
Color
,
ThemedText
}
from
'
lib/theme
'
import
styled
,
{
Color
,
ThemedText
}
from
'
lib/theme
'
import
{
useMemo
}
from
'
react
'
import
{
useMemo
}
from
'
react
'
import
{
currencyId
}
from
'
utils/currencyId
'
import
{
currencyId
}
from
'
utils/currencyId
'
import
{
formatCurrencyAmount
}
from
'
utils/formatCurrencyAmount
'
import
{
formatCurrencyAmount
}
from
'
utils/formatCurrencyAmount
'
import
{
computeRealizedLPFeeAmount
,
computeRealizedPriceImpact
}
from
'
utils/prices
'
import
{
computeRealizedLPFeeAmount
,
computeRealizedPriceImpact
,
getPriceImpactWarning
}
from
'
utils/prices
'
import
Row
from
'
../../Row
'
import
Row
from
'
../../Row
'
...
@@ -52,7 +51,7 @@ export default function Details({ trade, allowedSlippage }: DetailsProps) {
...
@@ -52,7 +51,7 @@ export default function Details({ trade, allowedSlippage }: DetailsProps) {
const
{
i18n
}
=
useLingui
()
const
{
i18n
}
=
useLingui
()
const
details
=
useMemo
(()
=>
{
const
details
=
useMemo
(()
=>
{
const
rows
=
[]
const
rows
:
Array
<
[
string
,
string
]
|
[
string
,
string
,
Color
|
undefined
]
>
=
[]
// @TODO(ianlapham): Check that provider fee is even a valid list item
// @TODO(ianlapham): Check that provider fee is even a valid list item
if
(
feeOptions
)
{
if
(
feeOptions
)
{
...
@@ -63,13 +62,7 @@ export default function Details({ trade, allowedSlippage }: DetailsProps) {
...
@@ -63,13 +62,7 @@ export default function Details({ trade, allowedSlippage }: DetailsProps) {
}
}
}
}
const
priceImpactRow
=
[
t
`Price impact`
,
`
${
priceImpact
.
toFixed
(
2
)}
%`
]
rows
.
push
([
t
`Price impact`
,
`
${
priceImpact
.
toFixed
(
2
)}
%`
,
getPriceImpactWarning
(
priceImpact
)])
if
(
priceImpact
.
greaterThan
(
ALLOWED_PRICE_IMPACT_HIGH
))
{
priceImpactRow
.
push
(
'
error
'
)
}
else
if
(
priceImpact
.
greaterThan
(
ALLOWED_PRICE_IMPACT_MEDIUM
))
{
priceImpactRow
.
push
(
'
warning
'
)
}
rows
.
push
(
priceImpactRow
)
if
(
lpFeeAmount
)
{
if
(
lpFeeAmount
)
{
const
parsedLpFee
=
formatCurrencyAmount
(
lpFeeAmount
,
6
,
i18n
.
locale
)
const
parsedLpFee
=
formatCurrencyAmount
(
lpFeeAmount
,
6
,
i18n
.
locale
)
...
@@ -86,11 +79,7 @@ export default function Details({ trade, allowedSlippage }: DetailsProps) {
...
@@ -86,11 +79,7 @@ export default function Details({ trade, allowedSlippage }: DetailsProps) {
rows
.
push
([
t
`Minimum received`
,
`
${
localizedMaxSent
}
${
outputCurrency
.
symbol
}
`
])
rows
.
push
([
t
`Minimum received`
,
`
${
localizedMaxSent
}
${
outputCurrency
.
symbol
}
`
])
}
}
const
slippageToleranceRow
=
[
t
`Slippage tolerance`
,
`
${
allowedSlippage
.
toFixed
(
2
)}
%`
]
rows
.
push
([
t
`Slippage tolerance`
,
`
${
allowedSlippage
.
toFixed
(
2
)}
%`
,
getSlippageWarning
(
allowedSlippage
)])
if
(
allowedSlippage
.
greaterThan
(
MIN_HIGH_SLIPPAGE
))
{
slippageToleranceRow
.
push
(
'
warning
'
)
}
rows
.
push
(
slippageToleranceRow
)
return
rows
return
rows
},
[
},
[
...
@@ -109,7 +98,7 @@ export default function Details({ trade, allowedSlippage }: DetailsProps) {
...
@@ -109,7 +98,7 @@ export default function Details({ trade, allowedSlippage }: DetailsProps) {
return
(
return
(
<>
<>
{
details
.
map
(([
label
,
detail
,
color
])
=>
(
{
details
.
map
(([
label
,
detail
,
color
])
=>
(
<
Detail
key=
{
label
}
label=
{
label
}
value=
{
detail
}
color=
{
color
as
Color
}
/>
<
Detail
key=
{
label
}
label=
{
label
}
value=
{
detail
}
color=
{
color
}
/>
))
}
))
}
</>
</>
)
)
...
...
src/lib/components/Swap/Summary/index.tsx
View file @
0f519911
...
@@ -2,18 +2,17 @@ import { Trans } from '@lingui/macro'
...
@@ -2,18 +2,17 @@ import { Trans } from '@lingui/macro'
import
{
useLingui
}
from
'
@lingui/react
'
import
{
useLingui
}
from
'
@lingui/react
'
import
{
Trade
}
from
'
@uniswap/router-sdk
'
import
{
Trade
}
from
'
@uniswap/router-sdk
'
import
{
Currency
,
Percent
,
TradeType
}
from
'
@uniswap/sdk-core
'
import
{
Currency
,
Percent
,
TradeType
}
from
'
@uniswap/sdk-core
'
import
{
ALLOWED_PRICE_IMPACT_HIGH
,
ALLOWED_PRICE_IMPACT_MEDIUM
}
from
'
constants/misc
'
import
{
useAtomValue
}
from
'
jotai/utils
'
import
{
useAtomValue
}
from
'
jotai/utils
'
import
{
IconButton
}
from
'
lib/components/Button
'
import
{
IconButton
}
from
'
lib/components/Button
'
import
{
getSlippageWarning
}
from
'
lib/hooks/useAllowedSlippage
'
import
useScrollbar
from
'
lib/hooks/useScrollbar
'
import
useScrollbar
from
'
lib/hooks/useScrollbar
'
import
{
AlertTriangle
,
BarChart
,
Expando
,
Info
}
from
'
lib/icons
'
import
{
AlertTriangle
,
BarChart
,
Expando
,
Info
}
from
'
lib/icons
'
import
{
MIN_HIGH_SLIPPAGE
}
from
'
lib/state/settings
'
import
{
Field
,
independentFieldAtom
}
from
'
lib/state/swap
'
import
{
Field
,
independentFieldAtom
}
from
'
lib/state/swap
'
import
styled
,
{
ThemedText
}
from
'
lib/theme
'
import
styled
,
{
ThemedText
}
from
'
lib/theme
'
import
formatLocaleNumber
from
'
lib/utils/formatLocaleNumber
'
import
formatLocaleNumber
from
'
lib/utils/formatLocaleNumber
'
import
{
useMemo
,
useState
}
from
'
react
'
import
{
useMemo
,
useState
}
from
'
react
'
import
{
formatCurrencyAmount
,
formatPrice
}
from
'
utils/formatCurrencyAmount
'
import
{
formatCurrencyAmount
,
formatPrice
}
from
'
utils/formatCurrencyAmount
'
import
{
computeRealizedPriceImpact
}
from
'
utils/prices
'
import
{
computeRealizedPriceImpact
,
getPriceImpactWarning
}
from
'
utils/prices
'
import
{
tradeMeaningfullyDiffers
}
from
'
utils/tradeMeaningFullyDiffer
'
import
{
tradeMeaningfullyDiffers
}
from
'
utils/tradeMeaningFullyDiffer
'
import
ActionButton
,
{
Action
}
from
'
../../ActionButton
'
import
ActionButton
,
{
Action
}
from
'
../../ActionButton
'
...
@@ -98,10 +97,7 @@ export function SummaryDialog({ trade, allowedSlippage, onConfirm }: SummaryDial
...
@@ -98,10 +97,7 @@ export function SummaryDialog({ trade, allowedSlippage, onConfirm }: SummaryDial
const
scrollbar
=
useScrollbar
(
details
)
const
scrollbar
=
useScrollbar
(
details
)
const
warning
=
useMemo
(()
=>
{
const
warning
=
useMemo
(()
=>
{
if
(
priceImpact
.
greaterThan
(
ALLOWED_PRICE_IMPACT_HIGH
))
return
'
error
'
return
getPriceImpactWarning
(
priceImpact
)
||
getSlippageWarning
(
allowedSlippage
)
if
(
priceImpact
.
greaterThan
(
ALLOWED_PRICE_IMPACT_MEDIUM
))
return
'
warning
'
if
(
allowedSlippage
.
greaterThan
(
MIN_HIGH_SLIPPAGE
))
return
'
warning
'
return
},
[
allowedSlippage
,
priceImpact
])
},
[
allowedSlippage
,
priceImpact
])
const
[
ackPriceImpact
,
setAckPriceImpact
]
=
useState
(
false
)
const
[
ackPriceImpact
,
setAckPriceImpact
]
=
useState
(
false
)
...
@@ -120,7 +116,7 @@ export function SummaryDialog({ trade, allowedSlippage, onConfirm }: SummaryDial
...
@@ -120,7 +116,7 @@ export function SummaryDialog({ trade, allowedSlippage, onConfirm }: SummaryDial
onClick
:
()
=>
setConfirmedTrade
(
trade
),
onClick
:
()
=>
setConfirmedTrade
(
trade
),
children
:
<
Trans
>
Accept
</
Trans
>,
children
:
<
Trans
>
Accept
</
Trans
>,
}
}
}
else
if
(
priceImpact
.
greaterThan
(
ALLOWED_PRICE_IMPACT_HIGH
)
&&
!
ackPriceImpact
)
{
}
else
if
(
getPriceImpactWarning
(
priceImpact
)
===
'
error
'
&&
!
ackPriceImpact
)
{
return
{
return
{
message
:
<
Trans
>
High price impact
</
Trans
>,
message
:
<
Trans
>
High price impact
</
Trans
>,
onClick
:
()
=>
setAckPriceImpact
(
true
),
onClick
:
()
=>
setAckPriceImpact
(
true
),
...
...
src/lib/hooks/useAllowedSlippage.ts
View file @
0f519911
...
@@ -11,8 +11,17 @@ export function toPercent(maxSlippage: number | undefined): Percent | undefined
...
@@ -11,8 +11,17 @@ export function toPercent(maxSlippage: number | undefined): Percent | undefined
}
}
/** Returns the user-inputted max slippage. */
/** Returns the user-inputted max slippage. */
export
default
function
use
Max
Slippage
(
trade
:
InterfaceTrade
<
Currency
,
Currency
,
TradeType
>
|
undefined
):
Percent
{
export
default
function
use
Allowed
Slippage
(
trade
:
InterfaceTrade
<
Currency
,
Currency
,
TradeType
>
|
undefined
):
Percent
{
const
autoSlippage
=
useAutoSlippageTolerance
(
trade
)
const
autoSlippage
=
useAutoSlippageTolerance
(
trade
)
const
maxSlippage
=
toPercent
(
useAtomValue
(
maxSlippageAtom
))
const
maxSlippage
=
toPercent
(
useAtomValue
(
maxSlippageAtom
))
return
useAtomValue
(
autoSlippageAtom
)
?
autoSlippage
:
maxSlippage
??
autoSlippage
return
useAtomValue
(
autoSlippageAtom
)
?
autoSlippage
:
maxSlippage
??
autoSlippage
}
}
export
const
MAX_VALID_SLIPPAGE
=
new
Percent
(
1
,
2
)
export
const
MIN_HIGH_SLIPPAGE
=
new
Percent
(
1
,
100
)
export
function
getSlippageWarning
(
slippage
?:
Percent
):
'
warning
'
|
'
error
'
|
undefined
{
if
(
slippage
?.
greaterThan
(
MAX_VALID_SLIPPAGE
))
return
'
error
'
if
(
slippage
?.
greaterThan
(
MIN_HIGH_SLIPPAGE
))
return
'
warning
'
return
}
src/lib/state/settings.ts
View file @
0f519911
import
{
Percent
}
from
'
@uniswap/sdk-core
'
import
{
atomWithReset
}
from
'
jotai/utils
'
import
{
atomWithReset
}
from
'
jotai/utils
'
import
{
pickAtom
,
setTogglable
}
from
'
./atoms
'
import
{
pickAtom
,
setTogglable
}
from
'
./atoms
'
export
const
MAX_VALID_SLIPPAGE
=
new
Percent
(
1
,
2
)
export
const
MIN_HIGH_SLIPPAGE
=
new
Percent
(
1
,
100
)
interface
Settings
{
interface
Settings
{
autoSlippage
:
boolean
// if true, slippage will use the default calculation
autoSlippage
:
boolean
// if true, slippage will use the default calculation
maxSlippage
:
number
|
undefined
// expressed as a percent
maxSlippage
:
number
|
undefined
// expressed as a percent
...
...
src/utils/prices.ts
View file @
0f519911
...
@@ -21,6 +21,12 @@ export function computeRealizedPriceImpact(trade: Trade<Currency, Currency, Trad
...
@@ -21,6 +21,12 @@ export function computeRealizedPriceImpact(trade: Trade<Currency, Currency, Trad
return
trade
.
priceImpact
.
subtract
(
realizedLpFeePercent
)
return
trade
.
priceImpact
.
subtract
(
realizedLpFeePercent
)
}
}
export
function
getPriceImpactWarning
(
priceImpact
?:
Percent
):
'
warning
'
|
'
error
'
|
undefined
{
if
(
priceImpact
?.
greaterThan
(
ALLOWED_PRICE_IMPACT_HIGH
))
return
'
error
'
if
(
priceImpact
?.
greaterThan
(
ALLOWED_PRICE_IMPACT_MEDIUM
))
return
'
warning
'
return
}
// computes realized lp fee as a percent
// computes realized lp fee as a percent
export
function
computeRealizedLPFeePercent
(
trade
:
Trade
<
Currency
,
Currency
,
TradeType
>
):
Percent
{
export
function
computeRealizedLPFeePercent
(
trade
:
Trade
<
Currency
,
Currency
,
TradeType
>
):
Percent
{
let
percent
:
Percent
let
percent
:
Percent
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment