improvement: estimated amounts instead of minimum/maximums (#1570)
* estimated amounts instead of minimum/maximums * missed a spot * fix linting error
This commit is contained in:
parent
534afb3278
commit
7a0b85bf41
@ -51,7 +51,7 @@
|
||||
"@uniswap/v2-sdk": "^3.0.0-alpha.0",
|
||||
"@uniswap/v3-core": "1.0.0",
|
||||
"@uniswap/v3-periphery": "1.0.0",
|
||||
"@uniswap/v3-sdk": "^3.0.0-alpha.2",
|
||||
"@uniswap/v3-sdk": "^3.0.0-alpha.4",
|
||||
"@web3-react/core": "^6.0.9",
|
||||
"@web3-react/fortmatic-connector": "^6.0.9",
|
||||
"@web3-react/injected-connector": "^6.0.7",
|
||||
|
@ -1,11 +1,10 @@
|
||||
import { Percent, Currency, TradeType } from '@uniswap/sdk-core'
|
||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
||||
import React, { useContext } from 'react'
|
||||
import React, { useContext, useMemo } from 'react'
|
||||
import { ThemeContext } from 'styled-components'
|
||||
import { TYPE } from '../../theme'
|
||||
import { computePriceImpactWithMaximumSlippage } from '../../utils/computePriceImpactWithMaximumSlippage'
|
||||
import { computeRealizedLPFeeAmount } from '../../utils/prices'
|
||||
import { computeRealizedLPFeePercent } from '../../utils/prices'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { RowBetween, RowFixed } from '../Row'
|
||||
import FormattedPriceImpact from './FormattedPriceImpact'
|
||||
@ -19,7 +18,14 @@ export interface AdvancedSwapDetailsProps {
|
||||
export function AdvancedSwapDetails({ trade, allowedSlippage }: AdvancedSwapDetailsProps) {
|
||||
const theme = useContext(ThemeContext)
|
||||
|
||||
const realizedLPFee = computeRealizedLPFeeAmount(trade)
|
||||
const { realizedLPFee, priceImpact } = useMemo(() => {
|
||||
if (!trade) return { realizedLPFee: undefined, priceImpact: undefined }
|
||||
|
||||
const realizedLpFeePercent = computeRealizedLPFeePercent(trade)
|
||||
const realizedLPFee = trade.inputAmount.multiply(realizedLpFeePercent)
|
||||
const priceImpact = trade.priceImpact.subtract(realizedLpFeePercent)
|
||||
return { priceImpact, realizedLPFee }
|
||||
}, [trade])
|
||||
|
||||
return !trade ? null : (
|
||||
<AutoColumn gap="8px">
|
||||
@ -30,7 +36,7 @@ export function AdvancedSwapDetails({ trade, allowedSlippage }: AdvancedSwapDeta
|
||||
</TYPE.black>
|
||||
</RowFixed>
|
||||
<TYPE.black textAlign="right" fontSize={12} color={theme.text1}>
|
||||
{realizedLPFee ? `${realizedLPFee.toSignificant(4)} ${trade.inputAmount.currency.symbol}` : '-'}
|
||||
{realizedLPFee ? `${realizedLPFee.toSignificant(4)} ${realizedLPFee.currency.symbol}` : '-'}
|
||||
</TYPE.black>
|
||||
</RowBetween>
|
||||
|
||||
@ -48,11 +54,24 @@ export function AdvancedSwapDetails({ trade, allowedSlippage }: AdvancedSwapDeta
|
||||
<RowBetween>
|
||||
<RowFixed>
|
||||
<TYPE.black fontSize={12} fontWeight={400} color={theme.text2}>
|
||||
Execution price vs. spot price
|
||||
Price Impact
|
||||
</TYPE.black>
|
||||
</RowFixed>
|
||||
<TYPE.black textAlign="right" fontSize={12} color={theme.text1}>
|
||||
<FormattedPriceImpact priceImpact={computePriceImpactWithMaximumSlippage(trade, allowedSlippage)} />
|
||||
<FormattedPriceImpact priceImpact={priceImpact} />
|
||||
</TYPE.black>
|
||||
</RowBetween>
|
||||
|
||||
<RowBetween>
|
||||
<RowFixed>
|
||||
<TYPE.black fontSize={12} fontWeight={400} color={theme.text2}>
|
||||
{trade.tradeType === TradeType.EXACT_INPUT ? 'Minimum Amount Out' : 'Maximum Amount In'}
|
||||
</TYPE.black>
|
||||
</RowFixed>
|
||||
<TYPE.black textAlign="right" fontSize={12} color={theme.text1}>
|
||||
{trade.tradeType === TradeType.EXACT_INPUT
|
||||
? `${trade.minimumAmountOut(allowedSlippage).toSignificant(6)} ${trade.outputAmount.currency.symbol}`
|
||||
: `${trade.maximumAmountIn(allowedSlippage).toSignificant(6)} ${trade.inputAmount.currency.symbol}`}
|
||||
</TYPE.black>
|
||||
</RowBetween>
|
||||
|
||||
|
@ -90,9 +90,9 @@ export default function ConfirmSwapModal({
|
||||
}, [onConfirm, showAcceptChanges, swapErrorMessage, trade])
|
||||
|
||||
// text to show while loading
|
||||
const pendingText = `Swapping ${trade?.maximumAmountIn(allowedSlippage)?.toSignificant(6)} ${
|
||||
const pendingText = `Swapping ${trade?.inputAmount?.toSignificant(6)} ${
|
||||
trade?.inputAmount?.currency?.symbol
|
||||
} for ${trade?.minimumAmountOut(allowedSlippage)?.toSignificant(6)} ${trade?.outputAmount?.currency?.symbol}`
|
||||
} for ${trade?.outputAmount?.toSignificant(6)} ${trade?.outputAmount?.currency?.symbol}`
|
||||
|
||||
const confirmationContent = useCallback(
|
||||
() =>
|
||||
|
@ -31,12 +31,10 @@ export const ArrowWrapper = styled.div`
|
||||
margin-top: -18px;
|
||||
margin-bottom: -18px;
|
||||
left: calc(50% - 16px);
|
||||
/* transform: rotate(90deg); */
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-color: ${({ theme }) => theme.bg1};
|
||||
/* border: 4px solid ${({ theme }) => theme.bg0}; */
|
||||
z-index: 2;
|
||||
`
|
||||
|
||||
@ -53,15 +51,12 @@ export default function SwapModalHeader({
|
||||
showAcceptChanges: boolean
|
||||
onAcceptChanges: () => void
|
||||
}) {
|
||||
const maximumAmountIn = trade.maximumAmountIn(allowedSlippage)
|
||||
const minimumAmountOut = trade.minimumAmountOut(allowedSlippage)
|
||||
|
||||
const theme = useContext(ThemeContext)
|
||||
|
||||
const [showInverted, setShowInverted] = useState<boolean>(false)
|
||||
|
||||
const fiatValueInput = useUSDCValue(maximumAmountIn)
|
||||
const fiatValueOutput = useUSDCValue(minimumAmountOut)
|
||||
const fiatValueInput = useUSDCValue(trade.inputAmount)
|
||||
const fiatValueOutput = useUSDCValue(trade.outputAmount)
|
||||
|
||||
return (
|
||||
<AutoColumn gap={'4px'} style={{ marginTop: '1rem' }}>
|
||||
@ -86,7 +81,7 @@ export default function SwapModalHeader({
|
||||
fontWeight={500}
|
||||
color={showAcceptChanges && trade.tradeType === TradeType.EXACT_OUTPUT ? theme.primary1 : ''}
|
||||
>
|
||||
{maximumAmountIn.toSignificant(6)}
|
||||
{trade.inputAmount.toSignificant(6)}
|
||||
</TruncatedText>
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
@ -117,7 +112,7 @@ export default function SwapModalHeader({
|
||||
</RowFixed>
|
||||
<RowFixed gap={'0px'}>
|
||||
<TruncatedText fontSize={24} fontWeight={500}>
|
||||
{minimumAmountOut.toSignificant(6)}
|
||||
{trade.outputAmount.toSignificant(6)}
|
||||
</TruncatedText>
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
@ -127,11 +122,7 @@ export default function SwapModalHeader({
|
||||
<TYPE.body color={theme.text2} fontWeight={500} fontSize={14}>
|
||||
{'Price:'}
|
||||
</TYPE.body>
|
||||
<TradePrice
|
||||
price={trade.worstExecutionPrice(allowedSlippage)}
|
||||
showInverted={showInverted}
|
||||
setShowInverted={setShowInverted}
|
||||
/>
|
||||
<TradePrice price={trade.executionPrice} showInverted={showInverted} setShowInverted={setShowInverted} />
|
||||
</RowBetween>
|
||||
|
||||
<LightCard style={{ padding: '.75rem', marginTop: '0.5rem' }}>
|
||||
@ -155,12 +146,12 @@ export default function SwapModalHeader({
|
||||
</SwapShowAcceptChanges>
|
||||
) : null}
|
||||
|
||||
{/* <AutoColumn justify="flex-start" gap="sm" style={{ padding: '.75rem 1rem' }}>
|
||||
<AutoColumn justify="flex-start" gap="sm" style={{ padding: '.75rem 1rem' }}>
|
||||
{trade.tradeType === TradeType.EXACT_INPUT ? (
|
||||
<TYPE.italic fontWeight={400} textAlign="left" style={{ width: '100%' }}>
|
||||
{`Output is estimated. You will receive at least `}
|
||||
<b>
|
||||
{minimumAmountOut.toSignificant(6)} {trade.outputAmount.currency.symbol}
|
||||
{trade.minimumAmountOut(allowedSlippage).toSignificant(6)} {trade.outputAmount.currency.symbol}
|
||||
</b>
|
||||
{' or the transaction will revert.'}
|
||||
</TYPE.italic>
|
||||
@ -168,12 +159,12 @@ export default function SwapModalHeader({
|
||||
<TYPE.italic fontWeight={400} textAlign="left" style={{ width: '100%' }}>
|
||||
{`Input is estimated. You will sell at most `}
|
||||
<b>
|
||||
{maximumAmountIn.toSignificant(6)} {trade.inputAmount.currency.symbol}
|
||||
{trade.maximumAmountIn(allowedSlippage).toSignificant(6)} {trade.inputAmount.currency.symbol}
|
||||
</b>
|
||||
{' or the transaction will revert.'}
|
||||
</TYPE.italic>
|
||||
)}
|
||||
</AutoColumn> */}
|
||||
</AutoColumn>
|
||||
{recipient !== null ? (
|
||||
<AutoColumn justify="flex-start" gap="sm" style={{ padding: '12px 0 0 0px' }}>
|
||||
<TYPE.main>
|
||||
|
@ -275,8 +275,8 @@ export function useSwapCallback(
|
||||
.then((response) => {
|
||||
const inputSymbol = trade.inputAmount.currency.symbol
|
||||
const outputSymbol = trade.outputAmount.currency.symbol
|
||||
const inputAmount = trade.maximumAmountIn(allowedSlippage).toSignificant(4)
|
||||
const outputAmount = trade.minimumAmountOut(allowedSlippage).toSignificant(4)
|
||||
const inputAmount = trade.inputAmount.toSignificant(4)
|
||||
const outputAmount = trade.outputAmount.toSignificant(4)
|
||||
|
||||
const base = `Swap ${inputAmount} ${inputSymbol} for ${outputAmount} ${outputSymbol}`
|
||||
const withRecipient =
|
||||
@ -312,5 +312,5 @@ export function useSwapCallback(
|
||||
},
|
||||
error: null,
|
||||
}
|
||||
}, [trade, library, account, chainId, recipient, recipientAddressOrName, swapCalls, allowedSlippage, addTransaction])
|
||||
}, [trade, library, account, chainId, recipient, recipientAddressOrName, swapCalls, addTransaction])
|
||||
}
|
||||
|
@ -49,7 +49,6 @@ import {
|
||||
import { useExpertModeManager, useUserSingleHopOnly } from '../../state/user/hooks'
|
||||
import { HideSmall, LinkStyledButton, TYPE } from '../../theme'
|
||||
import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact'
|
||||
import { computePriceImpactWithMaximumSlippage } from '../../utils/computePriceImpactWithMaximumSlippage'
|
||||
import { getTradeVersion } from '../../utils/getTradeVersion'
|
||||
import { isTradeBetter } from '../../utils/isTradeBetter'
|
||||
import { maxAmountSpend } from '../../utils/maxAmountSpend'
|
||||
@ -132,10 +131,10 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
[Field.OUTPUT]: parsedAmount,
|
||||
}
|
||||
: {
|
||||
[Field.INPUT]: independentField === Field.INPUT ? parsedAmount : trade?.maximumAmountIn(allowedSlippage),
|
||||
[Field.OUTPUT]: independentField === Field.OUTPUT ? parsedAmount : trade?.minimumAmountOut(allowedSlippage),
|
||||
[Field.INPUT]: independentField === Field.INPUT ? parsedAmount : trade?.inputAmount,
|
||||
[Field.OUTPUT]: independentField === Field.OUTPUT ? parsedAmount : trade?.outputAmount,
|
||||
},
|
||||
[allowedSlippage, independentField, parsedAmount, showWrap, trade]
|
||||
[independentField, parsedAmount, showWrap, trade]
|
||||
)
|
||||
|
||||
const fiatValueInput = useUSDCValue(parsedAmounts[Field.INPUT])
|
||||
@ -292,7 +291,7 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
|
||||
// warnings on the greater of fiat value price impact and execution price impact
|
||||
const priceImpactSeverity = useMemo(() => {
|
||||
const executionPriceImpact = trade ? computePriceImpactWithMaximumSlippage(trade, allowedSlippage) : undefined
|
||||
const executionPriceImpact = trade?.priceImpact
|
||||
return warningSeverity(
|
||||
executionPriceImpact && priceImpact
|
||||
? executionPriceImpact.greaterThan(priceImpact)
|
||||
@ -300,7 +299,7 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
: priceImpact
|
||||
: executionPriceImpact ?? priceImpact
|
||||
)
|
||||
}, [allowedSlippage, priceImpact, trade])
|
||||
}, [priceImpact, trade])
|
||||
|
||||
// show approve flow when: no error on inputs, not approved or pending, or approved in current session
|
||||
// never show if price impact is above threshold in non expert mode
|
||||
@ -475,7 +474,7 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
{trade ? (
|
||||
<RowFixed>
|
||||
<TradePrice
|
||||
price={trade.worstExecutionPrice(allowedSlippage)}
|
||||
price={trade.executionPrice}
|
||||
showInverted={showInverted}
|
||||
setShowInverted={setShowInverted}
|
||||
/>
|
||||
|
@ -1,14 +0,0 @@
|
||||
import { computePriceImpact, Currency, Percent, TradeType } from '@uniswap/sdk-core'
|
||||
import { Trade as V2Trade } from '@uniswap/v2-sdk'
|
||||
import { Trade as V3Trade } from '@uniswap/v3-sdk'
|
||||
|
||||
export function computePriceImpactWithMaximumSlippage(
|
||||
trade: V2Trade<Currency, Currency, TradeType> | V3Trade<Currency, Currency, TradeType>,
|
||||
allowedSlippage: Percent
|
||||
): Percent {
|
||||
return computePriceImpact(
|
||||
trade.route.midPrice,
|
||||
trade.maximumAmountIn(allowedSlippage),
|
||||
trade.minimumAmountOut(allowedSlippage)
|
||||
)
|
||||
}
|
@ -22,15 +22,15 @@ export function computeRealizedLPFeePercent(
|
||||
// for each hop in our trade, take away the x*y=k price impact from 0.3% fees
|
||||
// e.g. for 3 tokens/2 hops: 1 - ((1 - .03) * (1-.03))
|
||||
percent = ONE_HUNDRED_PERCENT.subtract(
|
||||
trade.route.pairs.reduce<Fraction>(
|
||||
(currentFee: Fraction): Fraction => currentFee.multiply(INPUT_FRACTION_AFTER_FEE),
|
||||
trade.route.pairs.reduce<Percent>(
|
||||
(currentFee: Percent): Percent => currentFee.multiply(INPUT_FRACTION_AFTER_FEE),
|
||||
ONE_HUNDRED_PERCENT
|
||||
)
|
||||
)
|
||||
} else {
|
||||
percent = ONE_HUNDRED_PERCENT.subtract(
|
||||
trade.route.pools.reduce<Fraction>(
|
||||
(currentFee: Fraction, pool): Fraction =>
|
||||
trade.route.pools.reduce<Percent>(
|
||||
(currentFee: Percent, pool): Percent =>
|
||||
currentFee.multiply(ONE_HUNDRED_PERCENT.subtract(new Fraction(pool.fee, 1_000_000))),
|
||||
ONE_HUNDRED_PERCENT
|
||||
)
|
||||
@ -44,14 +44,11 @@ export function computeRealizedLPFeePercent(
|
||||
export function computeRealizedLPFeeAmount(
|
||||
trade?: V2Trade<Currency, Currency, TradeType> | V3Trade<Currency, Currency, TradeType> | null
|
||||
): CurrencyAmount<Currency> | undefined {
|
||||
if (trade instanceof V2Trade || trade instanceof V3Trade) {
|
||||
if (trade) {
|
||||
const realizedLPFee = computeRealizedLPFeePercent(trade)
|
||||
|
||||
// the amount of the input that accrues to LPs
|
||||
return CurrencyAmount.fromRawAmount(
|
||||
trade.inputAmount.currency,
|
||||
trade.inputAmount.asFraction.multiply(realizedLPFee).quotient
|
||||
)
|
||||
return CurrencyAmount.fromRawAmount(trade.inputAmount.currency, trade.inputAmount.multiply(realizedLPFee).quotient)
|
||||
}
|
||||
|
||||
return undefined
|
||||
|
@ -4478,10 +4478,10 @@
|
||||
"@uniswap/v3-core" "1.0.0"
|
||||
base64-sol "1.0.1"
|
||||
|
||||
"@uniswap/v3-sdk@^3.0.0-alpha.2":
|
||||
version "3.0.0-alpha.2"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.0.0-alpha.2.tgz#c72c2a81da515839f48e8aba6dff2a7163c94da1"
|
||||
integrity sha512-L5coA6F2/Xq25wLjEddXzj3uXCV0v5TOm7Fsw+Z8PubWmi2sXaJFqUfsoOXSfICD5NjJUb3u3bpe4+ZHRaUrnw==
|
||||
"@uniswap/v3-sdk@^3.0.0-alpha.4":
|
||||
version "3.0.0-alpha.4"
|
||||
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.0.0-alpha.4.tgz#e8bf26291fd74e36a5a3d9b88f1809a7aceb7d3a"
|
||||
integrity sha512-BcEH8eHt+b6eaaiLDlzbFox2NquP1H7KgrgmNjAlU/et+vC4azdfNN6SsRlTFzhioPOwHlAKAAZJLq+yzboDOQ==
|
||||
dependencies:
|
||||
"@ethersproject/abi" "^5.0.12"
|
||||
"@ethersproject/solidity" "^5.0.9"
|
||||
|
Loading…
Reference in New Issue
Block a user