Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5bc5d6504e | ||
|
|
7a0b85bf41 | ||
|
|
534afb3278 | ||
|
|
7d71af353e | ||
|
|
af6098bfe5 | ||
|
|
fce29bb36f | ||
|
|
4517af39ba | ||
|
|
b40163ce05 | ||
|
|
809902efec | ||
|
|
70be9894fa | ||
|
|
698ad5bac9 | ||
|
|
cd37b7533d | ||
|
|
c0cd6a1c8d | ||
|
|
f6245d1093 | ||
|
|
83c784f7c0 | ||
|
|
3d95b1a33b | ||
|
|
5c96942922 | ||
|
|
d27c83b382 |
3
.env
3
.env
@@ -1,5 +1,4 @@
|
||||
REACT_APP_CHAIN_ID="1"
|
||||
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/4bf032f2d38a4ed6bb975b80d6340847"
|
||||
REACT_APP_INFURA_KEY="4bf032f2d38a4ed6bb975b80d6340847"
|
||||
REACT_APP_WALLETCONNECT_BRIDGE_URL="https://uniswap.bridge.walletconnect.org"
|
||||
# Because we use storybook which has its own babel-loader dependency @ 8.2.2, where react-scripts uses 8.1.0
|
||||
SKIP_PREFLIGHT_CHECK=true
|
||||
@@ -1,5 +1,4 @@
|
||||
REACT_APP_CHAIN_ID="1"
|
||||
REACT_APP_NETWORK_URL="https://mainnet.infura.io/v3/099fc58e0de9451d80b18d7c74caa7c1"
|
||||
REACT_APP_INFURA_KEY="099fc58e0de9451d80b18d7c74caa7c1"
|
||||
REACT_APP_PORTIS_ID="c0e2bf01-4b08-4fd5-ac7b-8e26b58cd236"
|
||||
REACT_APP_FORTMATIC_KEY="pk_live_F937DF033A1666BF"
|
||||
REACT_APP_GOOGLE_ANALYTICS_ID="UA-128182339-4"
|
||||
|
||||
14
.github/workflows/release.yaml
vendored
14
.github/workflows/release.yaml
vendored
@@ -94,19 +94,13 @@ jobs:
|
||||
The latest release is always accessible via our alias to the Cloudflare IPFS gateway at [app.uniswap.org](https://app.uniswap.org).
|
||||
|
||||
You can also access the Uniswap Interface directly from an IPFS gateway.
|
||||
The Uniswap interface uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to store your settings.
|
||||
**Beware** that other sites you access via the _same_ IPFS gateway can read and modify your settings on the Uniswap interface without your permission.
|
||||
You can avoid this issue by using a subdomain IPFS gateway, or our alias to the latest release at [app.uniswap.org](https://app.uniswap.org).
|
||||
The preferred URLs below are safe to use to access this specific release.
|
||||
**BEWARE**: The Uniswap interface uses [`localStorage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to remember your settings, such as which tokens you have imported.
|
||||
**You should always use an IPFS gateway that enforces origin separation**, or our alias to the latest release at [app.uniswap.org](https://app.uniswap.org).
|
||||
Your Uniswap settings are never remembered across different URLs.
|
||||
|
||||
Preferred URLs:
|
||||
IPFS gateways:
|
||||
- https://${{ steps.convert_cidv0.outputs.cidv1 }}.ipfs.dweb.link/
|
||||
- https://${{ steps.convert_cidv0.outputs.cidv1 }}.ipfs.cf-ipfs.com/
|
||||
- [ipfs://${{ steps.upload.outputs.hash }}/](ipfs://${{ steps.upload.outputs.hash }}/)
|
||||
|
||||
Other IPFS gateways:
|
||||
- https://cloudflare-ipfs.com/ipfs/${{ steps.upload.outputs.hash }}/
|
||||
- https://ipfs.infura.io/ipfs/${{ steps.upload.outputs.hash }}/
|
||||
- https://ipfs.io/ipfs/${{ steps.upload.outputs.hash }}/
|
||||
|
||||
${{ needs.bump_version.outputs.changelog }}
|
||||
|
||||
15
README.md
15
README.md
@@ -27,7 +27,7 @@ or visit [app.uniswap.org](https://app.uniswap.org).
|
||||
### Install Dependencies
|
||||
|
||||
```bash
|
||||
yarn
|
||||
yarn install
|
||||
```
|
||||
|
||||
### Run
|
||||
@@ -36,19 +36,6 @@ yarn
|
||||
yarn start
|
||||
```
|
||||
|
||||
### Configuring the environment (optional)
|
||||
|
||||
To have the interface default to a different network when a wallet is not connected:
|
||||
|
||||
1. Make a copy of `.env` named `.env.local`
|
||||
2. Change `REACT_APP_NETWORK_ID` to `"{YOUR_NETWORK_ID}"`
|
||||
3. Change `REACT_APP_NETWORK_URL` to e.g. `"https://{YOUR_NETWORK_ID}.infura.io/v3/{YOUR_INFURA_KEY}"`
|
||||
|
||||
Note that the interface only works on testnets where both
|
||||
[Uniswap V2](https://uniswap.org/docs/v2/smart-contracts/factory/) and
|
||||
[multicall](https://github.com/makerdao/multicall) are deployed.
|
||||
The interface will not work on other networks.
|
||||
|
||||
## Contributions
|
||||
|
||||
**Please open all pull requests against the `main` branch.**
|
||||
|
||||
8
babel-plugin-macros.config.js
Normal file
8
babel-plugin-macros.config.js
Normal file
@@ -0,0 +1,8 @@
|
||||
const isDev = process.env.NODE_ENV !== 'production'
|
||||
|
||||
module.exports = {
|
||||
styledComponents: {
|
||||
fileName: isDev,
|
||||
displayName: isDev,
|
||||
},
|
||||
}
|
||||
@@ -51,13 +51,13 @@
|
||||
"@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.1",
|
||||
"@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",
|
||||
"@web3-react/portis-connector": "^6.0.9",
|
||||
"@web3-react/walletconnect-connector": "^6.1.1",
|
||||
"@web3-react/walletlink-connector": "^6.0.9",
|
||||
"@web3-react/walletconnect-connector": "^6.2.0",
|
||||
"@web3-react/walletlink-connector": "^6.2.0",
|
||||
"ajv": "^6.12.3",
|
||||
"cids": "^1.0.0",
|
||||
"copy-to-clipboard": "^3.2.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useCopyClipboard from '../../hooks/useCopyClipboard'
|
||||
|
||||
import { LinkStyledButton } from '../../theme'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { CheckCircle, Triangle } from 'react-feather'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
|
||||
import Badge, { BadgeVariant } from 'components/Badge'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { MouseoverTooltip } from '../../components/Tooltip'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import React from 'react'
|
||||
import {
|
||||
ButtonConfirmed,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { darken } from 'polished'
|
||||
|
||||
import { RowBetween } from '../Row'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { Box } from 'rebass/styled-components'
|
||||
|
||||
const Card = styled(Box)<{ width?: string; padding?: string; border?: string; borderRadius?: string }>`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
const Column = styled.div`
|
||||
display: flex;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Pair } from '@uniswap/v2-sdk'
|
||||
import { Currency, CurrencyAmount, Percent, Token } from '@uniswap/sdk-core'
|
||||
import React, { useState, useCallback } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { darken } from 'polished'
|
||||
import { useCurrencyBalance } from '../../state/wallet/hooks'
|
||||
import CurrencySearchModal from '../SearchModal/CurrencySearchModal'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ChainId, Currency } from '@uniswap/sdk-core'
|
||||
import React, { useMemo } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import EthereumLogo from '../../assets/images/ethereum-logo.png'
|
||||
import useHttpLocations from '../../hooks/useHttpLocations'
|
||||
import { WrappedTokenInfo } from '../../state/lists/wrappedTokenInfo'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Currency } from '@uniswap/sdk-core'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import CurrencyLogo from '../CurrencyLogo'
|
||||
|
||||
const Wrapper = styled.div<{ margin: boolean; sizeraw: number }>`
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { ErrorInfo } from 'react'
|
||||
import store, { AppState } from '../../state'
|
||||
import { ExternalLink, ThemedBackground, TYPE } from '../../theme'
|
||||
import { AutoColumn } from '../Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import ReactGA from 'react-ga'
|
||||
import { getUserAgent } from '../../utils/getUserAgent'
|
||||
import { AutoRow } from '../Row'
|
||||
|
||||
@@ -6,7 +6,7 @@ import { DynamicSection } from 'pages/AddLiquidity/styled'
|
||||
import { TYPE } from 'theme'
|
||||
import { RowBetween } from 'components/Row'
|
||||
import { ButtonRadioChecked } from 'components/Button'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
const ResponsiveText = styled(TYPE.label)`
|
||||
${({ theme }) => theme.mediaWidth.upToSmall`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { AlertTriangle, X } from 'react-feather'
|
||||
import { useURLWarningToggle, useURLWarningVisible } from '../../state/user/hooks'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ChainId, CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import React, { useMemo } from 'react'
|
||||
import { X } from 'react-feather'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import tokenLogo from '../../assets/images/token-logo.png'
|
||||
import { UNI } from '../../constants'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
|
||||
@@ -6,7 +6,7 @@ import { NavLink } from 'react-router-dom'
|
||||
import { darken } from 'polished'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Moon, Sun } from 'react-feather'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import Logo from '../../assets/svg/logo.svg'
|
||||
import LogoDark from '../../assets/svg/logo_white.svg'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Tooltip from 'components/Tooltip'
|
||||
import React, { useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
const TextWrapper = styled.span<{ margin: boolean; link?: boolean; fontSize?: string; adjustSize?: boolean }>`
|
||||
cursor: auto;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import Jazzicon from 'jazzicon'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import React from 'react'
|
||||
// import Row, { RowFixed } from 'components/Row'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import Component, { LineChartProps } from './'
|
||||
import { dummyData } from './data'
|
||||
// import { AutoColumn } from 'components/Column'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createChart, IChartApi } from 'lightweight-charts'
|
||||
import { darken } from 'polished'
|
||||
import { RowBetween } from 'components/Row'
|
||||
import Card from '../Card'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useTheme from 'hooks/useTheme'
|
||||
|
||||
const Wrapper = styled(Card)`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useHttpLocations from '../../hooks/useHttpLocations'
|
||||
|
||||
import Logo from '../Logo'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import Component from './index'
|
||||
|
||||
const Wrapper = styled.div`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { darken } from 'polished'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { NavLink, Link as HistoryLink } from 'react-router-dom'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { escapeRegExp } from '../../utils'
|
||||
|
||||
const StyledInput = styled.input<{ error?: boolean; fontSize?: string; align?: string }>`
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Placement } from '@popperjs/core'
|
||||
import { transparentize } from 'polished'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { usePopper } from 'react-popper'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useInterval from '../../hooks/useInterval'
|
||||
import Portal from '@reach/portal'
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import React, { useCallback, useMemo } from 'react'
|
||||
import ReactGA from 'react-ga'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { AppDispatch } from '../../state'
|
||||
import { useRemovePopup } from '../../state/application/hooks'
|
||||
import { acceptListUpdate } from '../../state/lists/actions'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useActivePopups } from '../../state/application/hooks'
|
||||
import { AutoColumn } from '../Column'
|
||||
import PopupItem from './PopupItem'
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react'
|
||||
import { Token } from '@uniswap/sdk-core'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { unwrappedToken } from '../../utils/wrappedCurrency'
|
||||
import { ButtonEmpty } from '../Button'
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Pair } from '@uniswap/v2-sdk'
|
||||
import { ChevronDown, ChevronUp } from 'react-feather'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
|
||||
@@ -6,7 +6,7 @@ import React, { useState } from 'react'
|
||||
import { ChevronDown, ChevronUp } from 'react-feather'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useTotalSupply } from '../../hooks/useTotalSupply'
|
||||
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import PositionListItem from 'components/PositionListItem'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { MEDIA_WIDTHS } from 'theme'
|
||||
import { PositionDetails } from 'types/position'
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import DoubleCurrencyLogo from 'components/DoubleLogo'
|
||||
import { usePool } from 'hooks/usePools'
|
||||
import { useToken } from 'hooks/Tokens'
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { HideSmall, MEDIA_WIDTHS, SmallOnly } from 'theme'
|
||||
import { PositionDetails } from 'types/position'
|
||||
import { WETH9, Price, Token, Percent } from '@uniswap/sdk-core'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useContext } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { ThemeContext } from 'styled-components'
|
||||
import { TYPE } from '../../theme'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import Tooltip from '../Tooltip'
|
||||
|
||||
const QuestionWrapper = styled.div`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { Box } from 'rebass/styled-components'
|
||||
|
||||
const Row = styled(Box)<{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Text } from 'rebass'
|
||||
import { ChainId, Currency, currencyEquals, Token, ETHER } from '@uniswap/sdk-core'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { SUGGESTED_BASES } from '../../constants'
|
||||
import { AutoColumn } from '../Column'
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Currency, CurrencyAmount, currencyEquals, Token } from '@uniswap/sdk-co
|
||||
import React, { CSSProperties, MutableRefObject, useCallback, useMemo } from 'react'
|
||||
import { FixedSizeList } from 'react-window'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
import { useCombinedActiveList } from '../../state/lists/hooks'
|
||||
import { WrappedTokenInfo } from '../../state/lists/wrappedTokenInfo'
|
||||
|
||||
@@ -16,7 +16,7 @@ import { filterTokens, useSortedTokensByQuery } from './filtering'
|
||||
import { useTokenComparator } from './sorting'
|
||||
import { PaddedColumn, SearchInput, Separator } from './styleds'
|
||||
import AutoSizer from 'react-virtualized-auto-sizer'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import useToggle from 'hooks/useToggle'
|
||||
import { useOnClickOutside } from 'hooks/useOnClickOutside'
|
||||
import useTheme from 'hooks/useTheme'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useCallback } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import ReactGA from 'react-ga'
|
||||
import { TYPE, CloseIcon } from 'theme'
|
||||
import Card from 'components/Card'
|
||||
|
||||
@@ -7,7 +7,7 @@ import { TYPE } from 'theme'
|
||||
import ListLogo from 'components/ListLogo'
|
||||
import useTheme from 'hooks/useTheme'
|
||||
import { ButtonPrimary } from 'components/Button'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useIsUserAddedToken, useIsTokenActive } from 'hooks/Tokens'
|
||||
import { CheckCircle } from 'react-feather'
|
||||
import { WrappedTokenInfo } from '../../state/lists/wrappedTokenInfo'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { TokenList } from '@uniswap/token-lists/dist/types'
|
||||
import React from 'react'
|
||||
import { Token, Currency } from '@uniswap/sdk-core'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { TYPE, CloseIcon } from 'theme'
|
||||
import Card from 'components/Card'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
|
||||
@@ -4,7 +4,7 @@ import { RowBetween } from 'components/Row'
|
||||
import { ArrowLeft } from 'react-feather'
|
||||
import { Text } from 'rebass'
|
||||
import { CloseIcon } from 'theme'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { Token } from '@uniswap/sdk-core'
|
||||
import { ManageLists } from './ManageLists'
|
||||
import ManageTokens from './ManageTokens'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Settings, CheckCircle } from 'react-feather'
|
||||
import ReactGA from 'react-ga'
|
||||
import { usePopper } from 'react-popper'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useFetchListCallback } from '../../hooks/useFetchListCallback'
|
||||
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
|
||||
import { TokenList } from '@uniswap/token-lists'
|
||||
|
||||
@@ -4,7 +4,7 @@ import { PaddedColumn, Separator, SearchInput } from './styleds'
|
||||
import Row, { RowBetween, RowFixed } from 'components/Row'
|
||||
import { TYPE, ExternalLinkIcon, TrashIcon, ButtonText, ExternalLink } from 'theme'
|
||||
import { useToken } from 'hooks/Tokens'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useUserAddedTokens, useRemoveUserAddedToken } from 'state/user/hooks'
|
||||
import { Token } from '@uniswap/sdk-core'
|
||||
import CurrencyLogo from 'components/CurrencyLogo'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { RowFixed } from '../Row'
|
||||
|
||||
export const FilterWrapper = styled(RowFixed)`
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { RowBetween, RowFixed } from '../Row'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
const StyledRangeInput = styled.input<{ size: number }>`
|
||||
-webkit-appearance: none; /* Hides the slider so that custom slider can be made */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { readableColor } from 'polished'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { colors } from 'theme'
|
||||
|
||||
const Swatch = styled.div`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { TYPE } from '../../theme'
|
||||
|
||||
const Wrapper = styled.button<{ isActive?: boolean; activeElement?: boolean }>`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Story } from '@storybook/react/types-6-0'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import React, { useState } from 'react'
|
||||
import MultiToggle from './MultiToggle'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
export const ToggleWrapper = styled.button<{ width?: string }>`
|
||||
display: flex;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
const ToggleElement = styled.span<{ isActive?: boolean; isOnSwitch?: boolean }>`
|
||||
padding: 0.25rem 0.5rem;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import Popover, { PopoverProps } from '../Popover'
|
||||
|
||||
const TooltipContainer = styled.div`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { ExternalLink } from '../../theme'
|
||||
|
||||
const InfoCard = styled.button<{ active?: boolean }>`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AbstractConnector } from '@web3-react/abstract-connector'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import Option from './Option'
|
||||
import { SUPPORTED_WALLETS } from '../../constants'
|
||||
import { injected } from '../../connectors'
|
||||
|
||||
@@ -5,7 +5,7 @@ import { AutoRow } from 'components/Row'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { isMobile } from 'react-device-detect'
|
||||
import ReactGA from 'react-ga'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import MetamaskIcon from '../../assets/images/metamask.png'
|
||||
import { ReactComponent as Close } from '../../assets/images/x.svg'
|
||||
import { fortmatic, injected, portis } from '../../connectors'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { network } from '../../connectors'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from 'react'
|
||||
import Modal from '../Modal'
|
||||
import { AutoColumn, ColumnCenter } from '../Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { DataCard, CardSection, Break } from '../earn/styled'
|
||||
import { RowBetween } from '../Row'
|
||||
import { TYPE, ExternalLink, CloseIcon, CustomLightSpinner, UniTokenAnimated } from '../../theme'
|
||||
|
||||
@@ -3,7 +3,7 @@ import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import { isAddress } from 'ethers/lib/utils'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import Circle from '../../assets/images/blue-loader.svg'
|
||||
import tokenLogo from '../../assets/images/token-logo.png'
|
||||
import { useActiveWeb3React } from '../../hooks'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from 'react'
|
||||
import Modal from '../Modal'
|
||||
import { AutoColumn } from '../Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { RowBetween } from '../Row'
|
||||
import { TYPE, CloseIcon } from '../../theme'
|
||||
import { ButtonError } from '../Button'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { AutoColumn } from '../Column'
|
||||
import { RowBetween } from '../Row'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { TYPE, StyledInternalLink } from '../../theme'
|
||||
import DoubleCurrencyLogo from '../DoubleLogo'
|
||||
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useV2LiquidityTokenPermit } from '../../hooks/useERC20Permit'
|
||||
import useTransactionDeadline from '../../hooks/useTransactionDeadline'
|
||||
import Modal from '../Modal'
|
||||
import { AutoColumn } from '../Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { RowBetween } from '../Row'
|
||||
import { TYPE, CloseIcon } from '../../theme'
|
||||
import { ButtonConfirmed, ButtonError } from '../Button'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, { useState } from 'react'
|
||||
import Modal from '../Modal'
|
||||
import { AutoColumn } from '../Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { RowBetween } from '../Row'
|
||||
import { TYPE, CloseIcon } from '../../theme'
|
||||
import { ButtonError } from '../Button'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { AutoColumn } from '../Column'
|
||||
|
||||
import uImage from '../../assets/images/big_unicorn.png'
|
||||
|
||||
@@ -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 received' : 'Maximum sent'}
|
||||
</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>
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { useLastTruthy } from '../../hooks/useLast'
|
||||
import { AdvancedSwapDetails, AdvancedSwapDetailsProps } from './AdvancedSwapDetails'
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import useParsedQueryString from '../../hooks/useParsedQueryString'
|
||||
import { DEFAULT_VERSION, Version } from '../../hooks/useToggledVersion'
|
||||
import { HideSmall, TYPE, SmallOnly } from '../../theme'
|
||||
import { ButtonPrimary } from '../Button'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { Zap } from 'react-feather'
|
||||
|
||||
const ResponsiveButton = styled(ButtonPrimary)`
|
||||
|
||||
@@ -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(
|
||||
() =>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import SettingsTab from '../Settings'
|
||||
import { Percent } from '@uniswap/sdk-core'
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState } from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { TYPE, CloseIcon, ExternalLink } from 'theme'
|
||||
import { ButtonEmpty } from 'components/Button'
|
||||
import Modal from 'components/Modal'
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useState } from 'react'
|
||||
|
||||
import Modal from '../Modal'
|
||||
import { AutoColumn } from '../Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { RowBetween } from '../Row'
|
||||
import { TYPE } from '../../theme'
|
||||
import { X } from 'react-feather'
|
||||
|
||||
@@ -1,40 +1,53 @@
|
||||
import { Web3Provider } from '@ethersproject/providers'
|
||||
import { ChainId } from '@uniswap/sdk-core'
|
||||
import { InjectedConnector } from '@web3-react/injected-connector'
|
||||
import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
|
||||
import { WalletLinkConnector } from '@web3-react/walletlink-connector'
|
||||
import { PortisConnector } from '@web3-react/portis-connector'
|
||||
import getLibrary from '../utils/getLibrary'
|
||||
|
||||
import { FortmaticConnector } from './Fortmatic'
|
||||
import { NetworkConnector } from './NetworkConnector'
|
||||
import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
|
||||
|
||||
const NETWORK_URL = process.env.REACT_APP_NETWORK_URL
|
||||
const INFURA_KEY = process.env.REACT_APP_INFURA_KEY
|
||||
const FORMATIC_KEY = process.env.REACT_APP_FORTMATIC_KEY
|
||||
const PORTIS_ID = process.env.REACT_APP_PORTIS_ID
|
||||
const WALLETCONNECT_BRIDGE_URL = process.env.REACT_APP_WALLETCONNECT_BRIDGE_URL
|
||||
|
||||
export const NETWORK_CHAIN_ID: number = parseInt(process.env.REACT_APP_CHAIN_ID ?? '1')
|
||||
|
||||
if (typeof NETWORK_URL === 'undefined') {
|
||||
throw new Error(`REACT_APP_NETWORK_URL must be a defined environment variable`)
|
||||
if (typeof INFURA_KEY === 'undefined') {
|
||||
throw new Error(`REACT_APP_INFURA_KEY must be a defined environment variable`)
|
||||
}
|
||||
|
||||
const NETWORK_URLS: {
|
||||
[chainId in ChainId]: string
|
||||
} = {
|
||||
[ChainId.MAINNET]: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
|
||||
[ChainId.RINKEBY]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
|
||||
[ChainId.ROPSTEN]: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
|
||||
[ChainId.GÖRLI]: `https://goerli.infura.io/v3/${INFURA_KEY}`,
|
||||
[ChainId.KOVAN]: `https://kovan.infura.io/v3/${INFURA_KEY}`,
|
||||
}
|
||||
|
||||
const SUPPORTED_CHAIN_IDS = [ChainId.MAINNET, ChainId.RINKEBY, ChainId.ROPSTEN, ChainId.KOVAN, ChainId.GÖRLI]
|
||||
|
||||
export const network = new NetworkConnector({
|
||||
urls: { [NETWORK_CHAIN_ID]: NETWORK_URL },
|
||||
urls: NETWORK_URLS,
|
||||
defaultChainId: ChainId.MAINNET,
|
||||
})
|
||||
|
||||
let networkLibrary: Web3Provider | undefined
|
||||
export function getNetworkLibrary(): Web3Provider {
|
||||
return (networkLibrary = networkLibrary ?? new Web3Provider(network.provider as any))
|
||||
return (networkLibrary = networkLibrary ?? getLibrary(network.provider))
|
||||
}
|
||||
|
||||
export const injected = new InjectedConnector({
|
||||
supportedChainIds: [1, 3, 4, 5, 42],
|
||||
supportedChainIds: SUPPORTED_CHAIN_IDS,
|
||||
})
|
||||
|
||||
// mainnet only
|
||||
export const walletconnect = new WalletConnectConnector({
|
||||
rpc: { 1: NETWORK_URL },
|
||||
supportedChainIds: SUPPORTED_CHAIN_IDS,
|
||||
infuraId: INFURA_KEY, // obviously a hack
|
||||
bridge: WALLETCONNECT_BRIDGE_URL,
|
||||
qrcode: true,
|
||||
pollingInterval: 15000,
|
||||
@@ -54,7 +67,7 @@ export const portis = new PortisConnector({
|
||||
|
||||
// mainnet only
|
||||
export const walletlink = new WalletLinkConnector({
|
||||
url: NETWORK_URL,
|
||||
url: NETWORK_URLS[ChainId.MAINNET],
|
||||
appName: 'Uniswap',
|
||||
appLogoUrl: UNISWAP_LOGO_URL,
|
||||
})
|
||||
|
||||
22
src/hooks/useApeModeQueryParamReader.ts
Normal file
22
src/hooks/useApeModeQueryParamReader.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { useEffect } from 'react'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { AppDispatch } from 'state'
|
||||
import { updateUserExpertMode } from '../state/user/actions'
|
||||
import useParsedQueryString from './useParsedQueryString'
|
||||
|
||||
export default function ApeModeQueryParamReader(): null {
|
||||
useApeModeQueryParamReader()
|
||||
return null
|
||||
}
|
||||
|
||||
function useApeModeQueryParamReader() {
|
||||
const dispatch = useDispatch<AppDispatch>()
|
||||
const { ape } = useParsedQueryString()
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof ape !== 'string') return
|
||||
if (ape === '' || ape.toLowerCase() === 'true') {
|
||||
dispatch(updateUserExpertMode({ userExpertMode: true }))
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { ChainId } from '@uniswap/sdk-core'
|
||||
import { TokenList } from '@uniswap/token-lists'
|
||||
import { useCallback } from 'react'
|
||||
import { useDispatch } from 'react-redux'
|
||||
import { getNetworkLibrary, NETWORK_CHAIN_ID } from '../connectors'
|
||||
import { getNetworkLibrary } from '../connectors'
|
||||
import { AppDispatch } from '../state'
|
||||
import { fetchTokenList } from '../state/lists/actions'
|
||||
import getTokenList from '../utils/getTokenList'
|
||||
@@ -15,13 +15,12 @@ export function useFetchListCallback(): (listUrl: string, sendDispatch?: boolean
|
||||
const dispatch = useDispatch<AppDispatch>()
|
||||
|
||||
const ensResolver = useCallback(
|
||||
(ensName: string) => {
|
||||
async (ensName: string) => {
|
||||
if (!library || chainId !== ChainId.MAINNET) {
|
||||
if (NETWORK_CHAIN_ID === ChainId.MAINNET) {
|
||||
const networkLibrary = getNetworkLibrary()
|
||||
if (networkLibrary) {
|
||||
return resolveENSContentHash(ensName, networkLibrary)
|
||||
}
|
||||
const networkLibrary = getNetworkLibrary()
|
||||
const network = await networkLibrary.getNetwork()
|
||||
if (networkLibrary && network.chainId === ChainId.MAINNET) {
|
||||
return resolveENSContentHash(ensName, networkLibrary)
|
||||
}
|
||||
throw new Error('Could not construct mainnet ENS resolver')
|
||||
}
|
||||
|
||||
@@ -133,23 +133,40 @@ function useSwapCallArguments(
|
||||
}, [account, allowedSlippage, chainId, deadline, library, recipient, routerContract, signatureData, trade])
|
||||
}
|
||||
|
||||
export function swapErrorToUserReadableMessage(error: { reason: string }): string {
|
||||
switch (error.reason) {
|
||||
/**
|
||||
* This is hacking out the revert reason from the ethers provider thrown error however it can.
|
||||
* This object seems to be undocumented by ethers.
|
||||
* @param error an error from the ethers provider
|
||||
*/
|
||||
export function swapErrorToUserReadableMessage(error: any): string {
|
||||
let reason: string | undefined
|
||||
while (Boolean(error)) {
|
||||
reason = error.reason ?? error.message ?? reason
|
||||
error = error.error ?? error.data?.originalError
|
||||
}
|
||||
|
||||
if (reason?.indexOf('execution reverted: ') === 0) reason = reason.substr('execution reverted: '.length)
|
||||
|
||||
switch (reason) {
|
||||
case 'UniswapV2Router: EXPIRED':
|
||||
return 'The transaction could not be sent because the deadline has passed. Please check that your transaction deadline is not too low.'
|
||||
case 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT':
|
||||
case 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT':
|
||||
return 'This transaction will not succeed either due to price movement or fee on transfer. Try increasing your slippage tolerance.'
|
||||
case 'TransferHelper: TRANSFER_FROM_FAILED':
|
||||
return 'The input token cannot be transferred. There may be an issue with the input token.'
|
||||
case 'UniswapV2: TRANSFER_FAILED':
|
||||
return 'The token could not be transferred. There may be an issue with the token.'
|
||||
return 'The output token cannot be transferred. There may be an issue with the output token.'
|
||||
case 'UniswapV2: K':
|
||||
return 'The Uniswap invariant x*y=k was not satisfied by the swap. This usually means one of the tokens you are swapping incorporates custom behavior on transfer.'
|
||||
case 'Too little received':
|
||||
case 'Too much requested':
|
||||
case 'STF':
|
||||
return 'This transaction will not succeed due to price movement. Try increasing your slippage tolerance.'
|
||||
return 'This transaction will not succeed due to price movement. Try increasing your slippage tolerance. Note fee on transfer and rebase tokens are incompatible with Uniswap V3.'
|
||||
case 'TF':
|
||||
return 'The output token cannot be transferred. There may be an issue with the output token. Note fee on transfer and rebase tokens are incompatible with Uniswap V3.'
|
||||
default:
|
||||
return 'Unknown error. Please join the Discord to get help.'
|
||||
return `Unknown error${reason ? `: "${reason}"` : ''}. Please join the Discord to get help.`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,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 =
|
||||
@@ -289,13 +306,11 @@ export function useSwapCallback(
|
||||
// otherwise, the error was unexpected and we need to convey that
|
||||
console.error(`Swap failed`, error, address, calldata, value)
|
||||
|
||||
throw new Error(
|
||||
`Swap failed: ${'reason' in error ? swapErrorToUserReadableMessage(error) : error.message}`
|
||||
)
|
||||
throw new Error(`Swap failed: ${swapErrorToUserReadableMessage(error)}`)
|
||||
}
|
||||
})
|
||||
},
|
||||
error: null,
|
||||
}
|
||||
}, [trade, library, account, chainId, recipient, recipientAddressOrName, swapCalls, allowedSlippage, addTransaction])
|
||||
}, [trade, library, account, chainId, recipient, recipientAddressOrName, swapCalls, addTransaction])
|
||||
}
|
||||
|
||||
@@ -56,7 +56,9 @@ export default function useUSDCPrice(currency?: Currency): Price<Currency, Token
|
||||
|
||||
const ethPairETHAmount = ethPair?.reserveOf(weth)
|
||||
const ethPairETHUSDCValue: JSBI =
|
||||
ethPairETHAmount && usdcEthPair ? usdcEthPair.priceOf(weth).quote(ethPairETHAmount).quotient : JSBI.BigInt(0)
|
||||
ethPairETHAmount?.greaterThan(0) && usdcEthPair?.reserveOf(weth)?.greaterThan(0)
|
||||
? usdcEthPair.priceOf(weth).quote(ethPairETHAmount).quotient
|
||||
: JSBI.BigInt(0)
|
||||
|
||||
// all other tokens
|
||||
// first try the usdc pair
|
||||
@@ -81,6 +83,10 @@ export function useUSDCValue(currencyAmount: CurrencyAmount<Currency> | undefine
|
||||
|
||||
return useMemo(() => {
|
||||
if (!price || !currencyAmount) return null
|
||||
return price.quote(currencyAmount)
|
||||
try {
|
||||
return price.quote(currencyAmount)
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}, [currencyAmount, price])
|
||||
}
|
||||
|
||||
@@ -3,16 +3,18 @@ import { useEffect, useState } from 'react'
|
||||
import { useV3NFTPositionManagerContract } from './useContract'
|
||||
import { BigNumber } from '@ethersproject/bignumber'
|
||||
import { Pool } from '@uniswap/v3-sdk'
|
||||
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
|
||||
import { CurrencyAmount, Token, currencyEquals, ETHER, Ether } from '@uniswap/sdk-core'
|
||||
import { useBlockNumber } from 'state/application/hooks'
|
||||
import { unwrappedToken } from 'utils/wrappedCurrency'
|
||||
|
||||
const MAX_UINT128 = BigNumber.from(2).pow(128).sub(1)
|
||||
|
||||
// compute current + counterfactual fees for a v3 position
|
||||
export function useV3PositionFees(
|
||||
pool?: Pool,
|
||||
tokenId?: BigNumber
|
||||
): [CurrencyAmount<Token>, CurrencyAmount<Token>] | [undefined, undefined] {
|
||||
tokenId?: BigNumber,
|
||||
asWETH = false
|
||||
): [CurrencyAmount<Token | Ether>, CurrencyAmount<Token | Ether>] | [undefined, undefined] {
|
||||
const positionManager = useV3NFTPositionManagerContract(false)
|
||||
const owner = useSingleCallResult(tokenId ? positionManager : null, 'ownerOf', [tokenId]).result?.[0]
|
||||
|
||||
@@ -43,8 +45,12 @@ export function useV3PositionFees(
|
||||
|
||||
if (pool && amounts) {
|
||||
return [
|
||||
CurrencyAmount.fromRawAmount(pool.token0, amounts[0].toString()),
|
||||
CurrencyAmount.fromRawAmount(pool.token1, amounts[1].toString()),
|
||||
!asWETH && currencyEquals(unwrappedToken(pool.token0), ETHER)
|
||||
? CurrencyAmount.ether(amounts[0].toString())
|
||||
: CurrencyAmount.fromRawAmount(pool.token0, amounts[0].toString()),
|
||||
!asWETH && currencyEquals(unwrappedToken(pool.token1), ETHER)
|
||||
? CurrencyAmount.ether(amounts[1].toString())
|
||||
: CurrencyAmount.fromRawAmount(pool.token1, amounts[1].toString()),
|
||||
]
|
||||
} else {
|
||||
return [undefined, undefined]
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react'
|
||||
import { Field } from '../../state/mint/v3/actions'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import Card from 'components/Card'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { Currency, CurrencyAmount, Price } from '@uniswap/sdk-core'
|
||||
import { Position } from '@uniswap/v3-sdk'
|
||||
import { PositionPreview } from 'components/PositionPreview'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import CurrencyInputPanel from 'components/CurrencyInputPanel'
|
||||
import { DarkGreyCard } from 'components/Card'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { Suspense } from 'react'
|
||||
import { Route, Switch } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import GoogleAnalyticsReporter from '../components/analytics/GoogleAnalyticsReporter'
|
||||
import AddressClaimModal from '../components/claim/AddressClaimModal'
|
||||
import Header from '../components/Header'
|
||||
@@ -29,6 +29,7 @@ import { RedirectDuplicateTokenIdsV2 } from './AddLiquidityV2/redirects'
|
||||
import { PositionPage } from './Pool/PositionPage'
|
||||
import AddLiquidity from './AddLiquidity'
|
||||
import { ThemedBackground } from '../theme'
|
||||
import ApeModeQueryParamReader from 'hooks/useApeModeQueryParamReader'
|
||||
|
||||
const AppWrapper = styled.div`
|
||||
display: flex;
|
||||
@@ -76,6 +77,7 @@ export default function App() {
|
||||
<Suspense fallback={null}>
|
||||
<Route component={GoogleAnalyticsReporter} />
|
||||
<Route component={DarkModeQueryParamReader} />
|
||||
<Route component={ApeModeQueryParamReader} />
|
||||
<AppWrapper>
|
||||
<HeaderWrapper>
|
||||
<Header />
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
export const BodyWrapper = styled.div<{ margin?: string }>`
|
||||
position: relative;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import { AutoColumn } from '../../components/Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { Link } from 'react-router-dom'
|
||||
import JSBI from 'jsbi'
|
||||
import { Token, CurrencyAmount } from '@uniswap/sdk-core'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import JSBI from 'jsbi'
|
||||
import React from 'react'
|
||||
import { AutoColumn } from '../../components/Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { STAKING_REWARDS_INFO, useStakingInfo } from '../../state/stake/hooks'
|
||||
import { TYPE, ExternalLink } from '../../theme'
|
||||
import PoolCard from '../../components/earn/PoolCard'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { TYPE } from 'theme'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { ExternalLink } from '../../theme'
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import React, { SyntheticEvent, useCallback, useMemo, useRef, useState } from 'react'
|
||||
import React, { useCallback, useMemo, useRef, useState } from 'react'
|
||||
import { NonfungiblePositionManager, Pool, Position } from '@uniswap/v3-sdk'
|
||||
|
||||
import { PoolState, usePool } from 'hooks/usePools'
|
||||
import { useToken } from 'hooks/Tokens'
|
||||
import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
|
||||
import { Link, RouteComponentProps } from 'react-router-dom'
|
||||
import { unwrappedToken } from 'utils/wrappedCurrency'
|
||||
import { unwrappedToken, wrappedCurrencyAmount } from 'utils/wrappedCurrency'
|
||||
import { usePositionTokenURI } from '../../hooks/usePositionTokenURI'
|
||||
import { LoadingRows } from './styleds'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { AutoColumn } from 'components/Column'
|
||||
import { RowBetween, RowFixed } from 'components/Row'
|
||||
import DoubleCurrencyLogo from 'components/DoubleLogo'
|
||||
@@ -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 { Token, WETH9, Currency, CurrencyAmount, Percent, Fraction, Price, currencyEquals } from '@uniswap/sdk-core'
|
||||
import { Token, Currency, CurrencyAmount, Percent, Fraction, Price, Ether } from '@uniswap/sdk-core'
|
||||
import { useActiveWeb3React } from 'hooks'
|
||||
import { useV3NFTPositionManagerContract } from 'hooks/useContract'
|
||||
import { useIsTransactionPending, useTransactionAdder } from 'state/transactions/hooks'
|
||||
@@ -38,6 +38,7 @@ import { useSingleCallResult } from 'state/multicall/hooks'
|
||||
import RangeBadge from '../../components/Badge/RangeBadge'
|
||||
import useUSDCPrice from 'hooks/useUSDCPrice'
|
||||
import Loader from 'components/Loader'
|
||||
import Toggle from 'components/Toggle'
|
||||
|
||||
const PageWrapper = styled.div`
|
||||
min-width: 800px;
|
||||
@@ -200,20 +201,11 @@ function getRatio(
|
||||
}
|
||||
}
|
||||
|
||||
function NFT({ image, height: targetHeight }: { image: string; height: number }) {
|
||||
const [animate, setAnimate] = useState(false)
|
||||
|
||||
const canvasRef = useRef<HTMLCanvasElement>()
|
||||
const imageRef = useRef<HTMLImageElement>()
|
||||
|
||||
const getSnapshot = (src: HTMLImageElement) => {
|
||||
if (!canvasRef.current) return
|
||||
|
||||
const { current: canvas } = canvasRef
|
||||
const context = canvas.getContext('2d')
|
||||
|
||||
if (!context) return
|
||||
// snapshots a src img into a canvas
|
||||
function getSnapshot(src: HTMLImageElement, canvas: HTMLCanvasElement, targetHeight: number) {
|
||||
const context = canvas.getContext('2d')
|
||||
|
||||
if (context) {
|
||||
let { width, height } = src
|
||||
|
||||
// src may be hidden and not have the target dimensions
|
||||
@@ -231,15 +223,39 @@ function NFT({ image, height: targetHeight }: { image: string; height: number })
|
||||
context.clearRect(0, 0, width, height)
|
||||
context.drawImage(src, 0, 0, width, height)
|
||||
}
|
||||
}
|
||||
|
||||
const onLoad = (e: SyntheticEvent<HTMLImageElement>) => {
|
||||
getSnapshot(e.target as HTMLImageElement)
|
||||
}
|
||||
function NFT({ image, height: targetHeight }: { image: string; height: number }) {
|
||||
const [animate, setAnimate] = useState(false)
|
||||
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null)
|
||||
const imageRef = useRef<HTMLImageElement>(null)
|
||||
|
||||
return (
|
||||
<NFTGrid onMouseEnter={() => setAnimate(true)} onMouseLeave={() => setAnimate(false)}>
|
||||
<NFTCanvas ref={canvasRef as any} />
|
||||
<NFTImage src={image} hidden={!animate} onLoad={onLoad} ref={imageRef as any} />
|
||||
<NFTGrid
|
||||
onMouseEnter={() => {
|
||||
setAnimate(true)
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
// snapshot the current frame so the transition to the canvas is smooth
|
||||
if (imageRef.current && canvasRef.current) {
|
||||
getSnapshot(imageRef.current, canvasRef.current, targetHeight)
|
||||
}
|
||||
setAnimate(false)
|
||||
}}
|
||||
>
|
||||
<NFTCanvas ref={canvasRef} />
|
||||
<NFTImage
|
||||
ref={imageRef}
|
||||
src={image}
|
||||
hidden={!animate}
|
||||
onLoad={() => {
|
||||
// snapshot for the canvas
|
||||
if (imageRef.current && canvasRef.current) {
|
||||
getSnapshot(imageRef.current, canvasRef.current, targetHeight)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</NFTGrid>
|
||||
)
|
||||
}
|
||||
@@ -269,8 +285,11 @@ export function PositionPage({
|
||||
const currency0 = token0 ? unwrappedToken(token0) : undefined
|
||||
const currency1 = token1 ? unwrappedToken(token1) : undefined
|
||||
|
||||
// flag for receiving WETH
|
||||
const [receiveWETH, setReceiveWETH] = useState(false)
|
||||
|
||||
// construct Position from details returned
|
||||
const [poolState, pool] = usePool(currency0 ?? undefined, currency1 ?? undefined, feeAmount)
|
||||
const [poolState, pool] = usePool(token0 ?? undefined, token1 ?? undefined, feeAmount)
|
||||
const position = useMemo(() => {
|
||||
if (pool && liquidity && typeof tickLower === 'number' && typeof tickUpper === 'number') {
|
||||
return new Position({ pool, liquidity: liquidity.toString(), tickLower, tickUpper })
|
||||
@@ -304,7 +323,7 @@ export function PositionPage({
|
||||
}, [inverted, pool, priceLower, priceUpper])
|
||||
|
||||
// fees
|
||||
const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, positionDetails?.tokenId)
|
||||
const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, positionDetails?.tokenId, receiveWETH)
|
||||
|
||||
const [collecting, setCollecting] = useState<boolean>(false)
|
||||
const [collectMigrationHash, setCollectMigrationHash] = useState<string | null>(null)
|
||||
@@ -320,12 +339,8 @@ export function PositionPage({
|
||||
|
||||
const { calldata, value } = NonfungiblePositionManager.collectCallParameters({
|
||||
tokenId: tokenId.toString(),
|
||||
expectedCurrencyOwed0: currencyEquals(feeValue0.currency, WETH9[chainId])
|
||||
? CurrencyAmount.ether(feeValue0.quotient)
|
||||
: feeValue0,
|
||||
expectedCurrencyOwed1: currencyEquals(feeValue1.currency, WETH9[chainId])
|
||||
? CurrencyAmount.ether(feeValue1.quotient)
|
||||
: feeValue1,
|
||||
expectedCurrencyOwed0: feeValue0,
|
||||
expectedCurrencyOwed1: feeValue1,
|
||||
recipient: account,
|
||||
})
|
||||
|
||||
@@ -371,15 +386,23 @@ export function PositionPage({
|
||||
const owner = useSingleCallResult(!!tokenId ? positionManager : null, 'ownerOf', [tokenId]).result?.[0]
|
||||
const ownsNFT = owner === account || positionDetails?.operator === account
|
||||
|
||||
// usdc prices always in terms of tokens
|
||||
const price0 = useUSDCPrice(token0 ?? undefined)
|
||||
const price1 = useUSDCPrice(token1 ?? undefined)
|
||||
|
||||
const fiatValueOfFees: CurrencyAmount<Token> | null = useMemo(() => {
|
||||
const fiatValueOfFees: CurrencyAmount<Token | Ether> | null = useMemo(() => {
|
||||
if (!price0 || !price1 || !feeValue0 || !feeValue1) return null
|
||||
const amount0 = price0.quote(feeValue0)
|
||||
const amount1 = price1.quote(feeValue1)
|
||||
|
||||
// we wrap because it doesn't matter, the quote returns a USDC amount
|
||||
const feeValue0Wrapped = wrappedCurrencyAmount(feeValue0, chainId)
|
||||
const feeValue1Wrapped = wrappedCurrencyAmount(feeValue1, chainId)
|
||||
|
||||
if (!feeValue0Wrapped || !feeValue1Wrapped) return null
|
||||
|
||||
const amount0 = price0.quote(feeValue0Wrapped)
|
||||
const amount1 = price1.quote(feeValue1Wrapped)
|
||||
return amount0.add(amount1)
|
||||
}, [price0, price1, feeValue0, feeValue1])
|
||||
}, [price0, price1, feeValue0, feeValue1, chainId])
|
||||
|
||||
const fiatValueOfLiquidity: CurrencyAmount<Token> | null = useMemo(() => {
|
||||
if (!price0 || !price1 || !position) return null
|
||||
@@ -388,6 +411,9 @@ export function PositionPage({
|
||||
return amount0.add(amount1)
|
||||
}, [price0, price1, position])
|
||||
|
||||
const feeValueUpper = inverted ? feeValue0 : feeValue1
|
||||
const feeValueLower = inverted ? feeValue1 : feeValue0
|
||||
|
||||
function modalHeader() {
|
||||
return (
|
||||
<AutoColumn gap={'md'} style={{ marginTop: '20px' }}>
|
||||
@@ -395,33 +421,17 @@ export function PositionPage({
|
||||
<AutoColumn gap="md">
|
||||
<RowBetween>
|
||||
<RowFixed>
|
||||
<CurrencyLogo currency={currencyQuote} size={'20px'} style={{ marginRight: '0.5rem' }} />
|
||||
<TYPE.main>
|
||||
{inverted
|
||||
? feeValue0
|
||||
? formatTokenAmount(feeValue0, 4)
|
||||
: '-'
|
||||
: feeValue1
|
||||
? formatTokenAmount(feeValue1, 4)
|
||||
: '-'}
|
||||
</TYPE.main>
|
||||
<CurrencyLogo currency={feeValueUpper?.currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
|
||||
<TYPE.main>{feeValueUpper ? formatTokenAmount(feeValueUpper, 4) : '-'}</TYPE.main>
|
||||
</RowFixed>
|
||||
<TYPE.main>{currencyQuote?.symbol}</TYPE.main>
|
||||
<TYPE.main>{feeValueUpper?.currency?.symbol}</TYPE.main>
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<RowFixed>
|
||||
<CurrencyLogo currency={currencyBase} size={'20px'} style={{ marginRight: '0.5rem' }} />
|
||||
<TYPE.main>
|
||||
{inverted
|
||||
? feeValue0
|
||||
? formatTokenAmount(feeValue1, 4)
|
||||
: '-'
|
||||
: feeValue1
|
||||
? formatTokenAmount(feeValue0, 4)
|
||||
: '-'}
|
||||
</TYPE.main>
|
||||
<CurrencyLogo currency={feeValueLower?.currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
|
||||
<TYPE.main>{feeValueLower ? formatTokenAmount(feeValueLower, 4) : '-'}</TYPE.main>
|
||||
</RowFixed>
|
||||
<TYPE.main>{currencyBase?.symbol}</TYPE.main>
|
||||
<TYPE.main>{feeValueLower?.currency?.symbol}</TYPE.main>
|
||||
</RowBetween>
|
||||
</AutoColumn>
|
||||
</LightCard>
|
||||
@@ -640,40 +650,44 @@ export function PositionPage({
|
||||
<AutoColumn gap="md">
|
||||
<RowBetween>
|
||||
<RowFixed>
|
||||
<CurrencyLogo currency={currencyQuote} size={'20px'} style={{ marginRight: '0.5rem' }} />
|
||||
<TYPE.main>{currencyQuote?.symbol}</TYPE.main>
|
||||
<CurrencyLogo
|
||||
currency={feeValueUpper?.currency}
|
||||
size={'20px'}
|
||||
style={{ marginRight: '0.5rem' }}
|
||||
/>
|
||||
<TYPE.main>{feeValueUpper?.currency?.symbol}</TYPE.main>
|
||||
</RowFixed>
|
||||
<RowFixed>
|
||||
<TYPE.main>
|
||||
{inverted
|
||||
? feeValue0
|
||||
? formatTokenAmount(feeValue0, 4)
|
||||
: '-'
|
||||
: feeValue1
|
||||
? formatTokenAmount(feeValue1, 4)
|
||||
: '-'}
|
||||
</TYPE.main>
|
||||
<TYPE.main>{feeValueUpper ? formatTokenAmount(feeValueUpper, 4) : '-'}</TYPE.main>
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<RowFixed>
|
||||
<CurrencyLogo currency={currencyBase} size={'20px'} style={{ marginRight: '0.5rem' }} />
|
||||
<TYPE.main>{currencyBase?.symbol}</TYPE.main>
|
||||
<CurrencyLogo
|
||||
currency={feeValueLower?.currency}
|
||||
size={'20px'}
|
||||
style={{ marginRight: '0.5rem' }}
|
||||
/>
|
||||
<TYPE.main>{feeValueLower?.currency?.symbol}</TYPE.main>
|
||||
</RowFixed>
|
||||
<RowFixed>
|
||||
<TYPE.main>
|
||||
{inverted
|
||||
? feeValue0
|
||||
? formatTokenAmount(feeValue1, 4)
|
||||
: '-'
|
||||
: feeValue1
|
||||
? formatTokenAmount(feeValue0, 4)
|
||||
: '-'}
|
||||
</TYPE.main>
|
||||
<TYPE.main>{feeValueLower ? formatTokenAmount(feeValueLower, 4) : '-'}</TYPE.main>
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
</AutoColumn>
|
||||
</LightCard>
|
||||
{ownsNFT && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) && !collectMigrationHash ? (
|
||||
<AutoColumn gap="md">
|
||||
<RowBetween>
|
||||
<TYPE.main>Collect as WETH</TYPE.main>
|
||||
<Toggle
|
||||
id="receive-as-weth"
|
||||
isActive={receiveWETH}
|
||||
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
|
||||
/>
|
||||
</RowBetween>
|
||||
</AutoColumn>
|
||||
) : null}
|
||||
</AutoColumn>
|
||||
</DarkCard>
|
||||
</AutoColumn>
|
||||
|
||||
@@ -21,12 +21,10 @@ import ReactGA from 'react-ga'
|
||||
import { useActiveWeb3React } from 'hooks'
|
||||
import { TransactionResponse } from '@ethersproject/providers'
|
||||
import { useTransactionAdder } from 'state/transactions/hooks'
|
||||
import { WETH9, CurrencyAmount, currencyEquals, Percent } from '@uniswap/sdk-core'
|
||||
import { Percent } from '@uniswap/sdk-core'
|
||||
import { TYPE } from 'theme'
|
||||
import { Wrapper, SmallMaxButton, ResponsiveHeaderText } from './styled'
|
||||
import Loader from 'components/Loader'
|
||||
import { useToken } from 'hooks/Tokens'
|
||||
import { unwrappedToken } from 'utils/wrappedCurrency'
|
||||
import DoubleCurrencyLogo from 'components/DoubleLogo'
|
||||
import { Break } from 'components/earn/styled'
|
||||
import { NonfungiblePositionManager } from '@uniswap/v3-sdk'
|
||||
@@ -34,6 +32,7 @@ import { calculateGasMargin } from 'utils'
|
||||
import useTheme from 'hooks/useTheme'
|
||||
import { AddRemoveTabs } from 'components/NavigationTabs'
|
||||
import RangeBadge from 'components/Badge/RangeBadge'
|
||||
import Toggle from 'components/Toggle'
|
||||
|
||||
export const UINT128MAX = BigNumber.from(2).pow(128).sub(1)
|
||||
|
||||
@@ -65,11 +64,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
|
||||
const theme = useTheme()
|
||||
const { account, chainId, library } = useActiveWeb3React()
|
||||
|
||||
// currencies from position
|
||||
const token0 = useToken(position?.token0)
|
||||
const token1 = useToken(position?.token1)
|
||||
const currency0 = token0 ? unwrappedToken(token0) : undefined
|
||||
const currency1 = token1 ? unwrappedToken(token1) : undefined
|
||||
// flag for receiving WETH
|
||||
const [receiveWETH, setReceiveWETH] = useState(false)
|
||||
|
||||
// burn state
|
||||
const { percent } = useBurnV3State()
|
||||
@@ -82,7 +78,7 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
|
||||
feeValue1,
|
||||
outOfRange,
|
||||
error,
|
||||
} = useDerivedV3BurnInfo(position)
|
||||
} = useDerivedV3BurnInfo(position, receiveWETH)
|
||||
const { onPercentSelect } = useBurnV3ActionHandlers()
|
||||
|
||||
const removed = position?.liquidity?.eq(0)
|
||||
@@ -122,12 +118,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
|
||||
slippageTolerance: allowedSlippage,
|
||||
deadline: deadline.toString(),
|
||||
collectOptions: {
|
||||
expectedCurrencyOwed0: currencyEquals(liquidityValue0.currency, WETH9[chainId])
|
||||
? CurrencyAmount.ether(feeValue0.quotient)
|
||||
: feeValue0,
|
||||
expectedCurrencyOwed1: currencyEquals(liquidityValue1.currency, WETH9[chainId])
|
||||
? CurrencyAmount.ether(feeValue1.quotient)
|
||||
: feeValue1,
|
||||
expectedCurrencyOwed0: feeValue0,
|
||||
expectedCurrencyOwed1: feeValue1,
|
||||
recipient: account,
|
||||
},
|
||||
})
|
||||
@@ -195,32 +187,32 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
|
||||
}, [onPercentSelectForSlider, txnHash])
|
||||
|
||||
const pendingText = `Removing ${liquidityValue0?.toSignificant(6)} ${
|
||||
currency0?.symbol
|
||||
} and ${liquidityValue1?.toSignificant(6)} ${currency1?.symbol}`
|
||||
liquidityValue0?.currency?.symbol
|
||||
} and ${liquidityValue1?.toSignificant(6)} ${liquidityValue1?.currency?.symbol}`
|
||||
|
||||
function modalHeader() {
|
||||
return (
|
||||
<AutoColumn gap={'sm'} style={{ padding: '16px' }}>
|
||||
<RowBetween align="flex-end">
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{currency0?.symbol}:
|
||||
Pooled {liquidityValue0?.currency?.symbol}:
|
||||
</Text>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||
{liquidityValue0 && <FormattedCurrencyAmount currencyAmount={liquidityValue0} />}
|
||||
</Text>
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency0} />
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={liquidityValue0?.currency} />
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
<RowBetween align="flex-end">
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{currency1?.symbol}:
|
||||
Pooled {liquidityValue1?.currency?.symbol}:
|
||||
</Text>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||
{liquidityValue1 && <FormattedCurrencyAmount currencyAmount={liquidityValue1} />}
|
||||
</Text>
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency1} />
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={liquidityValue1?.currency} />
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
{feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) ? (
|
||||
@@ -230,24 +222,24 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
|
||||
</TYPE.italic>
|
||||
<RowBetween>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{currency0?.symbol} from fees:
|
||||
{feeValue0?.currency?.symbol} Fees Earned:
|
||||
</Text>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||
{feeValue0 && <FormattedCurrencyAmount currencyAmount={feeValue0} />}
|
||||
</Text>
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency0} />
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={feeValue0?.currency} />
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{currency1?.symbol} from fees:
|
||||
{feeValue1?.currency?.symbol} Fees Earned:
|
||||
</Text>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||
{feeValue1 && <FormattedCurrencyAmount currencyAmount={feeValue1} />}
|
||||
</Text>
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency1} />
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={feeValue1?.currency} />
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
</>
|
||||
@@ -287,8 +279,16 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
|
||||
<AutoColumn gap="lg">
|
||||
<RowBetween>
|
||||
<RowFixed>
|
||||
<DoubleCurrencyLogo currency0={currency1} currency1={currency0} size={20} margin={true} />
|
||||
<TYPE.label ml="10px" fontSize="20px">{`${currency0?.symbol}/${currency1?.symbol}`}</TYPE.label>
|
||||
<DoubleCurrencyLogo
|
||||
currency0={feeValue0?.currency}
|
||||
currency1={feeValue1?.currency}
|
||||
size={20}
|
||||
margin={true}
|
||||
/>
|
||||
<TYPE.label
|
||||
ml="10px"
|
||||
fontSize="20px"
|
||||
>{`${feeValue0?.currency?.symbol}/${feeValue1?.currency?.symbol}`}</TYPE.label>
|
||||
</RowFixed>
|
||||
<RangeBadge removed={removed} inRange={!outOfRange} />
|
||||
</RowBetween>
|
||||
@@ -319,24 +319,24 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
|
||||
<AutoColumn gap="md">
|
||||
<RowBetween>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pooled {currency0?.symbol}:
|
||||
Pooled {liquidityValue0?.currency?.symbol}:
|
||||
</Text>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||
{liquidityValue0 && <FormattedCurrencyAmount currencyAmount={liquidityValue0} />}
|
||||
</Text>
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency0} />
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={liquidityValue0?.currency} />
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
Pooled {currency1?.symbol}:
|
||||
Pooled {liquidityValue1?.currency?.symbol}:
|
||||
</Text>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||
{liquidityValue1 && <FormattedCurrencyAmount currencyAmount={liquidityValue1} />}
|
||||
</Text>
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency1} />
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={liquidityValue1?.currency} />
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
{feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0) ? (
|
||||
@@ -344,30 +344,40 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
|
||||
<Break />
|
||||
<RowBetween>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{currency0?.symbol} Fees Earned:
|
||||
{feeValue0?.currency?.symbol} Fees Earned:
|
||||
</Text>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||
{feeValue0 && <FormattedCurrencyAmount currencyAmount={feeValue0} />}
|
||||
</Text>
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency0} />
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={feeValue0?.currency} />
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
<RowBetween>
|
||||
<Text fontSize={16} fontWeight={500}>
|
||||
{currency1?.symbol} Fees Earned:
|
||||
{feeValue1?.currency?.symbol} Fees Earned:
|
||||
</Text>
|
||||
<RowFixed>
|
||||
<Text fontSize={16} fontWeight={500} marginLeft={'6px'}>
|
||||
{feeValue1 && <FormattedCurrencyAmount currencyAmount={feeValue1} />}
|
||||
</Text>
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={currency1} />
|
||||
<CurrencyLogo size="20px" style={{ marginLeft: '8px' }} currency={feeValue1?.currency} />
|
||||
</RowFixed>
|
||||
</RowBetween>
|
||||
</>
|
||||
) : null}
|
||||
</AutoColumn>
|
||||
</LightCard>
|
||||
|
||||
<RowBetween>
|
||||
<TYPE.main>Collect as WETH</TYPE.main>
|
||||
<Toggle
|
||||
id="receive-as-weth"
|
||||
isActive={receiveWETH}
|
||||
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
|
||||
/>
|
||||
</RowBetween>
|
||||
|
||||
<div style={{ display: 'flex' }}>
|
||||
<AutoColumn gap="12px" style={{ flex: '1' }}>
|
||||
<ButtonConfirmed
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MaxButton } from 'pages/Pool/styleds'
|
||||
import { Text } from 'rebass'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
export const Wrapper = styled.div`
|
||||
position: relative;
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
@@ -526,12 +525,12 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
approvalState === ApprovalState.APPROVED || signatureState === UseERC20PermitState.SIGNED
|
||||
}
|
||||
>
|
||||
<AutoRow justify="space-between">
|
||||
<AutoRow justify="space-between" style={{ flexWrap: 'nowrap' }}>
|
||||
<span style={{ display: 'flex', alignItems: 'center' }}>
|
||||
<CurrencyLogo
|
||||
currency={currencies[Field.INPUT]}
|
||||
size={'20px'}
|
||||
style={{ marginRight: '8px' }}
|
||||
style={{ marginRight: '8px', flexShrink: 0 }}
|
||||
/>
|
||||
{/* we need to shorten this string on mobile */}
|
||||
{approvalState === ApprovalState.APPROVED || signatureState === UseERC20PermitState.SIGNED
|
||||
@@ -551,7 +550,7 @@ export default function Swap({ history }: RouteComponentProps) {
|
||||
'. You only have to do this once per token.'
|
||||
}
|
||||
>
|
||||
<HelpCircle size="20" color={'white'} />
|
||||
<HelpCircle size="20" color={'white'} style={{ marginLeft: '8px' }} />
|
||||
</MouseoverTooltip>
|
||||
)}
|
||||
</AutoRow>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState } from 'react'
|
||||
import { AutoColumn } from '../../components/Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
import { RouteComponentProps } from 'react-router-dom'
|
||||
import { ExternalLink, StyledInternalLink, TYPE } from '../../theme'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react'
|
||||
import { AutoColumn } from '../../components/Column'
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
import { ExternalLink, TYPE } from '../../theme'
|
||||
import { RowBetween, RowFixed } from '../../components/Row'
|
||||
import { Link } from 'react-router-dom'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import styled from 'styled-components'
|
||||
import styled from 'styled-components/macro'
|
||||
|
||||
export const StandardPageWrapper = styled.div`
|
||||
padding-top: 160px;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Token, CurrencyAmount, Percent } from '@uniswap/sdk-core'
|
||||
import { Token, CurrencyAmount, Percent, Ether, currencyEquals, ETHER } from '@uniswap/sdk-core'
|
||||
import { Position } from '@uniswap/v3-sdk'
|
||||
import { usePool } from 'hooks/usePools'
|
||||
import { useActiveWeb3React } from 'hooks'
|
||||
@@ -10,20 +10,22 @@ import { PositionDetails } from 'types/position'
|
||||
|
||||
import { AppDispatch, AppState } from '../../index'
|
||||
import { selectPercent } from './actions'
|
||||
import { unwrappedToken } from 'utils/wrappedCurrency'
|
||||
|
||||
export function useBurnV3State(): AppState['burnV3'] {
|
||||
return useSelector<AppState, AppState['burnV3']>((state) => state.burnV3)
|
||||
}
|
||||
|
||||
export function useDerivedV3BurnInfo(
|
||||
position?: PositionDetails
|
||||
position?: PositionDetails,
|
||||
asWETH = false
|
||||
): {
|
||||
position?: Position
|
||||
liquidityPercentage?: Percent
|
||||
liquidityValue0?: CurrencyAmount<Token>
|
||||
liquidityValue1?: CurrencyAmount<Token>
|
||||
feeValue0?: CurrencyAmount<Token>
|
||||
feeValue1?: CurrencyAmount<Token>
|
||||
liquidityValue0?: CurrencyAmount<Token | Ether>
|
||||
liquidityValue1?: CurrencyAmount<Token | Ether>
|
||||
feeValue0?: CurrencyAmount<Token | Ether>
|
||||
feeValue1?: CurrencyAmount<Token | Ether>
|
||||
outOfRange: boolean
|
||||
error?: string
|
||||
} {
|
||||
@@ -50,20 +52,27 @@ export function useDerivedV3BurnInfo(
|
||||
|
||||
const liquidityPercentage = new Percent(percent, 100)
|
||||
|
||||
const liquidityValue0 =
|
||||
positionSDK &&
|
||||
CurrencyAmount.fromRawAmount(
|
||||
positionSDK.amount0.currency,
|
||||
liquidityPercentage.multiply(positionSDK.amount0.quotient).quotient
|
||||
)
|
||||
const liquidityValue1 =
|
||||
positionSDK &&
|
||||
CurrencyAmount.fromRawAmount(
|
||||
positionSDK.amount1.currency,
|
||||
liquidityPercentage.multiply(positionSDK.amount1.quotient).quotient
|
||||
)
|
||||
const discountedAmount0 = positionSDK
|
||||
? liquidityPercentage.multiply(positionSDK.amount0.quotient).quotient
|
||||
: undefined
|
||||
const discountedAmount1 = positionSDK
|
||||
? liquidityPercentage.multiply(positionSDK.amount1.quotient).quotient
|
||||
: undefined
|
||||
|
||||
const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, position?.tokenId)
|
||||
const liquidityValue0 =
|
||||
token0 && discountedAmount0
|
||||
? currencyEquals(unwrappedToken(token0), ETHER) && !asWETH
|
||||
? CurrencyAmount.ether(discountedAmount0)
|
||||
: CurrencyAmount.fromRawAmount(token0, discountedAmount0)
|
||||
: undefined
|
||||
const liquidityValue1 =
|
||||
token1 && discountedAmount1
|
||||
? currencyEquals(unwrappedToken(token1), ETHER) && !asWETH
|
||||
? CurrencyAmount.ether(discountedAmount1)
|
||||
: CurrencyAmount.fromRawAmount(token1, discountedAmount1)
|
||||
: undefined
|
||||
|
||||
const [feeValue0, feeValue1] = useV3PositionFees(pool ?? undefined, position?.tokenId, asWETH)
|
||||
|
||||
const outOfRange =
|
||||
pool && position ? pool.tickCurrent < position.tickLower || pool.tickCurrent > position.tickUpper : false
|
||||
|
||||
@@ -28,7 +28,7 @@ const store = configureStore({
|
||||
multicall,
|
||||
lists,
|
||||
},
|
||||
middleware: [...getDefaultMiddleware({ thunk: false }), save({ states: PERSISTED_KEYS })],
|
||||
middleware: [...getDefaultMiddleware({ thunk: false }), save({ states: PERSISTED_KEYS, debounce: 1000 })],
|
||||
preloadedState: load({ states: PERSISTED_KEYS }),
|
||||
})
|
||||
|
||||
|
||||
@@ -164,8 +164,8 @@ export default function Updater(): null {
|
||||
cancellations: chunkedCalls.map((chunk, index) => {
|
||||
const { cancel, promise } = retry(() => fetchChunk(multicall2Contract, chunk, latestBlockNumber), {
|
||||
n: Infinity,
|
||||
minWait: 2500,
|
||||
maxWait: 3500,
|
||||
minWait: 1000,
|
||||
maxWait: 2500,
|
||||
})
|
||||
promise
|
||||
.then(({ results: returnData, blockNumber: fetchBlockNumber }) => {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user