Commit 1f41587b authored by Moody Salem's avatar Moody Salem

fix the swap notification

parent 9b639bee
......@@ -10,8 +10,7 @@ import { Link } from 'react-router-dom'
import styled from 'styled-components'
import { MEDIA_WIDTHS } from 'theme'
import { PositionDetails } from 'types/position'
import { basisPointsToPercent } from 'utils'
import { TokenAmount, WETH9, Price, Token } from '@uniswap/sdk-core'
import { TokenAmount, WETH9, Price, Token, Percent } from '@uniswap/sdk-core'
import { formatPrice, formatTokenAmount } from 'utils/formatTokenAmount'
import Loader from 'components/Loader'
import { unwrappedToken } from 'utils/wrappedCurrency'
......@@ -238,7 +237,7 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr
</DataText>
&nbsp;
<Badge>
<BadgeText>{basisPointsToPercent(feeAmount / 100).toSignificant()}%</BadgeText>
<BadgeText>{new Percent(feeAmount, 1_000_000).toSignificant()}%</BadgeText>
</Badge>
</PrimaryPositionIdData>
<BadgeWrapper>
......
import JSBI from 'jsbi'
import React, { useContext, useRef, useState } from 'react'
import { Settings, X } from 'react-feather'
import ReactGA from 'react-ga'
......@@ -194,7 +195,7 @@ export default function SettingsTab() {
Transaction Settings
</Text>
<TransactionSettings
rawSlippage={userSlippageTolerance}
rawSlippage={JSBI.toNumber(userSlippageTolerance.numerator)}
setRawSlippage={setUserslippageTolerance}
deadline={ttl}
setDeadline={setTtl}
......
......@@ -43,7 +43,7 @@ export default function ConfirmSwapModal({
attemptingTxn: boolean
txHash: string | undefined
recipient: string | null
allowedSlippage: number
allowedSlippage: Percent
onAcceptChanges: () => void
onConfirm: () => void
swapErrorMessage: string | undefined
......@@ -86,12 +86,10 @@ export default function ConfirmSwapModal({
) : null
}, [allowedSlippage, onConfirm, showAcceptChanges, swapErrorMessage, trade])
const slippageTolerancePercent = new Percent(allowedSlippage, 10_000)
// text to show while loading
const pendingText = `Swapping ${trade?.maximumAmountIn(slippageTolerancePercent)?.toSignificant(6)} ${
const pendingText = `Swapping ${trade?.maximumAmountIn(allowedSlippage)?.toSignificant(6)} ${
trade?.inputAmount?.currency?.symbol
} for ${trade?.minimumAmountOut(slippageTolerancePercent)?.toSignificant(6)} ${trade?.outputAmount?.currency?.symbol}`
} for ${trade?.minimumAmountOut(allowedSlippage)?.toSignificant(6)} ${trade?.outputAmount?.currency?.symbol}`
const confirmationContent = useCallback(
() =>
......
......@@ -19,14 +19,13 @@ export default function SwapModalFooter({
disabledConfirm,
}: {
trade: V2Trade | V3Trade
allowedSlippage: number
allowedSlippage: Percent
onConfirm: () => void
swapErrorMessage: string | undefined
disabledConfirm: boolean
}) {
const [showInverted, setShowInverted] = useState<boolean>(false)
const theme = useContext(ThemeContext)
const slippageTolerancePercent = new Percent(allowedSlippage, 10_000)
const { priceImpactWithoutFee } = useMemo(() => computeTradePriceBreakdown(trade), [trade])
const severity = warningSeverity(priceImpactWithoutFee)
......@@ -49,7 +48,7 @@ export default function SwapModalFooter({
paddingLeft: '10px',
}}
>
{formatExecutionPrice(trade, showInverted, slippageTolerancePercent)}
{formatExecutionPrice(trade, showInverted, allowedSlippage)}
<StyledBalanceMaxMini onClick={() => setShowInverted(!showInverted)}>
<Repeat size={14} />
</StyledBalanceMaxMini>
......
......@@ -21,14 +21,13 @@ export default function SwapModalHeader({
onAcceptChanges,
}: {
trade: V2Trade | V3Trade
allowedSlippage: number
allowedSlippage: Percent
recipient: string | null
showAcceptChanges: boolean
onAcceptChanges: () => void
}) {
const slippageTolerancePercent = new Percent(allowedSlippage, 10_000)
const maximumAmountIn = trade.maximumAmountIn(slippageTolerancePercent)
const minimumAmountOut = trade.minimumAmountOut(slippageTolerancePercent)
const maximumAmountIn = trade.maximumAmountIn(allowedSlippage)
const minimumAmountOut = trade.minimumAmountOut(allowedSlippage)
const theme = useContext(ThemeContext)
......
......@@ -207,7 +207,7 @@ export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
export const NetworkContextName = 'NETWORK'
// default allowed slippage, in bips
export const INITIAL_ALLOWED_SLIPPAGE = 50
export const INITIAL_ALLOWED_SLIPPAGE = new Percent(50, 10_000)
// 20 minutes, denominated in seconds
export const DEFAULT_DEADLINE_FROM_NOW = 60 * 20
......
......@@ -99,13 +99,13 @@ export function useApproveCallback(
}
// wraps useApproveCallback in the context of a swap
export function useApproveCallbackFromTrade(trade: V2Trade | V3Trade | undefined, allowedSlippage: number) {
export function useApproveCallbackFromTrade(trade: V2Trade | V3Trade | undefined, allowedSlippage: Percent) {
const { chainId } = useActiveWeb3React()
const swapRouterAddress = SWAP_ROUTER_ADDRESSES[chainId as ChainId]
const amountToApprove = useMemo(
() => (trade ? trade.maximumAmountIn(new Percent(allowedSlippage, 10_000)) : undefined),
[trade, allowedSlippage]
)
const amountToApprove = useMemo(() => (trade ? trade.maximumAmountIn(allowedSlippage) : undefined), [
trade,
allowedSlippage,
])
return useApproveCallback(
amountToApprove,
trade instanceof V2Trade ? V2_ROUTER_ADDRESS : trade instanceof V3Trade ? swapRouterAddress : undefined
......
......@@ -269,13 +269,13 @@ export function useV2LiquidityTokenPermit(
return useERC20Permit(liquidityAmount, spender, REMOVE_V2_LIQUIDITY_PERMIT_INFO)
}
export function useERC20PermitFromTrade(trade: V2Trade | V3Trade | undefined, allowedSlippage: number) {
export function useERC20PermitFromTrade(trade: V2Trade | V3Trade | undefined, allowedSlippage: Percent) {
const { chainId } = useActiveWeb3React()
const swapRouterAddress = SWAP_ROUTER_ADDRESSES[chainId as ChainId]
const amountToApprove = useMemo(
() => (trade ? trade.maximumAmountIn(new Percent(allowedSlippage, 10_000)) : undefined),
[trade, allowedSlippage]
)
const amountToApprove = useMemo(() => (trade ? trade.maximumAmountIn(allowedSlippage) : undefined), [
trade,
allowedSlippage,
])
return useERC20Permit(
amountToApprove,
......
import JSBI from 'jsbi'
import { BigNumber } from '@ethersproject/bignumber'
import { Router, Trade as V2Trade } from '@uniswap/v2-sdk'
import { SwapRouter, Trade as V3Trade } from '@uniswap/v3-sdk'
import { ChainId, Percent, TradeType } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { BIPS_BASE, INITIAL_ALLOWED_SLIPPAGE } from '../constants'
import { INITIAL_ALLOWED_SLIPPAGE } from '../constants'
import { SWAP_ROUTER_ADDRESSES } from '../constants/v3'
import { getTradeVersion } from '../utils/getTradeVersion'
import { useTransactionAdder } from '../state/transactions/hooks'
......@@ -52,7 +51,7 @@ interface FailedCall extends SwapCallEstimate {
*/
function useSwapCallArguments(
trade: V2Trade | V3Trade | undefined, // trade to execute, required
allowedSlippage: number = INITIAL_ALLOWED_SLIPPAGE, // in bips
allowedSlippage: Percent = INITIAL_ALLOWED_SLIPPAGE, // in bips
recipientAddressOrName: string | null, // the ENS name or address of the recipient of the trade, or null if swap should be returned to sender
signatureData: SignatureData | null | undefined
): SwapCall[] {
......@@ -72,7 +71,7 @@ function useSwapCallArguments(
swapMethods.push(
Router.swapCallParameters(trade, {
feeOnTransfer: false,
allowedSlippage: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE),
allowedSlippage,
recipient,
deadline: deadline.toNumber(),
})
......@@ -82,7 +81,7 @@ function useSwapCallArguments(
swapMethods.push(
Router.swapCallParameters(trade, {
feeOnTransfer: true,
allowedSlippage: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE),
allowedSlippage,
recipient,
deadline: deadline.toNumber(),
})
......@@ -100,7 +99,7 @@ function useSwapCallArguments(
const { value, calldata } = SwapRouter.swapCallParameters(trade, {
recipient,
slippageTolerance: new Percent(JSBI.BigInt(allowedSlippage), BIPS_BASE),
slippageTolerance: allowedSlippage,
deadline: deadline.toString(),
...(signatureData
? {
......@@ -139,7 +138,7 @@ function useSwapCallArguments(
// and the user has approved the slippage adjusted input amount for the trade
export function useSwapCallback(
trade: V2Trade | V3Trade | undefined, // trade to execute, required
allowedSlippage: number = INITIAL_ALLOWED_SLIPPAGE, // in bips
allowedSlippage: Percent = INITIAL_ALLOWED_SLIPPAGE, // in bips
recipientAddressOrName: string | null, // the ENS name or address of the recipient of the trade, or null if swap should be returned to sender
signatureData: SignatureData | undefined | null
): { state: SwapCallbackState; callback: null | (() => Promise<string>); error: string | null } {
......@@ -261,9 +260,8 @@ export function useSwapCallback(
.then((response) => {
const inputSymbol = trade.inputAmount.currency.symbol
const outputSymbol = trade.outputAmount.currency.symbol
const slippageTolerancePercent = new Percent(allowedSlippage)
const inputAmount = trade.maximumAmountIn(slippageTolerancePercent).toSignificant(3)
const outputAmount = trade.minimumAmountOut(slippageTolerancePercent).toSignificant(3)
const inputAmount = trade.maximumAmountIn(allowedSlippage).toSignificant(4)
const outputAmount = trade.minimumAmountOut(allowedSlippage).toSignificant(4)
const base = `Swap ${inputAmount} ${inputSymbol} for ${outputAmount} ${outputSymbol}`
const withRecipient =
......
import { TransactionResponse } from '@ethersproject/providers'
import { Currency, TokenAmount, Percent, ETHER } from '@uniswap/sdk-core'
import { Currency, TokenAmount, ETHER } from '@uniswap/sdk-core'
import React, { useCallback, useContext, useMemo, useState } from 'react'
import { WETH9 } from '@uniswap/sdk-core'
import { Link2, AlertTriangle, ChevronRight } from 'react-feather'
......@@ -45,7 +45,6 @@ import { useTranslation } from 'react-i18next'
import { useMintState, useMintActionHandlers, useDerivedMintInfo, useRangeHopCallbacks } from 'state/mint/hooks'
import { FeeAmount, NonfungiblePositionManager } from '@uniswap/v3-sdk'
import { NONFUNGIBLE_POSITION_MANAGER_ADDRESSES } from 'constants/v3'
import JSBI from 'jsbi'
import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import { useDerivedPositionInfo } from 'hooks/useDerivedPositionInfo'
import { PositionPreview } from 'components/PositionPreview'
......@@ -140,7 +139,6 @@ export default function AddLiquidity({
// txn values
const deadline = useTransactionDeadline() // custom from users settings
const [allowedSlippage] = useUserSlippageTolerance() // custom from users
const fractionalizedTolerance = new Percent(JSBI.BigInt(allowedSlippage), JSBI.BigInt(10000))
const [txHash, setTxHash] = useState<string>('')
// get formatted amounts
......@@ -187,17 +185,17 @@ export default function AddLiquidity({
return
}
if (position && account && deadline && fractionalizedTolerance) {
if (position && account && deadline) {
const { calldata, value } =
hasExistingPosition && tokenId
? NonfungiblePositionManager.addCallParameters(position, {
tokenId,
slippageTolerance: fractionalizedTolerance,
slippageTolerance: allowedSlippage,
deadline: deadline.toString(),
useEther: currencyA === ETHER || currencyB === ETHER,
})
: NonfungiblePositionManager.addCallParameters(position, {
slippageTolerance: fractionalizedTolerance,
slippageTolerance: allowedSlippage,
recipient: account,
deadline: deadline.toString(),
useEther: currencyA === ETHER || currencyB === ETHER,
......
......@@ -17,7 +17,7 @@ import { AddRemoveTabs } from '../../components/NavigationTabs'
import { MinimalPositionCard } from '../../components/PositionCard'
import Row, { RowBetween, RowFlat } from '../../components/Row'
import { V2_ROUTER_ADDRESS } from '../../constants'
import { V2_ROUTER_ADDRESS, ZERO_PERCENT } from '../../constants'
import { useV2RouterContract } from '../../hooks/useContract'
import { PairState } from '../../hooks/useV2Pairs'
import { useActiveWeb3React } from '../../hooks'
......@@ -138,8 +138,8 @@ export default function AddLiquidity({
}
const amountsMin = {
[Field.CURRENCY_A]: calculateSlippageAmount(parsedAmountA, noLiquidity ? 0 : allowedSlippage)[0],
[Field.CURRENCY_B]: calculateSlippageAmount(parsedAmountB, noLiquidity ? 0 : allowedSlippage)[0],
[Field.CURRENCY_A]: calculateSlippageAmount(parsedAmountA, noLiquidity ? ZERO_PERCENT : allowedSlippage)[0],
[Field.CURRENCY_B]: calculateSlippageAmount(parsedAmountB, noLiquidity ? ZERO_PERCENT : allowedSlippage)[0],
}
let estimate,
......@@ -248,9 +248,9 @@ export default function AddLiquidity({
</Text>
</Row>
<TYPE.italic fontSize={12} textAlign="left" padding={'8px 0 0 0 '}>
{`Output is estimated. If the price changes by more than ${
allowedSlippage / 100
}% your transaction will revert.`}
{`Output is estimated. If the price changes by more than ${allowedSlippage.toSignificant(
4
)}% your transaction will revert.`}
</TYPE.italic>
</AutoColumn>
)
......
......@@ -191,7 +191,10 @@ function V2PairMigration({
position &&
new TokenAmount(
token0,
JSBI.divide(JSBI.multiply(position.amount0.raw, JSBI.BigInt(10000 - allowedSlippage)), JSBI.BigInt(10000))
JSBI.divide(
JSBI.multiply(position.amount0.raw, JSBI.BigInt(10000 - JSBI.toNumber(allowedSlippage.numerator))),
JSBI.BigInt(10000)
)
),
[token0, position, allowedSlippage]
)
......@@ -200,7 +203,10 @@ function V2PairMigration({
position &&
new TokenAmount(
token1,
JSBI.divide(JSBI.multiply(position.amount1.raw, JSBI.BigInt(10000 - allowedSlippage)), JSBI.BigInt(10000))
JSBI.divide(
JSBI.multiply(position.amount1.raw, JSBI.BigInt(10000 - JSBI.toNumber(allowedSlippage.numerator))),
JSBI.BigInt(10000)
)
),
[token1, position, allowedSlippage]
)
......
......@@ -13,7 +13,7 @@ import Row, { RowBetween, RowFixed } from 'components/Row'
import DoubleCurrencyLogo from 'components/DoubleLogo'
import { ButtonText, TYPE } from 'theme'
import Badge, { BadgeVariant } from 'components/Badge'
import { basisPointsToPercent, calculateGasMargin } from 'utils'
import { calculateGasMargin } from 'utils'
import { ButtonConfirmed, ButtonPrimary } from 'components/Button'
import { DarkCard, DarkGreyCard } from 'components/Card'
import CurrencyLogo from 'components/CurrencyLogo'
......@@ -23,7 +23,7 @@ import { currencyId } from 'utils/currencyId'
import { formatTokenAmount } from 'utils/formatTokenAmount'
import { useV3PositionFees } from 'hooks/useV3PositionFees'
import { BigNumber } from '@ethersproject/bignumber'
import { WETH9, Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { WETH9, Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import { useActiveWeb3React } from 'hooks'
import { useV3NFTPositionManagerContract } from 'hooks/useContract'
import { useIsTransactionPending, useTransactionAdder } from 'state/transactions/hooks'
......@@ -263,7 +263,7 @@ export function PositionPage({
&nbsp;{currencyQuote?.symbol}&nbsp;/&nbsp;{currencyBase?.symbol}
</TYPE.label>
<Badge>
<BadgeText>{basisPointsToPercent(feeAmount / 100).toSignificant()}%</BadgeText>
<BadgeText>{new Percent(feeAmount, 1_000_000).toSignificant()}%</BadgeText>
</Badge>
</RowFixed>
......
......@@ -310,9 +310,9 @@ export default function RemoveLiquidity({
</RowBetween>
<TYPE.italic fontSize={12} color={theme.text2} textAlign="left" padding={'12px 0 0 0'}>
{`Output is estimated. If the price changes by more than ${
allowedSlippage / 100
}% your transaction will revert.`}
{`Output is estimated. If the price changes by more than ${allowedSlippage.toSignificant(
4
)}% your transaction will revert.`}
</TYPE.italic>
</AutoColumn>
)
......
import { CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk'
import UnsupportedCurrencyFooter from 'components/swap/UnsupportedCurrencyFooter'
......@@ -122,14 +122,8 @@ export default function Swap({ history }: RouteComponentProps) {
[Field.OUTPUT]: parsedAmount,
}
: {
[Field.INPUT]:
independentField === Field.INPUT
? parsedAmount
: trade?.maximumAmountIn(new Percent(allowedSlippage, 10_000)),
[Field.OUTPUT]:
independentField === Field.OUTPUT
? parsedAmount
: trade?.minimumAmountOut(new Percent(allowedSlippage, 10_000)),
[Field.INPUT]: independentField === Field.INPUT ? parsedAmount : trade?.maximumAmountIn(allowedSlippage),
[Field.OUTPUT]: independentField === Field.OUTPUT ? parsedAmount : trade?.minimumAmountOut(allowedSlippage),
},
[allowedSlippage, independentField, parsedAmount, showWrap, trade]
)
......@@ -246,13 +240,9 @@ export default function Swap({ history }: RouteComponentProps) {
trade?.inputAmount?.currency?.symbol,
trade?.outputAmount?.currency?.symbol,
getTradeVersion(trade),
singleHopOnly ? 'SH' : 'MH',
].join('/'),
})
ReactGA.event({
category: 'Routing',
action: singleHopOnly ? 'Swap with multihop disabled' : 'Swap with multihop enabled',
})
})
.catch((error) => {
setSwapState({
......@@ -403,7 +393,7 @@ export default function Swap({ history }: RouteComponentProps) {
) : null}
{trade ? (
<TradePrice
price={trade.worstExecutionPrice(new Percent(allowedSlippage, 10_000))}
price={trade.worstExecutionPrice(allowedSlippage)}
showInverted={showInverted}
setShowInverted={setShowInverted}
/>
......
import { ChainId, Token } from '@uniswap/sdk-core'
import { ChainId, Percent, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import flatMap from 'lodash.flatmap'
import { useCallback, useMemo } from 'react'
......@@ -100,12 +100,14 @@ export function useUserSingleHopOnly(): [boolean, (newSingleHopOnly: boolean) =>
return [singleHopOnly, setSingleHopOnly]
}
export function useUserSlippageTolerance(): [number, (slippage: number) => void] {
export function useUserSlippageTolerance(): [Percent, (slippageBips: number) => void] {
const dispatch = useDispatch<AppDispatch>()
const userSlippageTolerance = useSelector<AppState, AppState['user']['userSlippageTolerance']>((state) => {
return state.user.userSlippageTolerance
})
const percentage = useMemo(() => new Percent(userSlippageTolerance, 10_000), [userSlippageTolerance])
const setUserSlippageTolerance = useCallback(
(userSlippageTolerance: number) => {
dispatch(updateUserSlippageTolerance({ userSlippageTolerance }))
......@@ -113,7 +115,7 @@ export function useUserSlippageTolerance(): [number, (slippage: number) => void]
[dispatch]
)
return [userSlippageTolerance, setUserSlippageTolerance]
return [percentage, setUserSlippageTolerance]
}
export function useUserTransactionTTL(): [number, (slippage: number) => void] {
......
......@@ -27,7 +27,7 @@ describe('swap reducer', () => {
} as any)
store.dispatch(updateVersion())
expect(store.getState().userDeadline).toEqual(DEFAULT_DEADLINE_FROM_NOW)
expect(store.getState().userSlippageTolerance).toEqual(INITIAL_ALLOWED_SLIPPAGE)
expect(store.getState().userSlippageTolerance).toEqual(50)
})
})
})
import { INITIAL_ALLOWED_SLIPPAGE, DEFAULT_DEADLINE_FROM_NOW } from '../../constants'
import { DEFAULT_DEADLINE_FROM_NOW } from '../../constants'
import { createReducer } from '@reduxjs/toolkit'
import { updateVersion } from '../global/actions'
import {
......@@ -62,7 +62,7 @@ export const initialState: UserState = {
matchesDarkMode: false,
userExpertMode: false,
userSingleHopOnly: false,
userSlippageTolerance: INITIAL_ALLOWED_SLIPPAGE,
userSlippageTolerance: 50,
userDeadline: DEFAULT_DEADLINE_FROM_NOW,
tokens: {},
pairs: {},
......@@ -76,7 +76,7 @@ export default createReducer(initialState, (builder) =>
// slippage isnt being tracked in local storage, reset to default
// noinspection SuspiciousTypeOfGuard
if (typeof state.userSlippageTolerance !== 'number') {
state.userSlippageTolerance = INITIAL_ALLOWED_SLIPPAGE
state.userSlippageTolerance = 50
}
// deadline isnt being tracked in local storage, reset to default
......
import { BigNumber } from '@ethersproject/bignumber'
import { AddressZero } from '@ethersproject/constants'
import { TokenAmount, Token, ChainId, Percent } from '@uniswap/sdk-core'
import { JSBI } from '@uniswap/v2-sdk'
import {
getEtherscanLink,
calculateSlippageAmount,
isAddress,
shortenAddress,
calculateGasMargin,
basisPointsToPercent,
} from '.'
import { getEtherscanLink, calculateSlippageAmount, isAddress, shortenAddress, calculateGasMargin } from '.'
describe('utils', () => {
describe('#getEtherscanLink', () => {
......@@ -37,12 +28,23 @@ describe('utils', () => {
describe('#calculateSlippageAmount', () => {
it('bounds are correct', () => {
const tokenAmount = new TokenAmount(new Token(ChainId.MAINNET, AddressZero, 0), '100')
expect(() => calculateSlippageAmount(tokenAmount, -1)).toThrow()
expect(calculateSlippageAmount(tokenAmount, 0).map((bound) => bound.toString())).toEqual(['100', '100'])
expect(calculateSlippageAmount(tokenAmount, 100).map((bound) => bound.toString())).toEqual(['99', '101'])
expect(calculateSlippageAmount(tokenAmount, 200).map((bound) => bound.toString())).toEqual(['98', '102'])
expect(calculateSlippageAmount(tokenAmount, 10000).map((bound) => bound.toString())).toEqual(['0', '200'])
expect(() => calculateSlippageAmount(tokenAmount, 10001)).toThrow()
expect(() => calculateSlippageAmount(tokenAmount, new Percent(-1, 10_000))).toThrow()
expect(calculateSlippageAmount(tokenAmount, new Percent(0, 10_000)).map((bound) => bound.toString())).toEqual([
'100',
'100',
])
expect(calculateSlippageAmount(tokenAmount, new Percent(100, 10_000)).map((bound) => bound.toString())).toEqual([
'99',
'101',
])
expect(calculateSlippageAmount(tokenAmount, new Percent(200, 10_000)).map((bound) => bound.toString())).toEqual([
'98',
'102',
])
expect(
calculateSlippageAmount(tokenAmount, new Percent(10000, 10_000)).map((bound) => bound.toString())
).toEqual(['0', '200'])
expect(() => calculateSlippageAmount(tokenAmount, new Percent(10001, 10_000))).toThrow()
})
})
......@@ -92,12 +94,4 @@ describe('utils', () => {
expect(calculateGasMargin(BigNumber.from(50)).toString()).toEqual('55')
})
})
describe('#basisPointsToPercent', () => {
it('converts basis points numbers to percents', () => {
expect(basisPointsToPercent(100).equalTo(new Percent(JSBI.BigInt(1), JSBI.BigInt(100)))).toBeTruthy()
expect(basisPointsToPercent(500).equalTo(new Percent(JSBI.BigInt(5), JSBI.BigInt(100)))).toBeTruthy()
expect(basisPointsToPercent(50).equalTo(new Percent(JSBI.BigInt(5), JSBI.BigInt(1000)))).toBeTruthy()
})
})
})
......@@ -63,18 +63,16 @@ export function calculateGasMargin(value: BigNumber): BigNumber {
return value.mul(BigNumber.from(10000).add(BigNumber.from(1000))).div(BigNumber.from(10000))
}
// converts a basis points value to a sdk percent
export function basisPointsToPercent(num: number): Percent {
return new Percent(JSBI.BigInt(num), JSBI.BigInt(10000))
}
export function calculateSlippageAmount(value: CurrencyAmount, slippage: number): [JSBI, JSBI] {
if (slippage < 0 || slippage > 10000) {
throw Error(`Unexpected slippage value: ${slippage}`)
}
export function calculateSlippageAmount(value: CurrencyAmount, slippage: Percent): [JSBI, JSBI] {
if (
JSBI.lessThan(slippage.numerator, JSBI.BigInt(0)) ||
JSBI.greaterThan(slippage.numerator, JSBI.BigInt(10_000)) ||
!JSBI.equal(slippage.denominator, JSBI.BigInt(10_000))
)
throw new Error('Unexpected slippage')
return [
JSBI.divide(JSBI.multiply(value.raw, JSBI.BigInt(10000 - slippage)), JSBI.BigInt(10000)),
JSBI.divide(JSBI.multiply(value.raw, JSBI.BigInt(10000 + slippage)), JSBI.BigInt(10000)),
JSBI.divide(JSBI.multiply(value.raw, JSBI.subtract(JSBI.BigInt(10000), slippage.numerator)), JSBI.BigInt(10000)),
JSBI.divide(JSBI.multiply(value.raw, JSBI.add(JSBI.BigInt(10000), slippage.numerator)), JSBI.BigInt(10000)),
]
}
......
......@@ -6,7 +6,6 @@ import { Trade as V3Trade } from '@uniswap/v3-sdk'
import { ALLOWED_PRICE_IMPACT_HIGH, ALLOWED_PRICE_IMPACT_LOW, ALLOWED_PRICE_IMPACT_MEDIUM } from '../constants'
import { Field } from '../state/swap/actions'
import { basisPointsToPercent } from './index'
const THIRTY_BIPS_FEE = new Percent(JSBI.BigInt(30), JSBI.BigInt(10000))
const ONE_HUNDRED_PERCENT = new Percent(JSBI.BigInt(10000), JSBI.BigInt(10000))
......@@ -78,12 +77,11 @@ export function computeTradePriceBreakdown(
// computes the minimum amount out and maximum amount in for a trade given a user specified allowed slippage in bips
export function computeSlippageAdjustedAmounts(
trade: V2Trade | V3Trade | undefined,
allowedSlippage: number
allowedSlippage: Percent
): { [field in Field]?: CurrencyAmount } {
const pct = basisPointsToPercent(allowedSlippage)
return {
[Field.INPUT]: trade?.maximumAmountIn(pct),
[Field.OUTPUT]: trade?.minimumAmountOut(pct),
[Field.INPUT]: trade?.maximumAmountIn(allowedSlippage),
[Field.OUTPUT]: trade?.minimumAmountOut(allowedSlippage),
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment