Commit f73a166d authored by Callil Capuozzo's avatar Callil Capuozzo

Merge branch 'main' of https://github.com/Uniswap/v3-interface into main

parents e1e52c06 ca4d9159
...@@ -33,14 +33,28 @@ export const DarkBadge = styled.div` ...@@ -33,14 +33,28 @@ export const DarkBadge = styled.div`
padding: 4px 6px; padding: 4px 6px;
` `
export default function RangeBadge({ inRange }: { inRange?: boolean }) { export default function RangeBadge({
removed,
inRange,
}: {
removed: boolean | undefined
inRange: boolean | undefined
}) {
const { t } = useTranslation() const { t } = useTranslation()
return ( return (
<BadgeWrapper> <BadgeWrapper>
{inRange ? ( {removed ? (
<MouseoverTooltip text={`Your position has 0 liquidity, and is not earning fees.`}>
<Badge variant={BadgeVariant.WARNING_OUTLINE}>
<AlertCircle width={14} height={14} />
&nbsp;
<BadgeText>{t('Inactive')}</BadgeText>
</Badge>
</MouseoverTooltip>
) : inRange ? (
<MouseoverTooltip <MouseoverTooltip
text={`The price of this pair is within your selected range. Your position is currently earning fees.`} text={`The price of this pool is within your selected range. Your position is currently earning fees.`}
> >
<Badge variant={BadgeVariant.DEFAULT}> <Badge variant={BadgeVariant.DEFAULT}>
<ActiveDot /> &nbsp; <ActiveDot /> &nbsp;
...@@ -49,7 +63,7 @@ export default function RangeBadge({ inRange }: { inRange?: boolean }) { ...@@ -49,7 +63,7 @@ export default function RangeBadge({ inRange }: { inRange?: boolean }) {
</MouseoverTooltip> </MouseoverTooltip>
) : ( ) : (
<MouseoverTooltip <MouseoverTooltip
text={`The price of this pair is outside of your selected range. Your position is not currently earning fees. `} text={`The price of this pool is outside of your selected range. Your position is not currently earning fees.`}
> >
<Badge variant={BadgeVariant.WARNING}> <Badge variant={BadgeVariant.WARNING}>
<AlertCircle width={14} height={14} /> <AlertCircle width={14} height={14} />
......
...@@ -159,7 +159,7 @@ interface CurrencyInputPanelProps { ...@@ -159,7 +159,7 @@ interface CurrencyInputPanelProps {
pair?: Pair | null pair?: Pair | null
hideInput?: boolean hideInput?: boolean
otherCurrency?: Currency | null otherCurrency?: Currency | null
fiatValue?: CurrencyAmount fiatValue?: CurrencyAmount | null
priceImpact?: Percent priceImpact?: Percent
id: string id: string
showCommonBases?: boolean showCommonBases?: boolean
......
...@@ -141,7 +141,7 @@ export default function Menu() { ...@@ -141,7 +141,7 @@ export default function Menu() {
<Info size={14} /> <Info size={14} />
About About
</MenuItem> </MenuItem>
<MenuItem href="https://uniswap.org/docs/v2"> <MenuItem href="https://docs.uniswap.org/">
<BookOpen size={14} /> <BookOpen size={14} />
Docs Docs
</MenuItem> </MenuItem>
......
import React, { useMemo, useState } from 'react' import React, { useMemo, useState } from 'react'
import { Position } from '@uniswap/v3-sdk' import { Position } from '@uniswap/v3-sdk'
import Badge, { BadgeVariant } from 'components/Badge' import Badge from 'components/Badge'
import DoubleCurrencyLogo from 'components/DoubleLogo' import DoubleCurrencyLogo from 'components/DoubleLogo'
import { usePool } from 'hooks/usePools' import { usePool } from 'hooks/usePools'
import { useToken } from 'hooks/Tokens' import { useToken } from 'hooks/Tokens'
import { AlertCircle } from 'react-feather'
import { useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import styled from 'styled-components' import styled from 'styled-components'
import { HideSmall, MEDIA_WIDTHS, SmallOnly } from 'theme' import { HideSmall, MEDIA_WIDTHS, SmallOnly } from 'theme'
...@@ -15,16 +13,9 @@ import { formatPrice } from 'utils/formatTokenAmount' ...@@ -15,16 +13,9 @@ import { formatPrice } from 'utils/formatTokenAmount'
import Loader from 'components/Loader' import Loader from 'components/Loader'
import { unwrappedToken } from 'utils/wrappedCurrency' import { unwrappedToken } from 'utils/wrappedCurrency'
import { DAI, USDC, USDT, WBTC } from '../../constants' import { DAI, USDC, USDT, WBTC } from '../../constants'
import { MouseoverTooltip } from '../Tooltip' import RangeBadge from 'components/Badge/RangeBadge'
import { RowFixed } from 'components/Row' import { RowFixed } from 'components/Row'
const ActiveDot = styled.span`
background-color: ${({ theme }) => theme.success};
border-radius: 50%;
height: 8px;
width: 8px;
margin-right: 4px;
`
const Row = styled(Link)` const Row = styled(Link)`
align-items: center; align-items: center;
border-radius: 20px; border-radius: 20px;
...@@ -65,9 +56,7 @@ const BadgeText = styled.div` ...@@ -65,9 +56,7 @@ const BadgeText = styled.div`
font-size: 12px; font-size: 12px;
`}; `};
` `
const BadgeWrapper = styled.div`
font-size: 14px;
`
const DataLineItem = styled.div` const DataLineItem = styled.div`
font-size: 14px; font-size: 14px;
` `
...@@ -185,8 +174,6 @@ export function getPriceOrderingFromPositionForUI( ...@@ -185,8 +174,6 @@ export function getPriceOrderingFromPositionForUI(
} }
export default function PositionListItem({ positionDetails }: PositionListItemProps) { export default function PositionListItem({ positionDetails }: PositionListItemProps) {
const { t } = useTranslation()
const { const {
token0: token0Address, token0: token0Address,
token1: token1Address, token1: token1Address,
...@@ -228,6 +215,8 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr ...@@ -228,6 +215,8 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr
;[priceLower, priceUpper, base, quote] = [priceUpper?.invert(), priceLower?.invert(), quote, base] ;[priceLower, priceUpper, base, quote] = [priceUpper?.invert(), priceLower?.invert(), quote, base]
} }
const removed = liquidity?.eq(0)
return ( return (
<Row to={positionSummaryLink}> <Row to={positionSummaryLink}>
<RowFixed> <RowFixed>
...@@ -241,28 +230,7 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr ...@@ -241,28 +230,7 @@ export default function PositionListItem({ positionDetails }: PositionListItemPr
<BadgeText>{new Percent(feeAmount, 1_000_000).toSignificant()}%</BadgeText> <BadgeText>{new Percent(feeAmount, 1_000_000).toSignificant()}%</BadgeText>
</Badge> </Badge>
</PrimaryPositionIdData> </PrimaryPositionIdData>
<BadgeWrapper> <RangeBadge removed={removed} inRange={!outOfRange} />
{outOfRange ? (
<MouseoverTooltip
text={`The price of this pair is outside of your selected range. Your position is not currently earning fees.`}
>
<Badge variant={BadgeVariant.WARNING}>
<AlertCircle width={14} height={14} style={{ marginRight: '' }} />
&nbsp;
<BadgeText>{t('Out of range')}</BadgeText>
</Badge>
</MouseoverTooltip>
) : (
<MouseoverTooltip
text={`The price of this pair is within your selected range. Your position is currently earning fees.`}
>
<Badge variant={BadgeVariant.DEFAULT}>
<ActiveDot /> &nbsp;
<BadgeText>{t('In range')}</BadgeText>
</Badge>
</MouseoverTooltip>
)}
</BadgeWrapper>
</RowFixed> </RowFixed>
{priceLower && priceUpper ? ( {priceLower && priceUpper ? (
......
...@@ -13,6 +13,7 @@ import RateToggle from 'components/RateToggle' ...@@ -13,6 +13,7 @@ import RateToggle from 'components/RateToggle'
import DoubleCurrencyLogo from 'components/DoubleLogo' import DoubleCurrencyLogo from 'components/DoubleLogo'
import RangeBadge from 'components/Badge/RangeBadge' import RangeBadge from 'components/Badge/RangeBadge'
import { ThemeContext } from 'styled-components' import { ThemeContext } from 'styled-components'
import { JSBI } from '@uniswap/v2-sdk'
export const PositionPreview = ({ export const PositionPreview = ({
position, position,
...@@ -55,6 +56,8 @@ export const PositionPreview = ({ ...@@ -55,6 +56,8 @@ export const PositionPreview = ({
setBaseCurrency(quoteCurrency) setBaseCurrency(quoteCurrency)
}, [quoteCurrency]) }, [quoteCurrency])
const removed = position?.liquidity && JSBI.equal(position?.liquidity, JSBI.BigInt(0))
return ( return (
<AutoColumn gap="md" style={{ marginTop: '0.5rem' }}> <AutoColumn gap="md" style={{ marginTop: '0.5rem' }}>
<RowBetween style={{ marginBottom: '0.5rem' }}> <RowBetween style={{ marginBottom: '0.5rem' }}>
...@@ -69,7 +72,7 @@ export const PositionPreview = ({ ...@@ -69,7 +72,7 @@ export const PositionPreview = ({
{currency0?.symbol} / {currency1?.symbol} {currency0?.symbol} / {currency1?.symbol}
</TYPE.label> </TYPE.label>
</RowFixed> </RowFixed>
<RangeBadge inRange={inRange} /> <RangeBadge removed={removed} inRange={inRange} />
</RowBetween> </RowBetween>
<LightCard> <LightCard>
......
...@@ -43,12 +43,4 @@ export const RowFixed = styled(Row)<{ gap?: string; justify?: string }>` ...@@ -43,12 +43,4 @@ export const RowFixed = styled(Row)<{ gap?: string; justify?: string }>`
margin: ${({ gap }) => gap && `-${gap}`}; margin: ${({ gap }) => gap && `-${gap}`};
` `
export const RowResponsive = styled(Row)`
${({ theme }) => theme.mediaWidth.upToSmall`
flex-direction: column;
justify-content: flext-start;
align-items: flex-start;
`}
`
export default Row export default Row
...@@ -44,7 +44,11 @@ export function MouseoverTooltipContent({ content, children, ...rest }: Omit<Too ...@@ -44,7 +44,11 @@ export function MouseoverTooltipContent({ content, children, ...rest }: Omit<Too
const close = useCallback(() => setShow(false), [setShow]) const close = useCallback(() => setShow(false), [setShow])
return ( return (
<TooltipContent {...rest} show={show} content={content}> <TooltipContent {...rest} show={show} content={content}>
<div onMouseEnter={open} onMouseLeave={close}> <div
style={{ display: 'inline-block', lineHeight: 0, padding: '0.25rem' }}
onMouseEnter={open}
onMouseLeave={close}
>
{children} {children}
</div> </div>
</TooltipContent> </TooltipContent>
......
...@@ -4,7 +4,7 @@ import { useLocation } from 'react-router' ...@@ -4,7 +4,7 @@ import { useLocation } from 'react-router'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import useParsedQueryString from '../../hooks/useParsedQueryString' import useParsedQueryString from '../../hooks/useParsedQueryString'
import useToggledVersion, { DEFAULT_VERSION, Version } from '../../hooks/useToggledVersion' import { DEFAULT_VERSION, Version } from '../../hooks/useToggledVersion'
import { HideSmall, TYPE, SmallOnly } from '../../theme' import { HideSmall, TYPE, SmallOnly } from '../../theme'
import { ButtonPrimary } from '../Button' import { ButtonPrimary } from '../Button'
import styled from 'styled-components' import styled from 'styled-components'
...@@ -17,7 +17,7 @@ const ResponsiveButton = styled(ButtonPrimary)` ...@@ -17,7 +17,7 @@ const ResponsiveButton = styled(ButtonPrimary)`
height: 24px; height: 24px;
margin-left: 0.75rem; margin-left: 0.75rem;
${({ theme }) => theme.mediaWidth.upToSmall` ${({ theme }) => theme.mediaWidth.upToSmall`
padding: 4px; padding: 4px;
border-radius: 8px; border-radius: 8px;
`}; `};
` `
...@@ -62,29 +62,3 @@ export default function BetterTradeLink({ ...@@ -62,29 +62,3 @@ export default function BetterTradeLink({
</ResponsiveButton> </ResponsiveButton>
) )
} }
export function DefaultVersionLink() {
const location = useLocation()
const search = useParsedQueryString()
const version = useToggledVersion()
const linkDestination = useMemo(() => {
return {
...location,
search: `?${stringify({
...search,
use: DEFAULT_VERSION,
})}`,
}
}, [location, search])
return (
<ButtonPrimary
as={Link}
to={linkDestination}
style={{ width: 'fit-content', marginTop: '4px', padding: '0.5rem 0.5rem' }}
>
Showing {version.toUpperCase()} price. <b>Switch to Uniswap {DEFAULT_VERSION.toUpperCase()}</b>
</ButtonPrimary>
)
}
...@@ -12,23 +12,16 @@ interface TradePriceProps { ...@@ -12,23 +12,16 @@ interface TradePriceProps {
} }
const StyledPriceContainer = styled.button` const StyledPriceContainer = styled.button`
display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
display: flex;
width: fit-content;
padding: 0; padding: 0;
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 400; font-weight: 400;
background-color: transparent; background-color: transparent;
border: none; border: none;
margin-left: 1rem;
height: 24px; height: 24px;
cursor: pointer; cursor: pointer;
${({ theme }) => theme.mediaWidth.upToSmall`
margin-left: 0;
margin-top: 8px;
`}
` `
export default function TradePrice({ price, showInverted, setShowInverted }: TradePriceProps) { export default function TradePrice({ price, showInverted, setShowInverted }: TradePriceProps) {
...@@ -45,11 +38,13 @@ export default function TradePrice({ price, showInverted, setShowInverted }: Tra ...@@ -45,11 +38,13 @@ export default function TradePrice({ price, showInverted, setShowInverted }: Tra
const labelInverted = showInverted ? `${price.baseCurrency?.symbol} ` : `${price.quoteCurrency?.symbol}` const labelInverted = showInverted ? `${price.baseCurrency?.symbol} ` : `${price.quoteCurrency?.symbol}`
const flipPrice = useCallback(() => setShowInverted(!showInverted), [setShowInverted, showInverted]) const flipPrice = useCallback(() => setShowInverted(!showInverted), [setShowInverted, showInverted])
const text = `${'1 ' + labelInverted + ' = ' + formattedPrice ?? '-'} ${label}`
return ( return (
<StyledPriceContainer onClick={flipPrice}> <StyledPriceContainer onClick={flipPrice} title={text}>
<div style={{ alignItems: 'center', display: 'flex', width: 'fit-content' }}> <div style={{ alignItems: 'center', display: 'flex', width: 'fit-content' }}>
<Text fontWeight={500} fontSize={14} color={theme.text1}> <Text fontWeight={500} fontSize={14} color={theme.text1}>
{'1 ' + labelInverted + ' = ' + formattedPrice ?? '-'} {label} {text}
</Text> </Text>
</div> </div>
</StyledPriceContainer> </StyledPriceContainer>
......
...@@ -206,7 +206,7 @@ export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = { ...@@ -206,7 +206,7 @@ export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
export const NetworkContextName = 'NETWORK' export const NetworkContextName = 'NETWORK'
// default allowed slippage, in bips // default allowed slippage, in bips
export const INITIAL_ALLOWED_SLIPPAGE = new Percent(50, 10_000) export const INITIAL_ALLOWED_SLIPPAGE = new Percent(10, 10_000)
// 20 minutes, denominated in seconds // 20 minutes, denominated in seconds
export const DEFAULT_DEADLINE_FROM_NOW = 60 * 20 export const DEFAULT_DEADLINE_FROM_NOW = 60 * 20
......
...@@ -13,10 +13,10 @@ import { useActiveWeb3React } from './index' ...@@ -13,10 +13,10 @@ import { useActiveWeb3React } from './index'
import { useTokenAllowance } from './useTokenAllowance' import { useTokenAllowance } from './useTokenAllowance'
export enum ApprovalState { export enum ApprovalState {
UNKNOWN, UNKNOWN = 'UNKNOWN',
NOT_APPROVED, NOT_APPROVED = 'NOT_APPROVED',
PENDING, PENDING = 'PENDING',
APPROVED, APPROVED = 'APPROVED',
} }
// returns a variable indicating the state of the approval and a function which approves if necessary or early returns // returns a variable indicating the state of the approval and a function which approves if necessary or early returns
......
...@@ -27,7 +27,7 @@ interface PermitInfo { ...@@ -27,7 +27,7 @@ interface PermitInfo {
version?: string version?: string
} }
// todo: read this information from extensions on token lists // todo: read this information from extensions on token lists or elsewhere (permit registry?)
const PERMITTABLE_TOKENS: { const PERMITTABLE_TOKENS: {
[chainId in ChainId]: { [chainId in ChainId]: {
[checksummedTokenAddress: string]: PermitInfo [checksummedTokenAddress: string]: PermitInfo
......
...@@ -15,6 +15,7 @@ import TransactionConfirmationModal, { ConfirmationModalContent } from '../../co ...@@ -15,6 +15,7 @@ import TransactionConfirmationModal, { ConfirmationModalContent } from '../../co
import CurrencyInputPanel from '../../components/CurrencyInputPanel' import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { RowBetween } from '../../components/Row' import { RowBetween } from '../../components/Row'
import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported' import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import Review from './Review' import Review from './Review'
import { useActiveWeb3React } from '../../hooks' import { useActiveWeb3React } from '../../hooks'
import { useCurrency } from '../../hooks/Tokens' import { useCurrency } from '../../hooks/Tokens'
...@@ -106,6 +107,7 @@ export default function AddLiquidity({ ...@@ -106,6 +107,7 @@ export default function AddLiquidity({
const { independentField, typedValue, startPriceTypedValue } = useV3MintState() const { independentField, typedValue, startPriceTypedValue } = useV3MintState()
const { const {
pool,
ticks, ticks,
dependentField, dependentField,
price, price,
...@@ -155,6 +157,11 @@ export default function AddLiquidity({ ...@@ -155,6 +157,11 @@ export default function AddLiquidity({
[dependentField]: parsedAmounts[dependentField]?.toSignificant(6) ?? '', [dependentField]: parsedAmounts[dependentField]?.toSignificant(6) ?? '',
} }
const usdcValues = {
[Field.CURRENCY_A]: useUSDCValue(parsedAmounts[Field.CURRENCY_A]),
[Field.CURRENCY_B]: useUSDCValue(parsedAmounts[Field.CURRENCY_B]),
}
// get the max amounts user can add // get the max amounts user can add
const maxAmounts: { [field in Field]?: TokenAmount } = [Field.CURRENCY_A, Field.CURRENCY_B].reduce( const maxAmounts: { [field in Field]?: TokenAmount } = [Field.CURRENCY_A, Field.CURRENCY_B].reduce(
(accumulator, field) => { (accumulator, field) => {
...@@ -348,9 +355,14 @@ export default function AddLiquidity({ ...@@ -348,9 +355,14 @@ export default function AddLiquidity({
quoteCurrency ?? undefined, quoteCurrency ?? undefined,
feeAmount, feeAmount,
tickLower, tickLower,
tickUpper tickUpper,
pool
) )
// we need an existence check on parsed amounts for single-asset deposits
const showApprovalA = approvalA !== ApprovalState.APPROVED && !!parsedAmounts[Field.CURRENCY_A]
const showApprovalB = approvalB !== ApprovalState.APPROVED && !!parsedAmounts[Field.CURRENCY_B]
return ( return (
<ScrollablePage> <ScrollablePage>
<TransactionConfirmationModal <TransactionConfirmationModal
...@@ -452,8 +464,11 @@ export default function AddLiquidity({ ...@@ -452,8 +464,11 @@ export default function AddLiquidity({
handleRateToggle={() => { handleRateToggle={() => {
onLeftRangeInput('') onLeftRangeInput('')
onRightRangeInput('') onRightRangeInput('')
console.log('test') history.push(
history.push(`/add/${currencyIdB as string}/${currencyIdA as string}`) `/add/${currencyIdB as string}/${currencyIdA as string}${
feeAmount ? '/' + feeAmount : ''
}`
)
}} }}
/> />
) : null} ) : null}
...@@ -515,8 +530,9 @@ export default function AddLiquidity({ ...@@ -515,8 +530,9 @@ export default function AddLiquidity({
handleRateToggle={() => { handleRateToggle={() => {
onLeftRangeInput('') onLeftRangeInput('')
onRightRangeInput('') onRightRangeInput('')
console.log('test') history.push(
history.push(`/add/${currencyIdB as string}/${currencyIdA as string}`) `/add/${currencyIdB as string}/${currencyIdA as string}${feeAmount ? '/' + feeAmount : ''}`
)
}} }}
/> />
) : null} ) : null}
...@@ -602,6 +618,7 @@ export default function AddLiquidity({ ...@@ -602,6 +618,7 @@ export default function AddLiquidity({
showMaxButton={!atMaxAmounts[Field.CURRENCY_A]} showMaxButton={!atMaxAmounts[Field.CURRENCY_A]}
currency={currencies[Field.CURRENCY_A]} currency={currencies[Field.CURRENCY_A]}
id="add-liquidity-input-tokena" id="add-liquidity-input-tokena"
fiatValue={usdcValues[Field.CURRENCY_A]}
showCommonBases showCommonBases
locked={depositADisabled} locked={depositADisabled}
/> />
...@@ -613,6 +630,7 @@ export default function AddLiquidity({ ...@@ -613,6 +630,7 @@ export default function AddLiquidity({
onFieldBInput(maxAmounts[Field.CURRENCY_B]?.toExact() ?? '') onFieldBInput(maxAmounts[Field.CURRENCY_B]?.toExact() ?? '')
}} }}
showMaxButton={!atMaxAmounts[Field.CURRENCY_B]} showMaxButton={!atMaxAmounts[Field.CURRENCY_B]}
fiatValue={usdcValues[Field.CURRENCY_B]}
currency={currencies[Field.CURRENCY_B]} currency={currencies[Field.CURRENCY_B]}
id="add-liquidity-input-tokenb" id="add-liquidity-input-tokenb"
showCommonBases showCommonBases
...@@ -637,13 +655,13 @@ export default function AddLiquidity({ ...@@ -637,13 +655,13 @@ export default function AddLiquidity({
approvalB === ApprovalState.PENDING) && approvalB === ApprovalState.PENDING) &&
isValid && ( isValid && (
<RowBetween> <RowBetween>
{approvalA !== ApprovalState.APPROVED && ( {showApprovalA && (
<ButtonPrimary <ButtonPrimary
borderRadius="12px" borderRadius="12px"
padding={'12px'} padding={'12px'}
onClick={approveACallback} onClick={approveACallback}
disabled={approvalA === ApprovalState.PENDING} disabled={approvalA === ApprovalState.PENDING}
width={approvalB !== ApprovalState.APPROVED ? '48%' : '100%'} width={showApprovalB ? '48%' : '100%'}
> >
{approvalA === ApprovalState.PENDING ? ( {approvalA === ApprovalState.PENDING ? (
<Dots>Approving {currencies[Field.CURRENCY_A]?.symbol}</Dots> <Dots>Approving {currencies[Field.CURRENCY_A]?.symbol}</Dots>
...@@ -652,13 +670,13 @@ export default function AddLiquidity({ ...@@ -652,13 +670,13 @@ export default function AddLiquidity({
)} )}
</ButtonPrimary> </ButtonPrimary>
)} )}
{approvalB !== ApprovalState.APPROVED && ( {showApprovalB && (
<ButtonPrimary <ButtonPrimary
borderRadius="12px" borderRadius="12px"
padding={'12px'} padding={'12px'}
onClick={approveBCallback} onClick={approveBCallback}
disabled={approvalB === ApprovalState.PENDING} disabled={approvalB === ApprovalState.PENDING}
width={approvalA !== ApprovalState.APPROVED ? '48%' : '100%'} width={showApprovalA ? '48%' : '100%'}
> >
{approvalB === ApprovalState.PENDING ? ( {approvalB === ApprovalState.PENDING ? (
<Dots>Approving {currencies[Field.CURRENCY_B]?.symbol}</Dots> <Dots>Approving {currencies[Field.CURRENCY_B]?.symbol}</Dots>
......
import styled from 'styled-components' import styled from 'styled-components'
import { AutoColumn } from 'components/Column' import { AutoColumn } from 'components/Column'
import CurrencyInputPanel from 'components/CurrencyInputPanel' import CurrencyInputPanel from 'components/CurrencyInputPanel'
import Card, { DarkGreyCard } from 'components/Card' import { DarkGreyCard } from 'components/Card'
import Input from 'components/NumericalInput' import Input from 'components/NumericalInput'
export const Wrapper = styled.div` export const Wrapper = styled.div`
...@@ -24,16 +24,6 @@ export const ScrollablePage = styled.div` ...@@ -24,16 +24,6 @@ export const ScrollablePage = styled.div`
flex-direction: row; flex-direction: row;
` `
export const RangeBadge = styled(Card)<{ inRange?: boolean }>`
width: fit-content;
font-size: 14px;
font-weight: 500;
border-radius: 8px;
padding: 4px 6px;
color: ${({ theme }) => theme.black};
background-color: ${({ inRange, theme }) => (inRange ? theme.green1 : theme.yellow2)};
`
export const FixedPreview = styled.div` export const FixedPreview = styled.div`
position: relative; position: relative;
padding: 16px; padding: 16px;
...@@ -49,8 +39,8 @@ export const FixedPreview = styled.div` ...@@ -49,8 +39,8 @@ export const FixedPreview = styled.div`
` `
export const DynamicSection = styled(AutoColumn)<{ disabled?: boolean }>` export const DynamicSection = styled(AutoColumn)<{ disabled?: boolean }>`
opacity: ${({ disabled }) => (disabled ? '0.3' : '1')} opacity: ${({ disabled }) => (disabled ? '0.3' : '1')};
pointer-events: ${({ disabled }) => (disabled ? 'none' : 'initial')} pointer-events: ${({ disabled }) => (disabled ? 'none' : 'initial')};
` `
export const CurrencyDropdown = styled(CurrencyInputPanel)` export const CurrencyDropdown = styled(CurrencyInputPanel)`
......
...@@ -194,6 +194,8 @@ export function PositionPage({ ...@@ -194,6 +194,8 @@ export function PositionPage({
const { token0: token0Address, token1: token1Address, fee: feeAmount, liquidity, tickLower, tickUpper, tokenId } = const { token0: token0Address, token1: token1Address, fee: feeAmount, liquidity, tickLower, tickUpper, tokenId } =
positionDetails || {} positionDetails || {}
const removed = liquidity?.eq(0)
const token0 = useToken(token0Address) const token0 = useToken(token0Address)
const token1 = useToken(token1Address) const token1 = useToken(token1Address)
...@@ -236,9 +238,6 @@ export function PositionPage({ ...@@ -236,9 +238,6 @@ export function PositionPage({
: undefined : undefined
}, [inverted, pool, priceLower, priceUpper]) }, [inverted, pool, priceLower, priceUpper])
// really can't figure out why i have to do this, getting conditional hook call errors otherwise
const WORKAROUND = typeof ratio === 'number' ? (inverted ? 100 - ratio : ratio) : undefined
// fees // fees
const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, positionDetails) const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, positionDetails)
...@@ -408,7 +407,7 @@ export function PositionPage({ ...@@ -408,7 +407,7 @@ export function PositionPage({
<Badge style={{ marginRight: '8px' }}> <Badge style={{ marginRight: '8px' }}>
<BadgeText>{new Percent(feeAmount, 1_000_000).toSignificant()}%</BadgeText> <BadgeText>{new Percent(feeAmount, 1_000_000).toSignificant()}%</BadgeText>
</Badge> </Badge>
<RangeBadge inRange={inRange} /> <RangeBadge removed={removed} inRange={inRange} />
</RowFixed> </RowFixed>
{ownsNFT && ( {ownsNFT && (
<RowFixed> <RowFixed>
...@@ -424,7 +423,7 @@ export function PositionPage({ ...@@ -424,7 +423,7 @@ export function PositionPage({
{t('Add Liquidity')} {t('Add Liquidity')}
</ButtonGray> </ButtonGray>
) : null} ) : null}
{tokenId && ( {tokenId && !removed ? (
<ResponsiveButtonPrimary <ResponsiveButtonPrimary
as={Link} as={Link}
to={`/remove/${tokenId}`} to={`/remove/${tokenId}`}
...@@ -434,7 +433,7 @@ export function PositionPage({ ...@@ -434,7 +433,7 @@ export function PositionPage({
> >
{t('Remove Liquidity')} {t('Remove Liquidity')}
</ResponsiveButtonPrimary> </ResponsiveButtonPrimary>
)} ) : null}
</RowFixed> </RowFixed>
)} )}
</ResponsiveRow> </ResponsiveRow>
...@@ -498,13 +497,13 @@ export function PositionPage({ ...@@ -498,13 +497,13 @@ export function PositionPage({
<TYPE.main> <TYPE.main>
{inverted ? position?.amount0.toSignificant(4) : position?.amount1.toSignificant(4)} {inverted ? position?.amount0.toSignificant(4) : position?.amount1.toSignificant(4)}
</TYPE.main> </TYPE.main>
{typeof ratio === 'number' && ( {typeof ratio === 'number' && !removed ? (
<DarkGreyCard padding="4px 6px" style={{ width: 'fit-content', marginLeft: '8px' }}> <DarkGreyCard padding="4px 6px" style={{ width: 'fit-content', marginLeft: '8px' }}>
<TYPE.main color={theme.text2} fontSize={11}> <TYPE.main color={theme.text2} fontSize={11}>
{inverted ? ratio : 100 - ratio}% {inverted ? ratio : 100 - ratio}%
</TYPE.main> </TYPE.main>
</DarkGreyCard> </DarkGreyCard>
)} ) : null}
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
<RowBetween> <RowBetween>
...@@ -516,13 +515,13 @@ export function PositionPage({ ...@@ -516,13 +515,13 @@ export function PositionPage({
<TYPE.main> <TYPE.main>
{inverted ? position?.amount1.toSignificant(4) : position?.amount0.toSignificant(4)} {inverted ? position?.amount1.toSignificant(4) : position?.amount0.toSignificant(4)}
</TYPE.main> </TYPE.main>
{typeof ratio === 'number' && ( {typeof ratio === 'number' && !removed ? (
<DarkGreyCard padding="4px 6px" style={{ width: 'fit-content', marginLeft: '8px' }}> <DarkGreyCard padding="4px 6px" style={{ width: 'fit-content', marginLeft: '8px' }}>
<TYPE.main color={theme.text2} fontSize={11}> <TYPE.main color={theme.text2} fontSize={11}>
{WORKAROUND}% {inverted ? 100 - ratio : ratio}%
</TYPE.main> </TYPE.main>
</DarkGreyCard> </DarkGreyCard>
)} ) : null}
</RowFixed> </RowFixed>
</RowBetween> </RowBetween>
</AutoColumn> </AutoColumn>
...@@ -621,7 +620,7 @@ export function PositionPage({ ...@@ -621,7 +620,7 @@ export function PositionPage({
</Label> </Label>
<HideExtraSmall> <HideExtraSmall>
<> <>
<RangeBadge inRange={inRange} /> <RangeBadge removed={removed} inRange={inRange} />
<span style={{ width: '8px' }} /> <span style={{ width: '8px' }} />
</> </>
</HideExtraSmall> </HideExtraSmall>
......
...@@ -138,7 +138,7 @@ export default function Pool() { ...@@ -138,7 +138,7 @@ export default function Pool() {
{t('Learn')} {t('Learn')}
</MenuItem> </MenuItem>
), ),
link: 'https://uniswap.org/docs/v2/', link: 'https://docs.uniswap.org/',
external: true, external: true,
}, },
] ]
......
...@@ -28,12 +28,12 @@ import Loader from 'components/Loader' ...@@ -28,12 +28,12 @@ import Loader from 'components/Loader'
import { useToken } from 'hooks/Tokens' import { useToken } from 'hooks/Tokens'
import { unwrappedToken } from 'utils/wrappedCurrency' import { unwrappedToken } from 'utils/wrappedCurrency'
import DoubleCurrencyLogo from 'components/DoubleLogo' import DoubleCurrencyLogo from 'components/DoubleLogo'
import { RangeBadge } from 'pages/AddLiquidity/styled'
import { Break } from 'components/earn/styled' import { Break } from 'components/earn/styled'
import { NonfungiblePositionManager } from '@uniswap/v3-sdk' import { NonfungiblePositionManager } from '@uniswap/v3-sdk'
import { calculateGasMargin } from 'utils' import { calculateGasMargin } from 'utils'
import useTheme from 'hooks/useTheme' import useTheme from 'hooks/useTheme'
import { AddRemoveTabs } from 'components/NavigationTabs' import { AddRemoveTabs } from 'components/NavigationTabs'
import RangeBadge from 'components/Badge/RangeBadge'
export const UINT128MAX = BigNumber.from(2).pow(128).sub(1) export const UINT128MAX = BigNumber.from(2).pow(128).sub(1)
...@@ -83,6 +83,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -83,6 +83,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
} = useDerivedV3BurnInfo(position) } = useDerivedV3BurnInfo(position)
const { onPercentSelect } = useBurnV3ActionHandlers() const { onPercentSelect } = useBurnV3ActionHandlers()
const removed = position?.liquidity?.eq(0)
// boilerplate for the slider // boilerplate for the slider
const [percentForSlider, onPercentSelectForSlider] = useDebouncedChangeHandler(percent, onPercentSelect) const [percentForSlider, onPercentSelectForSlider] = useDebouncedChangeHandler(percent, onPercentSelect)
...@@ -281,7 +283,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -281,7 +283,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
<DoubleCurrencyLogo currency0={currency1} currency1={currency0} size={20} margin={true} /> <DoubleCurrencyLogo currency0={currency1} currency1={currency0} size={20} margin={true} />
<TYPE.label ml="10px" fontSize="20px">{`${currency0?.symbol}/${currency1?.symbol}`}</TYPE.label> <TYPE.label ml="10px" fontSize="20px">{`${currency0?.symbol}/${currency1?.symbol}`}</TYPE.label>
</RowFixed> </RowFixed>
<RangeBadge inRange={!outOfRange}>{outOfRange ? 'Out of range' : 'In Range'}</RangeBadge> <RangeBadge removed={removed} inRange={!outOfRange} />
</RowBetween> </RowBetween>
<LightCard> <LightCard>
<AutoColumn gap="md"> <AutoColumn gap="md">
...@@ -363,10 +365,10 @@ function Remove({ tokenId }: { tokenId: BigNumber }) { ...@@ -363,10 +365,10 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
<AutoColumn gap="12px" style={{ flex: '1' }}> <AutoColumn gap="12px" style={{ flex: '1' }}>
<ButtonConfirmed <ButtonConfirmed
confirmed={false} confirmed={false}
disabled={percent === 0 || !liquidityValue0} disabled={removed || percent === 0 || !liquidityValue0}
onClick={() => setShowConfirm(true)} onClick={() => setShowConfirm(true)}
> >
{error ?? 'Remove'} {removed ? 'Inactive' : error ?? 'Remove'}
</ButtonConfirmed> </ButtonConfirmed>
</AutoColumn> </AutoColumn>
</div> </div>
......
...@@ -10,7 +10,7 @@ import { ArrowDown, CheckCircle, HelpCircle, Info, ArrowLeft } from 'react-feath ...@@ -10,7 +10,7 @@ import { ArrowDown, CheckCircle, HelpCircle, Info, ArrowLeft } from 'react-feath
import ReactGA from 'react-ga' import ReactGA from 'react-ga'
import { Link, RouteComponentProps } from 'react-router-dom' import { Link, RouteComponentProps } from 'react-router-dom'
import { Text } from 'rebass' import { Text } from 'rebass'
import { ThemeContext } from 'styled-components' import styled, { ThemeContext } from 'styled-components'
import AddressInputPanel from '../../components/AddressInputPanel' import AddressInputPanel from '../../components/AddressInputPanel'
import { ButtonConfirmed, ButtonError, ButtonGray, ButtonLight, ButtonPrimary } from '../../components/Button' import { ButtonConfirmed, ButtonError, ButtonGray, ButtonLight, ButtonPrimary } from '../../components/Button'
import { GreyCard } from '../../components/Card' import { GreyCard } from '../../components/Card'
...@@ -18,7 +18,7 @@ import { AutoColumn } from '../../components/Column' ...@@ -18,7 +18,7 @@ import { AutoColumn } from '../../components/Column'
import CurrencyInputPanel from '../../components/CurrencyInputPanel' import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import CurrencyLogo from '../../components/CurrencyLogo' import CurrencyLogo from '../../components/CurrencyLogo'
import Loader from '../../components/Loader' import Loader from '../../components/Loader'
import { AutoRow, RowResponsive, RowFixed } from '../../components/Row' import Row, { AutoRow, RowFixed } from '../../components/Row'
import BetterTradeLink from '../../components/swap/BetterTradeLink' import BetterTradeLink from '../../components/swap/BetterTradeLink'
import confirmPriceImpactWithoutFee from '../../components/swap/confirmPriceImpactWithoutFee' import confirmPriceImpactWithoutFee from '../../components/swap/confirmPriceImpactWithoutFee'
import ConfirmSwapModal from '../../components/swap/ConfirmSwapModal' import ConfirmSwapModal from '../../components/swap/ConfirmSwapModal'
...@@ -47,14 +47,25 @@ import { ...@@ -47,14 +47,25 @@ import {
useSwapState, useSwapState,
} from '../../state/swap/hooks' } from '../../state/swap/hooks'
import { useExpertModeManager, useUserSingleHopOnly, useUserSlippageTolerance } from '../../state/user/hooks' import { useExpertModeManager, useUserSingleHopOnly, useUserSlippageTolerance } from '../../state/user/hooks'
import { LinkStyledButton, TYPE } from '../../theme' import { HideSmall, LinkStyledButton, TYPE } from '../../theme'
import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact' import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact'
import { computePriceImpactWithMaximumSlippage } from '../../utils/computePriceImpactWithMaximumSlippage'
import { getTradeVersion } from '../../utils/getTradeVersion' import { getTradeVersion } from '../../utils/getTradeVersion'
import { isTradeBetter } from '../../utils/isTradeBetter' import { isTradeBetter } from '../../utils/isTradeBetter'
import { maxAmountSpend } from '../../utils/maxAmountSpend' import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { warningSeverity } from '../../utils/prices' import { warningSeverity } from '../../utils/prices'
import AppBody from '../AppBody' import AppBody from '../AppBody'
const StyledInfo = styled(Info)`
opacity: 0.4;
color: ${({ theme }) => theme.text1};
height: 16px;
width: 16px;
:hover {
opacity: 0.8;
}
`
export default function Swap({ history }: RouteComponentProps) { export default function Swap({ history }: RouteComponentProps) {
const loadedUrlParams = useDefaultsFromURLSearch() const loadedUrlParams = useDefaultsFromURLSearch()
...@@ -274,8 +285,17 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -274,8 +285,17 @@ export default function Swap({ history }: RouteComponentProps) {
// errors // errors
const [showInverted, setShowInverted] = useState<boolean>(false) const [showInverted, setShowInverted] = useState<boolean>(false)
// warnings on price impact // warnings on the greater of fiat value price impact and execution price impact
const priceImpactSeverity = warningSeverity(priceImpact) const priceImpactSeverity = useMemo(() => {
const executionPriceImpact = trade ? computePriceImpactWithMaximumSlippage(trade, allowedSlippage) : undefined
return warningSeverity(
executionPriceImpact && priceImpact
? executionPriceImpact.greaterThan(priceImpact)
? executionPriceImpact
: priceImpact
: executionPriceImpact ?? priceImpact
)
}, [allowedSlippage, priceImpact, trade])
// show approve flow when: no error on inputs, not approved or pending, or approved in current session // 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 // never show if price impact is above threshold in non expert mode
...@@ -398,7 +418,7 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -398,7 +418,7 @@ export default function Swap({ history }: RouteComponentProps) {
</> </>
) : null} ) : null}
<RowResponsive style={{ justifyContent: !trade ? 'center' : 'space-between' }}> <Row style={{ justifyContent: !trade ? 'center' : 'space-between' }}>
<RowFixed> <RowFixed>
{[V3TradeState.VALID, V3TradeState.SYNCING, V3TradeState.NO_ROUTE_FOUND].includes(v3TradeState) && {[V3TradeState.VALID, V3TradeState.SYNCING, V3TradeState.NO_ROUTE_FOUND].includes(v3TradeState) &&
(toggledVersion === Version.v3 && isTradeBetter(v3Trade, v2Trade) ? ( (toggledVersion === Version.v3 && isTradeBetter(v3Trade, v2Trade) ? (
...@@ -424,7 +444,7 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -424,7 +444,7 @@ export default function Swap({ history }: RouteComponentProps) {
> >
<ArrowLeft color={theme.text3} size={12} /> &nbsp; <ArrowLeft color={theme.text3} size={12} /> &nbsp;
<TYPE.main style={{ lineHeight: '120%' }} fontSize={12}> <TYPE.main style={{ lineHeight: '120%' }} fontSize={12}>
Back to V3 <HideSmall>Back to </HideSmall>V3
</TYPE.main> </TYPE.main>
</ButtonGray> </ButtonGray>
) )
...@@ -447,33 +467,19 @@ export default function Swap({ history }: RouteComponentProps) { ...@@ -447,33 +467,19 @@ export default function Swap({ history }: RouteComponentProps) {
</ButtonGray> </ButtonGray>
)} )}
</RowFixed> </RowFixed>
<RowFixed> {trade ? (
{trade ? ( <RowFixed>
<TradePrice <TradePrice
price={trade.worstExecutionPrice(allowedSlippage)} price={trade.worstExecutionPrice(allowedSlippage)}
showInverted={showInverted} showInverted={showInverted}
setShowInverted={setShowInverted} setShowInverted={setShowInverted}
/> />
) : (
<TYPE.main></TYPE.main>
)}
{trade && (
<MouseoverTooltipContent content={<AdvancedSwapDetails trade={trade} />}> <MouseoverTooltipContent content={<AdvancedSwapDetails trade={trade} />}>
<Info <StyledInfo />
size={16}
style={{
display: 'flex',
justifyContent: 'space-between',
height: '24px',
opacity: 0.4,
margin: '0 .75rem 0 .5rem',
}}
color={theme.text1}
/>
</MouseoverTooltipContent> </MouseoverTooltipContent>
)} </RowFixed>
</RowFixed> ) : null}
</RowResponsive> </Row>
<BottomGrouping> <BottomGrouping>
{swapIsUnsupported ? ( {swapIsUnsupported ? (
......
...@@ -420,7 +420,8 @@ export function useRangeHopCallbacks( ...@@ -420,7 +420,8 @@ export function useRangeHopCallbacks(
quoteCurrency: Currency | undefined, quoteCurrency: Currency | undefined,
feeAmount: FeeAmount | undefined, feeAmount: FeeAmount | undefined,
tickLower: number | undefined, tickLower: number | undefined,
tickUpper: number | undefined tickUpper: number | undefined,
pool?: Pool | undefined | null
) { ) {
const { chainId } = useActiveWeb3React() const { chainId } = useActiveWeb3React()
const baseToken = useMemo(() => wrappedCurrency(baseCurrency, chainId), [baseCurrency, chainId]) const baseToken = useMemo(() => wrappedCurrency(baseCurrency, chainId), [baseCurrency, chainId])
...@@ -431,32 +432,52 @@ export function useRangeHopCallbacks( ...@@ -431,32 +432,52 @@ export function useRangeHopCallbacks(
const newPrice = tickToPrice(baseToken, quoteToken, tickLower - TICK_SPACINGS[feeAmount]) const newPrice = tickToPrice(baseToken, quoteToken, tickLower - TICK_SPACINGS[feeAmount])
return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP) return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP)
} }
// use pool current tick as starting tick if we have pool but no tick input
if (!(typeof tickLower === 'number') && baseToken && quoteToken && feeAmount && pool) {
const newPrice = tickToPrice(baseToken, quoteToken, pool.tickCurrent - TICK_SPACINGS[feeAmount])
return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP)
}
return '' return ''
}, [baseToken, quoteToken, tickLower, feeAmount]) }, [baseToken, quoteToken, tickLower, feeAmount, pool])
const getIncrementLower = useCallback(() => { const getIncrementLower = useCallback(() => {
if (baseToken && quoteToken && typeof tickLower === 'number' && feeAmount) { if (baseToken && quoteToken && typeof tickLower === 'number' && feeAmount) {
const newPrice = tickToPrice(baseToken, quoteToken, tickLower + TICK_SPACINGS[feeAmount]) const newPrice = tickToPrice(baseToken, quoteToken, tickLower + TICK_SPACINGS[feeAmount])
return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP) return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP)
} }
// use pool current tick as starting tick if we have pool but no tick input
if (!(typeof tickLower === 'number') && baseToken && quoteToken && feeAmount && pool) {
const newPrice = tickToPrice(baseToken, quoteToken, pool.tickCurrent + TICK_SPACINGS[feeAmount])
return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP)
}
return '' return ''
}, [baseToken, quoteToken, tickLower, feeAmount]) }, [baseToken, quoteToken, tickLower, feeAmount, pool])
const getDecrementUpper = useCallback(() => { const getDecrementUpper = useCallback(() => {
if (baseToken && quoteToken && typeof tickUpper === 'number' && feeAmount) { if (baseToken && quoteToken && typeof tickUpper === 'number' && feeAmount) {
const newPrice = tickToPrice(baseToken, quoteToken, tickUpper - TICK_SPACINGS[feeAmount]) const newPrice = tickToPrice(baseToken, quoteToken, tickUpper - TICK_SPACINGS[feeAmount])
return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP) return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP)
} }
// use pool current tick as starting tick if we have pool but no tick input
if (!(typeof tickUpper === 'number') && baseToken && quoteToken && feeAmount && pool) {
const newPrice = tickToPrice(baseToken, quoteToken, pool.tickCurrent - TICK_SPACINGS[feeAmount])
return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP)
}
return '' return ''
}, [baseToken, quoteToken, tickUpper, feeAmount]) }, [baseToken, quoteToken, tickUpper, feeAmount, pool])
const getIncrementUpper = useCallback(() => { const getIncrementUpper = useCallback(() => {
if (baseToken && quoteToken && typeof tickUpper === 'number' && feeAmount) { if (baseToken && quoteToken && typeof tickUpper === 'number' && feeAmount) {
const newPrice = tickToPrice(baseToken, quoteToken, tickUpper + TICK_SPACINGS[feeAmount]) const newPrice = tickToPrice(baseToken, quoteToken, tickUpper + TICK_SPACINGS[feeAmount])
return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP) return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP)
} }
// use pool current tick as starting tick if we have pool but no tick input
if (!(typeof tickUpper === 'number') && baseToken && quoteToken && feeAmount && pool) {
const newPrice = tickToPrice(baseToken, quoteToken, pool.tickCurrent + TICK_SPACINGS[feeAmount])
return newPrice.toSignificant(5, undefined, Rounding.ROUND_UP)
}
return '' return ''
}, [baseToken, quoteToken, tickUpper, feeAmount]) }, [baseToken, quoteToken, tickUpper, feeAmount, pool])
return { getDecrementLower, getIncrementLower, getDecrementUpper, getIncrementUpper } return { getDecrementLower, getIncrementLower, getDecrementUpper, getIncrementUpper }
} }
...@@ -62,7 +62,7 @@ export const initialState: UserState = { ...@@ -62,7 +62,7 @@ export const initialState: UserState = {
matchesDarkMode: false, matchesDarkMode: false,
userExpertMode: false, userExpertMode: false,
userSingleHopOnly: false, userSingleHopOnly: false,
userSlippageTolerance: 50, userSlippageTolerance: 10,
userDeadline: DEFAULT_DEADLINE_FROM_NOW, userDeadline: DEFAULT_DEADLINE_FROM_NOW,
tokens: {}, tokens: {},
pairs: {}, pairs: {},
...@@ -76,7 +76,7 @@ export default createReducer(initialState, (builder) => ...@@ -76,7 +76,7 @@ export default createReducer(initialState, (builder) =>
// slippage isnt being tracked in local storage, reset to default // slippage isnt being tracked in local storage, reset to default
// noinspection SuspiciousTypeOfGuard // noinspection SuspiciousTypeOfGuard
if (typeof state.userSlippageTolerance !== 'number') { if (typeof state.userSlippageTolerance !== 'number') {
state.userSlippageTolerance = 50 state.userSlippageTolerance = 10
} }
// deadline isnt being tracked in local storage, reset to default // deadline isnt being tracked in local storage, reset to default
......
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