Compare commits

...

29 Commits

Author SHA1 Message Date
Moody Salem
b14da2844d chore: remove all tick lens stuff that is not used 2021-05-19 17:35:59 -05:00
Justin Domingue
d3c04b7246 fix: stabilize fiat value by fixing max hop and increasing USDC out to 100k (#1651)
* stablizie fiat value by fixing max hop and increasing USDC out to 100k

* move maxHops and singleHopOnly to parameter of useV2TradeExactOut

* remove single hop param
2021-05-19 13:21:27 -07:00
Justin Domingue
307a995a50 fix: handle insufficient input amount error in v2 add liquidity (#1652)
* handle insufficient input amount error in mint/hooks

* use error.isInsufficientInputAmountError

* fixed typo
2021-05-19 13:18:32 -07:00
Moody Salem
46911593e5 fix: removing and adding liquidity when the price of the pool is at the min/max price
fixes https://github.com/Uniswap/uniswap-interface/issues/1641
2021-05-18 19:17:05 -05:00
Justin Domingue
1ac36c7b6b fix: display pool shares < 10% (#1639)
* fix: display pool shares < 10%

* set bips to 1/10_000
2021-05-18 17:07:06 -05:00
Moody Salem
8e055df447 refactor: make the price computation in v2 add liquidity a little safer 2021-05-18 16:06:54 -05:00
Moody Salem
02ecd727eb fix: do not crash when user switches eth -> weth in add (#1637)
* fix: do not crash when user switches eth -> weth in add

* linting error
2021-05-18 16:52:34 -04:00
Moody Salem
adc8429bdc fix: working copy to clipboard button in walletconnect qr code modal (#1636)
fixes https://github.com/Uniswap/uniswap-interface/issues/1488
2021-05-18 15:22:53 -05:00
Moody Salem
458d34d96c give the check a name 2021-05-18 15:14:33 -05:00
Justin Domingue
6a4fa0c9bf fix: division by 0 error when both reserves are 0 (#1632)
* set pair to invalid if both reserves are 0

* consider reserve0/1=0 as no liquidity
2021-05-18 12:50:28 -07:00
Moody Salem
7fc9a655fc fix: improve rendering of fee dollar values 2021-05-18 14:35:02 -05:00
Moody Salem
8d3babd015 refactor: more separation by chain of addresses 2021-05-18 14:33:03 -05:00
Moody Salem
75ed4c5dae fix: missed a memo for fetching v2 pairs (#1635) 2021-05-18 14:21:06 -05:00
Justin Domingue
58dfadb13c handle custom token overflow (#1634) 2021-05-18 11:32:09 -07:00
Moody Salem
3d5f5f783c chore: check pr titles 2021-05-18 13:26:23 -05:00
jab416171
ecb7132843 Add etherscan links for the two tokens in the pool on the NFT page (#1593)
* Add etherscan links for the two tokens in the pool on the NFT page

* moving linked tokens to a function

added arrow to show that it's a link
added check for eth

* clean up impl

Co-authored-by: Noah Zinsmeister <noahwz@gmail.com>
2021-05-18 13:34:20 -04:00
Justin Domingue
980eb8a518 Leverage Trade api for USDC price with v2 & v3 support (#1610)
* calculate usdc price using trade exact out

* fix typo

* add support for non-mainnet

* use fromRawAmount instead of tryParseAmount
2021-05-18 10:07:37 -07:00
Noah Zinsmeister
a11e89c0e1 hide WETH toggle for non-WETH pairs (#1633)
* only show weth toggle for eth pairs

* revert unwrappedToken change
2021-05-18 12:58:42 -04:00
Moody Salem
3efe5268ae refactor: break down some constants files and move some stuff around 2021-05-18 10:31:22 -05:00
Moody Salem
3f43a8fbaf npx not needed 2021-05-18 09:28:30 -05:00
Ian Lapham
cccf149568 fix: update tick parsing to handle min/max prices (#1613)
* update tick parsing to handle min/max prices

* remove fee tier step
2021-05-17 20:19:15 -04:00
Justin Domingue
604ea49567 Revert "lazy load uncommon routes to reduce initial bundle size (#1597)" (#1611)
This reverts commit 4c0c6dfde6.
2021-05-17 11:24:31 -07:00
Justin Domingue
4c0c6dfde6 lazy load uncommon routes to reduce initial bundle size (#1597) 2021-05-17 11:03:49 -07:00
Noah Zinsmeister
a160bb8f02 Merge remote-tracking branch 'refs/remotes/origin/main' 2021-05-17 11:54:17 -04:00
Noah Zinsmeister
e86946b104 bump to sdk version that fixes mint slippage bug
closes #1573
2021-05-17 11:54:06 -04:00
Moody Salem
03108b981e update README.md 2021-05-17 10:14:35 -05:00
Moody Salem
ae27e245b4 replace the message when we fail to parse an error 2021-05-14 14:13:13 -05:00
Moody Salem
897f354202 chore: bump mathieudutour/github-tag-action to latest release version to fix generated changelogs
https://github.com/Uniswap/uniswap-interface/issues/1572
2021-05-14 10:56:57 -05:00
Moody Salem
4745052f0e fix: break words in swap error messages (fixes https://github.com/Uniswap/uniswap-interface/issues/1462) 2021-05-14 10:50:55 -05:00
134 changed files with 1113 additions and 1159 deletions

17
.github/workflows/check-pr-title.yaml vendored Normal file
View File

@@ -0,0 +1,17 @@
name: "Check PR Title"
on:
pull_request_target:
types:
- opened
- edited
- synchronize
jobs:
check-pr-title:
name: Check PR Title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v3.4.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -19,7 +19,7 @@ jobs:
- name: Bump version and push tag
id: github_tag_action
uses: mathieudutour/github-tag-action@v4.5
uses: mathieudutour/github-tag-action@331898d5052eedac9b15fec867b5ba66ebf9b692
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
release_branches: .*

View File

@@ -4,7 +4,7 @@ import { createWeb3ReactRoot, Web3ReactProvider } from '@web3-react/core'
import React from 'react'
import { Provider as StoreProvider } from 'react-redux'
import { ThemeProvider as SCThemeProvider } from 'styled-components'
import { NetworkContextName } from '../src/constants'
import { NetworkContextName } from '../src/constants/misc'
import store from '../src/state'
import { FixedGlobalStyle, theme, ThemedGlobalStyle } from '../src/theme'
import getLibrary from '../src/utils/getLibrary'

View File

@@ -41,8 +41,17 @@ yarn start
**Please open all pull requests against the `main` branch.**
CI checks will run against all PRs.
## Accessing Uniswap Interface V1
## Accessing Uniswap V2
The Uniswap Interface supports swapping against, and migrating or removing liquidity from Uniswap V1. However,
if you would like to use Uniswap V1, the Uniswap V1 interface for mainnet and testnets is accessible via IPFS gateways
The Uniswap Interface supports swapping, adding liquidity, removing liquidity and migrating liquidity for
Uniswap protocol V2.
- Swap on Uniswap V2: https://app.uniswap.org/#/swap?use=v2
- View V2 liquidity: https://app.uniswap.org/#/pool/v2
- Add V2 liquidity: https://app.uniswap.org/#/add/v2
- Migrate V2 liquidity to V3: https://app.uniswap.org/#/migrate/v2
## Accessing Uniswap V1
The Uniswap V1 interface for mainnet and testnets is accessible via IPFS gateways
linked from the [v1.0.0 release](https://github.com/Uniswap/uniswap-interface/releases/tag/v1.0.0).

View File

@@ -51,7 +51,7 @@
"@uniswap/v2-sdk": "^3.0.0-alpha.0",
"@uniswap/v3-core": "1.0.0",
"@uniswap/v3-periphery": "1.0.0",
"@uniswap/v3-sdk": "^3.0.0-alpha.4",
"@uniswap/v3-sdk": "^3.0.0-alpha.6",
"@web3-react/core": "^6.0.9",
"@web3-react/fortmatic-connector": "^6.0.9",
"@web3-react/injected-connector": "^6.0.7",
@@ -116,10 +116,13 @@
"workbox-routing": "^6.1.0",
"workbox-strategies": "^6.1.0"
},
"resolutions": {
"@walletconnect/web3-provider": "1.4.2-rc.2"
},
"scripts": {
"compile-contract-types": "yarn compile-external-abi-types && yarn compile-v3-contract-types",
"compile-external-abi-types": "npx typechain --target ethers-v5 --out-dir src/abis/types './src/abis/**/*.json'",
"compile-v3-contract-types": "npx typechain --target ethers-v5 --out-dir src/types/v3 './node_modules/@uniswap/?(v3-core|v3-periphery)/artifacts/contracts/**/*.json'",
"compile-external-abi-types": "typechain --target ethers-v5 --out-dir src/abis/types './src/abis/**/*.json'",
"compile-v3-contract-types": "typechain --target ethers-v5 --out-dir src/types/v3 './node_modules/@uniswap/?(v3-core|v3-periphery)/artifacts/contracts/**/*.json'",
"build": "yarn compile-contract-types && react-scripts build",
"integration-test": "start-server-and-test 'serve build -l 3000' http://localhost:3000 'cypress run'",
"postinstall": "yarn compile-contract-types",

View File

@@ -1,55 +0,0 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "_factoryV1",
"type": "address"
},
{
"internalType": "address",
"name": "_router",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [
{
"internalType": "address",
"name": "token",
"type": "address"
},
{
"internalType": "uint256",
"name": "amountTokenMin",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amountETHMin",
"type": "uint256"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "deadline",
"type": "uint256"
}
],
"name": "migrate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"stateMutability": "payable",
"type": "receive"
}
]

View File

@@ -1,6 +0,0 @@
import { Interface } from '@ethersproject/abi'
import { abi as STAKING_REWARDS_ABI } from '@uniswap/liquidity-staker/build/StakingRewards.json'
const STAKING_REWARDS_INTERFACE = new Interface(STAKING_REWARDS_ABI)
export { STAKING_REWARDS_INTERFACE }

View File

@@ -2,10 +2,10 @@ import React from 'react'
import styled from 'styled-components/macro'
import { CheckCircle, Triangle } from 'react-feather'
import { useActiveWeb3React } from '../../hooks'
import { getEtherscanLink } from '../../utils'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink } from '../../theme'
import { useAllTransactions } from '../../state/transactions/hooks'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { RowFixed } from '../Row'
import Loader from '../Loader'
@@ -49,7 +49,11 @@ export default function Transaction({ hash }: { hash: string }) {
return (
<TransactionWrapper>
<TransactionState href={getEtherscanLink(chainId, hash, 'transaction')} pending={pending} success={success}>
<TransactionState
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
pending={pending}
success={success}
>
<RowFixed>
<TransactionStatusText>{summary ?? hash} </TransactionStatusText>
</RowFixed>

View File

@@ -1,17 +1,17 @@
import React, { useCallback, useContext } from 'react'
import { useDispatch } from 'react-redux'
import styled, { ThemeContext } from 'styled-components'
import { useActiveWeb3React } from '../../hooks'
import { SUPPORTED_WALLETS } from '../../constants/wallet'
import { useActiveWeb3React } from '../../hooks/web3'
import { AppDispatch } from '../../state'
import { clearAllTransactions } from '../../state/transactions/actions'
import { shortenAddress } from '../../utils'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { AutoRow } from '../Row'
import Copy from './Copy'
import Transaction from './Transaction'
import { SUPPORTED_WALLETS } from '../../constants'
import { ReactComponent as Close } from '../../assets/images/x.svg'
import { getEtherscanLink } from '../../utils'
import { injected, walletconnect, walletlink, fortmatic, portis } from '../../connectors'
import CoinbaseWalletIcon from '../../assets/images/coinbaseWalletIcon.svg'
import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
@@ -354,7 +354,7 @@ export default function AccountDetails({
<AddressLink
hasENS={!!ENSName}
isENS={true}
href={chainId && getEtherscanLink(chainId, ENSName, 'address')}
href={chainId && getExplorerLink(chainId, ENSName, ExplorerDataType.ADDRESS)}
>
<LinkIcon size={16} />
<span style={{ marginLeft: '4px' }}>View on Etherscan</span>
@@ -376,7 +376,7 @@ export default function AccountDetails({
<AddressLink
hasENS={!!ENSName}
isENS={false}
href={getEtherscanLink(chainId, account, 'address')}
href={getExplorerLink(chainId, account, ExplorerDataType.ADDRESS)}
>
<LinkIcon size={16} />
<span style={{ marginLeft: '4px' }}>View on Etherscan</span>

View File

@@ -1,11 +1,11 @@
import React, { useContext, useCallback } from 'react'
import styled, { ThemeContext } from 'styled-components'
import useENS from '../../hooks/useENS'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExternalLink, TYPE } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { AutoColumn } from '../Column'
import { RowBetween } from '../Row'
import { getEtherscanLink } from '../../utils'
const InputPanel = styled.div`
${({ theme }) => theme.flexColumnNoWrap}
@@ -102,7 +102,10 @@ export default function AddressInputPanel({
Recipient
</TYPE.black>
{address && chainId && (
<ExternalLink href={getEtherscanLink(chainId, name ?? address, 'address')} style={{ fontSize: '14px' }}>
<ExternalLink
href={getExplorerLink(chainId, name ?? address, ExplorerDataType.ADDRESS)}
style={{ fontSize: '14px' }}
>
(View on Etherscan)
</ExternalLink>
)}

View File

@@ -1,6 +1,14 @@
import React, { ReactNode, useMemo } from 'react'
import { BLOCKED_ADDRESSES } from '../../constants'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
// SDN OFAC addresses
const BLOCKED_ADDRESSES: string[] = [
'0x7F367cC41522cE07553e823bf3be79A889DEbe1B',
'0xd882cFc20F52f2599D84b8e8D58C7FB62cfE344b',
'0x901bb9583b24D97e995513C6778dc6888AB6870e',
'0xA7e5d5A720f06526557c513402f2e6B5fA20b008',
'0x8576aCC5C05D6Ce88f4e49bf65BdF0C62F91353C',
]
export default function Blocklist({ children }: { children: ReactNode }) {
const { account } = useActiveWeb3React()

View File

@@ -12,7 +12,7 @@ import { RowBetween, RowFixed } from '../Row'
import { TYPE } from '../../theme'
import { Input as NumericalInput } from '../NumericalInput'
import { ReactComponent as DropDown } from '../../assets/images/dropdown.svg'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTranslation } from 'react-i18next'
import useTheme from '../../hooks/useTheme'
import { Lock } from 'react-feather'

View File

@@ -1,6 +1,6 @@
import { Story } from '@storybook/react/types-6-0'
import React from 'react'
import { DAI, WBTC } from '../../constants'
import { DAI, WBTC } from '../../constants/tokens'
import Component, { DoubleCurrencyLogoProps } from './index'
export default {

View File

@@ -1,10 +1,10 @@
import React, { useState, useEffect } from 'react'
import React, { useEffect, useState } from 'react'
import styled, { keyframes } from 'styled-components'
import { TYPE, ExternalLink } from '../../theme'
import { useActiveWeb3React } from '../../hooks/web3'
import { useBlockNumber } from '../../state/application/hooks'
import { getEtherscanLink } from '../../utils'
import { useActiveWeb3React } from '../../hooks'
import { ExternalLink, TYPE } from '../../theme'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
const StyledPolling = styled.div`
position: fixed;
@@ -91,7 +91,9 @@ export default function Polling() {
)
return (
<ExternalLink href={chainId && blockNumber ? getEtherscanLink(chainId, blockNumber.toString(), 'block') : ''}>
<ExternalLink
href={chainId && blockNumber ? getExplorerLink(chainId, blockNumber.toString(), ExplorerDataType.BLOCK) : ''}
>
<StyledPolling onMouseEnter={() => setIsHover(true)} onMouseLeave={() => setIsHover(false)}>
<StyledPollingNumber breathe={isMounting} hovering={isHover}>
{blockNumber}

View File

@@ -3,9 +3,9 @@ import React, { useMemo } from 'react'
import { X } from 'react-feather'
import styled from 'styled-components/macro'
import tokenLogo from '../../assets/images/token-logo.png'
import { UNI } from '../../constants'
import { UNI } from '../../constants/tokens'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useMerkleDistributorContract } from '../../hooks/useContract'
import useCurrentBlockTimestamp from '../../hooks/useCurrentBlockTimestamp'
import { useTotalUniEarned } from '../../state/stake/hooks'

View File

@@ -11,7 +11,7 @@ import styled from 'styled-components/macro'
import Logo from '../../assets/svg/logo.svg'
import LogoDark from '../../assets/svg/logo_white.svg'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useDarkModeManager } from '../../state/user/hooks'
import { useETHBalances } from '../../state/wallet/hooks'
import { CardNoise } from '../earn/styled'

View File

@@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react'
import styled from 'styled-components/macro'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import Jazzicon from 'jazzicon'
const StyledIdenticonContainer = styled.div`

View File

@@ -3,7 +3,7 @@ import { BookOpen, Code, Info, MessageCircle, PieChart } from 'react-feather'
import { Link } from 'react-router-dom'
import styled, { css } from 'styled-components'
import { ReactComponent as MenuIcon } from '../../assets/images/menu.svg'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useOnClickOutside } from '../../hooks/useOnClickOutside'
import { ApplicationModal } from '../../state/application/actions'
import { useModalOpen, useToggleModal } from '../../state/application/hooks'

View File

@@ -1,5 +1,6 @@
import React, { useContext } from 'react'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { AutoColumn, ColumnCenter } from '../Column'
import styled, { ThemeContext } from 'styled-components'
@@ -8,7 +9,6 @@ import { TYPE, CloseIcon, CustomLightSpinner } from '../../theme'
import { ArrowUpCircle } from 'react-feather'
import Circle from '../../assets/images/blue-loader.svg'
import { getEtherscanLink } from '../../utils'
import { ExternalLink } from '../../theme/components'
const ConfirmOrLoadingWrapper = styled.div`
@@ -62,7 +62,10 @@ export function SubmittedView({
<AutoColumn gap="100px" justify={'center'}>
{children}
{chainId && hash && (
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')} style={{ marginLeft: '4px' }}>
<ExternalLink
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
style={{ marginLeft: '4px' }}
>
<TYPE.subHeader>View transaction on Etherscan</TYPE.subHeader>
</ExternalLink>
)}

View File

@@ -4,7 +4,7 @@ import { X } from 'react-feather'
import styled, { keyframes } from 'styled-components'
import tokenLogo from '../../assets/images/token-logo.png'
import { ButtonPrimary } from '../../components/Button'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { ApplicationModal } from '../../state/application/actions'
import {
useModalOpen,

View File

@@ -1,10 +1,10 @@
import React, { useContext } from 'react'
import { AlertCircle, CheckCircle } from 'react-feather'
import styled, { ThemeContext } from 'styled-components'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { TYPE } from '../../theme'
import { ExternalLink } from '../../theme/components'
import { getEtherscanLink } from '../../utils'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { AutoColumn } from '../Column'
import { AutoRow } from '../Row'
@@ -33,7 +33,9 @@ export default function TransactionPopup({
<AutoColumn gap="8px">
<TYPE.body fontWeight={500}>{summary ?? 'Hash: ' + hash.slice(0, 8) + '...' + hash.slice(58, 65)}</TYPE.body>
{chainId && (
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')}>View on Etherscan</ExternalLink>
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}>
View on Etherscan
</ExternalLink>
)}
</AutoColumn>
</RowNoFlex>

View File

@@ -8,7 +8,7 @@ import { Text } from 'rebass'
import styled from 'styled-components/macro'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTokenBalance } from '../../state/wallet/hooks'
import { currencyId } from '../../utils/currencyId'
import { unwrappedToken } from '../../utils/wrappedCurrency'
@@ -24,7 +24,7 @@ import CurrencyLogo from '../CurrencyLogo'
import DoubleCurrencyLogo from '../DoubleLogo'
import { RowBetween, RowFixed, AutoRow } from '../Row'
import { Dots } from '../swap/styleds'
import { BIG_INT_ZERO } from '../../constants'
import { BIG_INT_ZERO } from '../../constants/misc'
import { FixedHeightRow } from '.'
const StyledPositionCard = styled(LightCard)<{ bgColor: any }>`

View File

@@ -9,7 +9,7 @@ import { Text } from 'rebass'
import styled from 'styled-components/macro'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTokenBalance } from '../../state/wallet/hooks'
import { ExternalLink, TYPE } from '../../theme'
import { currencyId } from '../../utils/currencyId'
@@ -26,7 +26,7 @@ import CurrencyLogo from '../CurrencyLogo'
import DoubleCurrencyLogo from '../DoubleLogo'
import { RowBetween, RowFixed, AutoRow } from '../Row'
import { Dots } from '../swap/styleds'
import { BIG_INT_ZERO } from '../../constants'
import { BIG_INT_ZERO } from '../../constants/misc'
export const FixedHeightRow = styled(RowBetween)`
height: 24px;

View File

@@ -12,10 +12,10 @@ import { WETH9, Price, Token, Percent } from '@uniswap/sdk-core'
import { formatPrice } from 'utils/formatTokenAmount'
import Loader from 'components/Loader'
import { unwrappedToken } from 'utils/wrappedCurrency'
import { DAI, USDC, USDT, WBTC } from '../../constants'
import RangeBadge from 'components/Badge/RangeBadge'
import { RowFixed } from 'components/Row'
import HoverInlineText from 'components/HoverInlineText'
import { DAI, USDC, USDT, WBTC } from '../../constants/tokens'
const Row = styled(Link)`
align-items: center;

View File

@@ -2,7 +2,7 @@ import React from 'react'
import { Currency, Price, Token } from '@uniswap/sdk-core'
import StepCounter from 'components/InputStepCounter/InputStepCounter'
import { RowBetween } from 'components/Row'
import { useActiveWeb3React } from 'hooks'
import { useActiveWeb3React } from 'hooks/web3'
import { wrappedCurrency } from 'utils/wrappedCurrency'
// currencyA is the base token

View File

@@ -1,7 +1,7 @@
import React from 'react'
import { Currency } from '@uniswap/sdk-core'
import { ToggleElement, ToggleWrapper } from 'components/Toggle/MultiToggle'
import { useActiveWeb3React } from 'hooks'
import { useActiveWeb3React } from 'hooks/web3'
import { wrappedCurrency } from 'utils/wrappedCurrency'
// the order of displayed base currencies from left to right is always in sort order

View File

@@ -3,7 +3,7 @@ import { Text } from 'rebass'
import { ChainId, Currency, currencyEquals, Token, ETHER } from '@uniswap/sdk-core'
import styled from 'styled-components/macro'
import { SUGGESTED_BASES } from '../../constants'
import { SUGGESTED_BASES } from '../../constants/routing'
import { AutoColumn } from '../Column'
import QuestionHelper from '../QuestionHelper'
import { AutoRow } from '../Row'

View File

@@ -3,7 +3,7 @@ import React, { CSSProperties, MutableRefObject, useCallback, useMemo } from 're
import { FixedSizeList } from 'react-window'
import { Text } from 'rebass'
import styled from 'styled-components/macro'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useCombinedActiveList } from '../../state/lists/hooks'
import { WrappedTokenInfo } from '../../state/lists/wrappedTokenInfo'
import { useCurrencyBalance } from '../../state/wallet/hooks'

View File

@@ -4,7 +4,7 @@ import ReactGA from 'react-ga'
import { useTranslation } from 'react-i18next'
import { FixedSizeList } from 'react-window'
import { Text } from 'rebass'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useAllTokens, useToken, useIsUserAddedToken, useSearchInactiveTokenLists } from '../../hooks/Tokens'
import { CloseIcon, TYPE, ButtonText, IconWrapper } from '../../theme'
import { isAddress } from '../../utils'

View File

@@ -13,10 +13,10 @@ import useTheme from 'hooks/useTheme'
import { ButtonPrimary } from 'components/Button'
import { SectionBreak } from 'components/swap/styleds'
import { useAddUserToken } from 'state/user/hooks'
import { getEtherscanLink } from 'utils'
import { useActiveWeb3React } from 'hooks'
import { useActiveWeb3React } from 'hooks/web3'
import { ExternalLink } from '../../theme/components'
import ListLogo from 'components/ListLogo'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { PaddedColumn } from './styleds'
const Wrapper = styled.div`
@@ -93,7 +93,7 @@ export function ImportToken({ tokens, list, onBack, onDismiss, handleCurrencySel
</TYPE.darkGray>
</AutoColumn>
{chainId && (
<ExternalLink href={getEtherscanLink(chainId, token.address, 'address')}>
<ExternalLink href={getExplorerLink(chainId, token.address, ExplorerDataType.ADDRESS)}>
<AddressText fontSize={12}>{token.address}</AddressText>
</ExternalLink>
)}

View File

@@ -1,5 +1,6 @@
import React, { useRef, RefObject, useCallback, useState, useMemo } from 'react'
import Column from 'components/Column'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { PaddedColumn, Separator, SearchInput } from './styleds'
import Row, { RowBetween, RowFixed } from 'components/Row'
import { TYPE, ExternalLinkIcon, TrashIcon, ButtonText, ExternalLink } from 'theme'
@@ -8,8 +9,8 @@ import styled from 'styled-components/macro'
import { useUserAddedTokens, useRemoveUserAddedToken } from 'state/user/hooks'
import { Token } from '@uniswap/sdk-core'
import CurrencyLogo from 'components/CurrencyLogo'
import { getEtherscanLink, isAddress } from 'utils'
import { useActiveWeb3React } from 'hooks'
import { isAddress } from 'utils'
import { useActiveWeb3React } from 'hooks/web3'
import Card from 'components/Card'
import ImportRow from './ImportRow'
import useTheme from '../../hooks/useTheme'
@@ -20,7 +21,7 @@ const Wrapper = styled.div`
width: 100%;
height: calc(100% - 60px);
position: relative;
padding-bottom: 60px;
padding-bottom: 80px;
`
const Footer = styled.div`
@@ -78,7 +79,7 @@ export default function ManageTokens({
<RowBetween key={token.address} width="100%">
<RowFixed>
<CurrencyLogo currency={token} size={'20px'} />
<ExternalLink href={getEtherscanLink(chainId, token.address, 'address')}>
<ExternalLink href={getExplorerLink(chainId, token.address, ExplorerDataType.ADDRESS)}>
<TYPE.main ml={'10px'} fontWeight={600}>
{token.symbol}
</TYPE.main>
@@ -86,7 +87,7 @@ export default function ManageTokens({
</RowFixed>
<RowFixed>
<TrashIcon onClick={() => removeToken(chainId, token.address)} />
<ExternalLinkIcon href={getEtherscanLink(chainId, token.address, 'address')} />
<ExternalLinkIcon href={getExplorerLink(chainId, token.address, ExplorerDataType.ADDRESS)} />
</RowFixed>
</RowBetween>
))
@@ -95,7 +96,7 @@ export default function ManageTokens({
return (
<Wrapper>
<Column style={{ width: '100%', flex: '1 1' }}>
<Column style={{ width: '100%', height: '100%', flex: '1 1' }}>
<PaddedColumn gap="14px">
<Row>
<SearchInput
@@ -121,7 +122,7 @@ export default function ManageTokens({
)}
</PaddedColumn>
<Separator />
<PaddedColumn gap="lg">
<PaddedColumn gap="lg" style={{ overflow: 'auto', marginBottom: '10px' }}>
<RowBetween>
<TYPE.main fontWeight={600}>
{userAddedTokens?.length} Custom {userAddedTokens.length === 1 ? 'Token' : 'Tokens'}

View File

@@ -1,6 +1,7 @@
import { ChainId, Currency } from '@uniswap/sdk-core'
import React, { useContext } from 'react'
import styled, { ThemeContext } from 'styled-components'
import { getExplorerLink, ExplorerDataType } from '../../utils/getExplorerLink'
import Modal from '../Modal'
import { ExternalLink } from '../../theme'
import { Text } from 'rebass'
@@ -11,8 +12,7 @@ import { ButtonPrimary, ButtonLight } from '../Button'
import { AutoColumn, ColumnCenter } from '../Column'
import Circle from '../../assets/images/blue-loader.svg'
import MetaMaskLogo from '../../assets/images/metamask.png'
import { getEtherscanLink } from '../../utils'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import useAddTokenToMetamask from 'hooks/useAddTokenToMetamask'
const Wrapper = styled.div`
@@ -113,7 +113,7 @@ export function TransactionSubmittedContent({
Transaction Submitted
</Text>
{chainId && hash && (
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')}>
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}>
<Text fontWeight={500} fontSize={14} color={theme.primary1}>
View on Etherscan
</Text>
@@ -184,7 +184,12 @@ export function TransactionErrorContent({ message, onDismiss }: { message: strin
</RowBetween>
<AutoColumn style={{ marginTop: 20, padding: '2rem 0' }} gap="24px" justify="center">
<AlertTriangle color={theme.red1} style={{ strokeWidth: 1.5 }} size={64} />
<Text fontWeight={500} fontSize={16} color={theme.red1} style={{ textAlign: 'center', width: '85%' }}>
<Text
fontWeight={500}
fontSize={16}
color={theme.red1}
style={{ textAlign: 'center', width: '85%', wordBreak: 'break-word' }}
>
{message}
</Text>
</AutoColumn>

View File

@@ -6,7 +6,7 @@ import QuestionHelper from '../QuestionHelper'
import { TYPE } from '../../theme'
import { AutoColumn } from '../Column'
import { RowBetween, RowFixed } from '../Row'
import { DEFAULT_DEADLINE_FROM_NOW } from 'constants/index'
import { DEFAULT_DEADLINE_FROM_NOW } from 'constants/misc'
import { darken } from 'polished'
import { useSetUserSlippageTolerance, useUserSlippageTolerance, useUserTransactionTTL } from 'state/user/hooks'

View File

@@ -1,8 +1,8 @@
import { AbstractConnector } from '@web3-react/abstract-connector'
import React from 'react'
import styled from 'styled-components/macro'
import { SUPPORTED_WALLETS } from '../../constants/wallet'
import Option from './Option'
import { SUPPORTED_WALLETS } from '../../constants'
import { injected } from '../../connectors'
import { darken } from 'polished'
import Loader from '../Loader'

View File

@@ -10,7 +10,7 @@ import MetamaskIcon from '../../assets/images/metamask.png'
import { ReactComponent as Close } from '../../assets/images/x.svg'
import { fortmatic, injected, portis } from '../../connectors'
import { OVERLAY_READY } from '../../connectors/Fortmatic'
import { SUPPORTED_WALLETS } from '../../constants'
import { SUPPORTED_WALLETS } from '../../constants/wallet'
import usePrevious from '../../hooks/usePrevious'
import { ApplicationModal } from '../../state/application/actions'
import { useModalOpen, useWalletModalToggle } from '../../state/application/hooks'

View File

@@ -4,8 +4,8 @@ import styled from 'styled-components/macro'
import { useTranslation } from 'react-i18next'
import { network } from '../../connectors'
import { useEagerConnect, useInactiveListener } from '../../hooks'
import { NetworkContextName } from '../../constants'
import { useEagerConnect, useInactiveListener } from '../../hooks/web3'
import { NetworkContextName } from '../../constants/misc'
import Loader from '../Loader'
const MessageWrapper = styled.div`

View File

@@ -10,7 +10,7 @@ import FortmaticIcon from '../../assets/images/fortmaticIcon.png'
import PortisIcon from '../../assets/images/portisIcon.png'
import WalletConnectIcon from '../../assets/images/walletConnectIcon.svg'
import { fortmatic, injected, portis, walletconnect, walletlink } from '../../connectors'
import { NetworkContextName } from '../../constants'
import { NetworkContextName } from '../../constants/misc'
import useENSName from '../../hooks/useENSName'
import { useHasSocks } from '../../hooks/useSocksBalance'
import { useWalletModalToggle } from '../../state/application/hooks'

View File

@@ -1,4 +1,5 @@
import React, { useState } from 'react'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import Modal from '../Modal'
import { AutoColumn, ColumnCenter } from '../Column'
import styled from 'styled-components/macro'
@@ -12,13 +13,13 @@ import Circle from '../../assets/images/blue-loader.svg'
import { Text } from 'rebass'
import AddressInputPanel from '../AddressInputPanel'
import useENS from '../../hooks/useENS'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { isAddress } from 'ethers/lib/utils'
import Confetti from '../Confetti'
import { CardNoise, CardBGImage, CardBGImageSmaller } from '../earn/styled'
import { useIsTransactionPending } from '../../state/transactions/hooks'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { getEtherscanLink, shortenAddress } from '../../utils'
import { shortenAddress } from '../../utils'
const ContentWrapper = styled(AutoColumn)`
width: 100%;
@@ -181,7 +182,7 @@ export default function AddressClaimModal({ isOpen, onDismiss }: { isOpen: boole
<TYPE.subHeader color="black">Confirm this transaction in your wallet</TYPE.subHeader>
)}
{attempting && hash && !claimConfirmed && chainId && hash && (
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')} style={{ zIndex: 99 }}>
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)} style={{ zIndex: 99 }}>
View transaction on Etherscan
</ExternalLink>
)}

View File

@@ -6,13 +6,13 @@ import { Text } from 'rebass'
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'
import { useActiveWeb3React } from '../../hooks/web3'
import { ApplicationModal } from '../../state/application/actions'
import { useModalOpen, useToggleSelfClaimModal } from '../../state/application/hooks'
import { useClaimCallback, useUserClaimData, useUserUnclaimedAmount } from '../../state/claim/hooks'
import { useUserHasSubmittedClaim } from '../../state/transactions/hooks'
import { CloseIcon, CustomLightSpinner, ExternalLink, TYPE, UniTokenAnimated } from '../../theme'
import { getEtherscanLink } from '../../utils'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { ButtonPrimary } from '../Button'
import { AutoColumn, ColumnCenter } from '../Column'
import Confetti from '../Confetti'
@@ -196,7 +196,10 @@ export default function ClaimModal() {
<TYPE.subHeader color="black">Confirm this transaction in your wallet</TYPE.subHeader>
)}
{attempting && claimSubmitted && !claimConfirmed && chainId && claimTxn?.hash && (
<ExternalLink href={getEtherscanLink(chainId, claimTxn?.hash, 'transaction')} style={{ zIndex: 99 }}>
<ExternalLink
href={getExplorerLink(chainId, claimTxn?.hash, ExplorerDataType.TRANSACTION)}
style={{ zIndex: 99 }}
>
View transaction on Etherscan
</ExternalLink>
)}

View File

@@ -10,7 +10,7 @@ import { useStakingContract } from '../../hooks/useContract'
import { SubmittedView, LoadingView } from '../ModalViews'
import { TransactionResponse } from '@ethersproject/providers'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
const ContentWrapper = styled(AutoColumn)`
width: 100%;

View File

@@ -15,7 +15,7 @@ import { unwrappedToken } from '../../utils/wrappedCurrency'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useV2Pair } from '../../hooks/useV2Pairs'
import useUSDCPrice from '../../hooks/useUSDCPrice'
import { BIG_INT_SECONDS_IN_WEEK } from '../../constants'
import { BIG_INT_SECONDS_IN_WEEK } from '../../constants/misc'
const StatContainer = styled.div`
display: flex;

View File

@@ -1,5 +1,5 @@
import React, { useState, useCallback } from 'react'
import { V2_ROUTER_ADDRESS } from '../../constants'
import { V2_ROUTER_ADDRESS } from '../../constants/addresses'
import { useV2LiquidityTokenPermit } from '../../hooks/useERC20Permit'
import useTransactionDeadline from '../../hooks/useTransactionDeadline'
import Modal from '../Modal'
@@ -12,7 +12,7 @@ import ProgressCircles from '../ProgressSteps'
import CurrencyInputPanel from '../CurrencyInputPanel'
import { Pair } from '@uniswap/v2-sdk'
import { Token, CurrencyAmount } from '@uniswap/sdk-core'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { usePairContract, useStakingContract } from '../../hooks/useContract'
import { useApproveCallback, ApprovalState } from '../../hooks/useApproveCallback'
@@ -83,7 +83,10 @@ export default function StakingModal({ isOpen, onDismiss, stakingInfo, userLiqui
// approval data for stake
const deadline = useTransactionDeadline()
const { signatureData, gatherPermitSignature } = useV2LiquidityTokenPermit(parsedAmountWrapped, V2_ROUTER_ADDRESS)
const { signatureData, gatherPermitSignature } = useV2LiquidityTokenPermit(
parsedAmountWrapped,
chainId && V2_ROUTER_ADDRESS[chainId]
)
const [approval, approveCallback] = useApproveCallback(parsedAmount, stakingInfo.stakingRewardAddress)
const stakingContract = useStakingContract(stakingInfo.stakingRewardAddress)

View File

@@ -11,7 +11,7 @@ import { SubmittedView, LoadingView } from '../ModalViews'
import { TransactionResponse } from '@ethersproject/providers'
import { useTransactionAdder } from '../../state/transactions/hooks'
import FormattedCurrencyAmount from '../FormattedCurrencyAmount'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
const ContentWrapper = styled(AutoColumn)`
width: 100%;

View File

@@ -7,11 +7,11 @@ import Card, { OutlineCard } from 'components/Card'
import { RowBetween, AutoRow } from 'components/Row'
import { AutoColumn } from 'components/Column'
import CurrencyLogo from 'components/CurrencyLogo'
import { useActiveWeb3React } from 'hooks'
import { getEtherscanLink } from 'utils'
import { useActiveWeb3React } from 'hooks/web3'
import { Currency, Token } from '@uniswap/sdk-core'
import { wrappedCurrency } from 'utils/wrappedCurrency'
import { useUnsupportedTokens } from '../../hooks/Tokens'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
const DetailsFooter = styled.div<{ show: boolean }>`
padding-top: calc(16px + 2rem);
@@ -78,7 +78,7 @@ export default function UnsupportedCurrencyFooter({
<TYPE.body fontWeight={500}>{token.symbol}</TYPE.body>
</AutoRow>
{chainId && (
<ExternalLink href={getEtherscanLink(chainId, token.address, 'address')}>
<ExternalLink href={getExplorerLink(chainId, token.address, ExplorerDataType.ADDRESS)}>
<AddressText>{token.address}</AddressText>
</ExternalLink>
)}

View File

@@ -1,5 +1,5 @@
import { Percent } from '@uniswap/sdk-core'
import { ALLOWED_PRICE_IMPACT_HIGH, PRICE_IMPACT_WITHOUT_FEE_CONFIRM_MIN } from '../../constants'
import { ALLOWED_PRICE_IMPACT_HIGH, PRICE_IMPACT_WITHOUT_FEE_CONFIRM_MIN } from '../../constants/misc'
/**
* Given the price impact, get user confirmation.

View File

@@ -171,7 +171,7 @@ export function SwapCallbackError({ error }: { error: string }) {
<SwapCallbackErrorInnerAlertTriangle>
<AlertTriangle size={24} />
</SwapCallbackErrorInnerAlertTriangle>
<p>{error}</p>
<p style={{ wordBreak: 'break-word' }}>{error}</p>
</SwapCallbackErrorInner>
)
}

View File

@@ -1,4 +1,5 @@
import React, { useState } from 'react'
import { UNI } from '../../constants/tokens'
import Modal from '../Modal'
import { AutoColumn } from '../Column'
@@ -7,13 +8,12 @@ import { RowBetween } from '../Row'
import { TYPE } from '../../theme'
import { X } from 'react-feather'
import { ButtonPrimary } from '../Button'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import AddressInputPanel from '../AddressInputPanel'
import { isAddress } from 'ethers/lib/utils'
import useENS from '../../hooks/useENS'
import { useDelegateCallback } from '../../state/governance/hooks'
import { useTokenBalance } from '../../state/wallet/hooks'
import { UNI } from '../../constants'
import { LoadingView, SubmittedView } from '../ModalViews'
import { formatTokenAmount } from 'utils/formatTokenAmount'

View File

@@ -1,5 +1,6 @@
import React, { useState, useContext } from 'react'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { getExplorerLink, ExplorerDataType } from '../../utils/getExplorerLink'
import Modal from '../Modal'
import { AutoColumn, ColumnCenter } from '../Column'
@@ -10,7 +11,6 @@ import { X, ArrowUpCircle } from 'react-feather'
import { ButtonPrimary } from '../Button'
import Circle from '../../assets/images/blue-loader.svg'
import { useVoteCallback, useUserVotes } from '../../state/governance/hooks'
import { getEtherscanLink } from '../../utils'
import { ExternalLink } from '../../theme/components'
import { formatTokenAmount } from 'utils/formatTokenAmount'
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
@@ -133,7 +133,10 @@ export default function VoteModal({ isOpen, onDismiss, proposalId, support }: Vo
<TYPE.largeHeader>Transaction Submitted</TYPE.largeHeader>
</AutoColumn>
{chainId && (
<ExternalLink href={getEtherscanLink(chainId, hash, 'transaction')} style={{ marginLeft: '4px' }}>
<ExternalLink
href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}
style={{ marginLeft: '4px' }}
>
<TYPE.subHeader>View transaction on Etherscan</TYPE.subHeader>
</ExternalLink>
)}

View File

@@ -1,5 +1,5 @@
import { Web3Provider } from '@ethersproject/providers'
import { ChainId } from '@uniswap/sdk-core'
import { Web3Provider } from '@ethersproject/providers'
import { InjectedConnector } from '@web3-react/injected-connector'
import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
import { WalletLinkConnector } from '@web3-react/walletlink-connector'

View File

@@ -0,0 +1,31 @@
import { ChainId } from '@uniswap/sdk-core'
import { FACTORY_ADDRESS as V3_FACTORY_ADDRESS } from '@uniswap/v3-sdk'
import { constructSameAddressMap } from '../utils/constructSameAddressMap'
export const UNI_ADDRESS = constructSameAddressMap('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
export const MULTICALL2_ADDRESSES = constructSameAddressMap('0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696')
export const V2_ROUTER_ADDRESS = constructSameAddressMap('0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D')
export const GOVERNANCE_ADDRESS = constructSameAddressMap('0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F')
export const TIMELOCK_ADDRESS = constructSameAddressMap('0x1a9C8182C09F50C8318d769245beA52c32BE35BC')
export const MERKLE_DISTRIBUTOR_ADDRESS: { [chainId in ChainId]?: string } = {
[ChainId.MAINNET]: '0x090D4613473dEE047c3f2706764f49E0821D256e',
}
export const ARGENT_WALLET_DETECTOR_ADDRESS: { [chainId in ChainId]?: string } = {
[ChainId.MAINNET]: '0xeca4B0bDBf7c55E9b7925919d03CbF8Dc82537E8',
}
export const V3_CORE_FACTORY_ADDRESSES = constructSameAddressMap(V3_FACTORY_ADDRESS)
export const QUOTER_ADDRESSES = constructSameAddressMap('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6')
export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES = constructSameAddressMap(
'0xC36442b4a4522E871399CD717aBDD847Ab11FE88'
)
export const ENS_REGISTRAR_ADDRESSES = {
[ChainId.MAINNET]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[ChainId.GÖRLI]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[ChainId.RINKEBY]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[ChainId.ROPSTEN]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
}
export const SOCKS_CONTROLLER_ADDRESSES = {
[ChainId.MAINNET]: '0x65770b5283117639760beA3F867b69b3697a91dd',
}
export const SWAP_ROUTER_ADDRESSES = constructSameAddressMap('0xE592427A0AEce92De3Edee1F18E0157C05861564')
export const V3_MIGRATOR_ADDRESSES = constructSameAddressMap('0xA5644E29708357803b5A882D272c41cC0dF92B34')

View File

@@ -0,0 +1,37 @@
import { ChainId } from '@uniswap/sdk-core'
import { GOVERNANCE_ADDRESS, TIMELOCK_ADDRESS, UNI_ADDRESS } from './addresses'
export const COMMON_CONTRACT_NAMES: { [chainId in ChainId]?: { [address: string]: string } } = {
[ChainId.MAINNET]: {
[UNI_ADDRESS[ChainId.MAINNET]]: 'UNI',
[GOVERNANCE_ADDRESS[ChainId.MAINNET]]: 'Governance',
[TIMELOCK_ADDRESS[ChainId.MAINNET]]: 'Timelock',
},
[ChainId.RINKEBY]: {
[UNI_ADDRESS[ChainId.RINKEBY]]: 'Rinkeby UNI',
[GOVERNANCE_ADDRESS[ChainId.RINKEBY]]: 'Rinkeby Governance',
[TIMELOCK_ADDRESS[ChainId.RINKEBY]]: 'Rinkeby Timelock',
},
[ChainId.ROPSTEN]: {
[UNI_ADDRESS[ChainId.ROPSTEN]]: 'Ropsten UNI',
[GOVERNANCE_ADDRESS[ChainId.ROPSTEN]]: 'Ropsten Governance',
[TIMELOCK_ADDRESS[ChainId.ROPSTEN]]: 'Ropsten Timelock',
},
[ChainId.KOVAN]: {
[UNI_ADDRESS[ChainId.KOVAN]]: 'Kovan UNI',
[GOVERNANCE_ADDRESS[ChainId.KOVAN]]: 'Kovan Governance',
[TIMELOCK_ADDRESS[ChainId.KOVAN]]: 'Kovan Timelock',
},
[ChainId.GÖRLI]: {
[UNI_ADDRESS[ChainId.GÖRLI]]: 'Goerli UNI',
[GOVERNANCE_ADDRESS[ChainId.GÖRLI]]: 'Goerli Governance',
[TIMELOCK_ADDRESS[ChainId.GÖRLI]]: 'Goerli Timelock',
},
}
export const DEFAULT_AVERAGE_BLOCK_TIME_IN_SECS = 13
// Block time here is slightly higher (~1s) than average in order to avoid ongoing proposals past the displayed time
export const AVERAGE_BLOCK_TIME_IN_SECS: { [chainId in ChainId]?: number } = {
[ChainId.MAINNET]: DEFAULT_AVERAGE_BLOCK_TIME_IN_SECS,
}

View File

@@ -1,279 +0,0 @@
import { ChainId, Percent, Token, WETH9 } from '@uniswap/sdk-core'
import { AbstractConnector } from '@web3-react/abstract-connector'
import JSBI from 'jsbi'
import { fortmatic, injected, portis, walletconnect, walletlink } from '../connectors'
import INJECTED_ICON_URL from '../assets/images/arrow-right.svg'
import METAMASK_ICON_URL from '../assets/images/metamask.png'
import WALLETCONNECT_ICON_URL from '../assets/images/walletConnectIcon.svg'
import COINBASE_ICON_URL from '../assets/images/coinbaseWalletIcon.svg'
import FORTMATIC_ICON_URL from '../assets/images/fortmaticIcon.png'
import PORTIS_ICON_URL from '../assets/images/portisIcon.png'
export const MULTICALL2_ADDRESSES: { [chainId in ChainId]: string } = {
[ChainId.MAINNET]: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696',
[ChainId.ROPSTEN]: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696',
[ChainId.KOVAN]: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696',
[ChainId.RINKEBY]: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696',
[ChainId.GÖRLI]: '0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696',
}
export const V2_ROUTER_ADDRESS = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D'
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
export { PRELOADED_PROPOSALS } from './proposals'
// a list of tokens by chain
type ChainTokenList = {
readonly [chainId in ChainId]: Token[]
}
export const AMPL = new Token(ChainId.MAINNET, '0xD46bA6D942050d489DBd938a2C909A5d5039A161', 9, 'AMPL', 'Ampleforth')
export const DAI = new Token(ChainId.MAINNET, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'Dai Stablecoin')
export const USDC = new Token(ChainId.MAINNET, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD//C')
export const USDT = new Token(ChainId.MAINNET, '0xdAC17F958D2ee523a2206206994597C13D831ec7', 6, 'USDT', 'Tether USD')
export const WBTC = new Token(ChainId.MAINNET, '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 8, 'WBTC', 'Wrapped BTC')
export const FEI = new Token(ChainId.MAINNET, '0x956F47F50A910163D8BF957Cf5846D573E7f87CA', 18, 'FEI', 'Fei USD')
export const TRIBE = new Token(ChainId.MAINNET, '0xc7283b66Eb1EB5FB86327f08e1B5816b0720212B', 18, 'TRIBE', 'Tribe')
export const FRAX = new Token(ChainId.MAINNET, '0x853d955aCEf822Db058eb8505911ED77F175b99e', 18, 'FRAX', 'Frax')
export const FXS = new Token(ChainId.MAINNET, '0x3432B6A60D23Ca0dFCa7761B7ab56459D9C964D0', 18, 'FXS', 'Frax Share')
export const renBTC = new Token(ChainId.MAINNET, '0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D', 8, 'renBTC', 'renBTC')
export const UMA = new Token(
ChainId.MAINNET,
'0x04Fa0d235C4abf4BcF4787aF4CF447DE572eF828',
18,
'UMA',
'UMA Voting Token v1'
)
// Mirror Protocol compat.
export const UST = new Token(ChainId.MAINNET, '0xa47c8bf37f92abed4a126bda807a7b7498661acd', 18, 'UST', 'Wrapped UST')
export const MIR = new Token(ChainId.MAINNET, '0x09a3ecafa817268f77be1283176b946c4ff2e608', 18, 'MIR', 'Wrapped MIR')
// List of all mirror's assets addresses.
// Last pulled from : https://whitelist.mirror.finance/eth/tokenlists.json
// TODO: Generate this programaticaly ?
const mAssetsAdditionalBases: { [tokenAddress: string]: Token[] } = {
[UST.address]: [MIR],
[MIR.address]: [UST],
'0xd36932143F6eBDEDD872D5Fb0651f4B72Fd15a84': [MIR, UST], // mAAPL
'0x59A921Db27Dd6d4d974745B7FfC5c33932653442': [MIR, UST], // mGOOGL
'0x21cA39943E91d704678F5D00b6616650F066fD63': [MIR, UST], // mTSLA
'0xC8d674114bac90148d11D3C1d33C61835a0F9DCD': [MIR, UST], // mNFLX
'0x13B02c8dE71680e71F0820c996E4bE43c2F57d15': [MIR, UST], // mQQQ
'0xEdb0414627E6f1e3F082DE65cD4F9C693D78CCA9': [MIR, UST], // mTWTR
'0x41BbEDd7286dAab5910a1f15d12CBda839852BD7': [MIR, UST], // mMSFT
'0x0cae9e4d663793c2a2A0b211c1Cf4bBca2B9cAa7': [MIR, UST], // mAMZN
'0x56aA298a19C93c6801FDde870fA63EF75Cc0aF72': [MIR, UST], // mBABA
'0x1d350417d9787E000cc1b95d70E9536DcD91F373': [MIR, UST], // mIAU
'0x9d1555d8cB3C846Bb4f7D5B1B1080872c3166676': [MIR, UST], // mSLV
'0x31c63146a635EB7465e5853020b39713AC356991': [MIR, UST], // mUSO
'0xf72FCd9DCF0190923Fadd44811E240Ef4533fc86': [MIR, UST], // mVIXY
}
// Block time here is slightly higher (~1s) than average in order to avoid ongoing proposals past the displayed time
export const AVERAGE_BLOCK_TIME_IN_SECS = 13
export const PROPOSAL_LENGTH_IN_BLOCKS = 40_320
export const PROPOSAL_LENGTH_IN_SECS = AVERAGE_BLOCK_TIME_IN_SECS * PROPOSAL_LENGTH_IN_BLOCKS
export const GOVERNANCE_ADDRESS = '0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F'
export const TIMELOCK_ADDRESS = '0x1a9C8182C09F50C8318d769245beA52c32BE35BC'
const UNI_ADDRESS = '0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984'
export const UNI: { [chainId in ChainId]: Token } = {
[ChainId.MAINNET]: new Token(ChainId.MAINNET, UNI_ADDRESS, 18, 'UNI', 'Uniswap'),
[ChainId.RINKEBY]: new Token(ChainId.RINKEBY, UNI_ADDRESS, 18, 'UNI', 'Uniswap'),
[ChainId.ROPSTEN]: new Token(ChainId.ROPSTEN, UNI_ADDRESS, 18, 'UNI', 'Uniswap'),
[ChainId.GÖRLI]: new Token(ChainId.GÖRLI, UNI_ADDRESS, 18, 'UNI', 'Uniswap'),
[ChainId.KOVAN]: new Token(ChainId.KOVAN, UNI_ADDRESS, 18, 'UNI', 'Uniswap'),
}
export const COMMON_CONTRACT_NAMES: { [address: string]: string } = {
[UNI_ADDRESS]: 'UNI',
[GOVERNANCE_ADDRESS]: 'Governance',
[TIMELOCK_ADDRESS]: 'Timelock',
}
export const MERKLE_DISTRIBUTOR_ADDRESS: { [chainId in ChainId]?: string } = {
[ChainId.MAINNET]: '0x090D4613473dEE047c3f2706764f49E0821D256e',
}
const WETH_ONLY: ChainTokenList = {
[ChainId.MAINNET]: [WETH9[ChainId.MAINNET]],
[ChainId.ROPSTEN]: [WETH9[ChainId.ROPSTEN]],
[ChainId.RINKEBY]: [WETH9[ChainId.RINKEBY]],
[ChainId.GÖRLI]: [WETH9[ChainId.GÖRLI]],
[ChainId.KOVAN]: [WETH9[ChainId.KOVAN]],
}
// used to construct intermediary pairs for trading
export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = {
...WETH_ONLY,
[ChainId.MAINNET]: [...WETH_ONLY[ChainId.MAINNET], DAI, USDC, USDT, WBTC],
}
export const ADDITIONAL_BASES: { [chainId in ChainId]?: { [tokenAddress: string]: Token[] } } = {
[ChainId.MAINNET]: {
...mAssetsAdditionalBases,
'0xA948E86885e12Fb09AfEF8C52142EBDbDf73cD18': [UNI[ChainId.MAINNET]],
'0x561a4717537ff4AF5c687328c0f7E90a319705C0': [UNI[ChainId.MAINNET]],
'0xa6e3454fec677772dd771788a079355e43910638': [UMA],
[FEI.address]: [TRIBE],
[TRIBE.address]: [FEI],
[FRAX.address]: [FXS],
[FXS.address]: [FRAX],
[WBTC.address]: [renBTC],
[renBTC.address]: [WBTC],
},
}
/**
* Some tokens can only be swapped via certain pairs, so we override the list of bases that are considered for these
* tokens.
*/
export const CUSTOM_BASES: { [chainId in ChainId]?: { [tokenAddress: string]: Token[] } } = {
[ChainId.MAINNET]: {
[AMPL.address]: [DAI, WETH9[ChainId.MAINNET]],
},
}
// used for display in the default list when adding liquidity
export const SUGGESTED_BASES: Partial<ChainTokenList> = {
[ChainId.MAINNET]: [DAI, USDC, USDT, WBTC],
}
// used to construct the list of all pairs we consider by default in the frontend
export const BASES_TO_TRACK_LIQUIDITY_FOR: ChainTokenList = {
...WETH_ONLY,
[ChainId.MAINNET]: [...WETH_ONLY[ChainId.MAINNET], DAI, USDC, USDT, WBTC],
}
export const PINNED_PAIRS: { readonly [chainId in ChainId]?: [Token, Token][] } = {
[ChainId.MAINNET]: [
[
new Token(ChainId.MAINNET, '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643', 8, 'cDAI', 'Compound Dai'),
new Token(ChainId.MAINNET, '0x39AA39c021dfbaE8faC545936693aC917d5E7563', 8, 'cUSDC', 'Compound USD Coin'),
],
[USDC, USDT],
[DAI, USDT],
],
}
export interface WalletInfo {
connector?: AbstractConnector
name: string
iconURL: string
description: string
href: string | null
color: string
primary?: true
mobile?: true
mobileOnly?: true
}
export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
INJECTED: {
connector: injected,
name: 'Injected',
iconURL: INJECTED_ICON_URL,
description: 'Injected web3 provider.',
href: null,
color: '#010101',
primary: true,
},
METAMASK: {
connector: injected,
name: 'MetaMask',
iconURL: METAMASK_ICON_URL,
description: 'Easy-to-use browser extension.',
href: null,
color: '#E8831D',
},
WALLET_CONNECT: {
connector: walletconnect,
name: 'WalletConnect',
iconURL: WALLETCONNECT_ICON_URL,
description: 'Connect to Trust Wallet, Rainbow Wallet and more...',
href: null,
color: '#4196FC',
mobile: true,
},
WALLET_LINK: {
connector: walletlink,
name: 'Coinbase Wallet',
iconURL: COINBASE_ICON_URL,
description: 'Use Coinbase Wallet app on mobile device',
href: null,
color: '#315CF5',
},
COINBASE_LINK: {
name: 'Open in Coinbase Wallet',
iconURL: COINBASE_ICON_URL,
description: 'Open in Coinbase Wallet app.',
href: 'https://go.cb-w.com/mtUDhEZPy1',
color: '#315CF5',
mobile: true,
mobileOnly: true,
},
FORTMATIC: {
connector: fortmatic,
name: 'Fortmatic',
iconURL: FORTMATIC_ICON_URL,
description: 'Login using Fortmatic hosted wallet',
href: null,
color: '#6748FF',
mobile: true,
},
Portis: {
connector: portis,
name: 'Portis',
iconURL: PORTIS_ICON_URL,
description: 'Login using Portis hosted wallet',
href: null,
color: '#4A6C9B',
mobile: true,
},
}
export const NetworkContextName = 'NETWORK'
// 30 minutes, denominated in seconds
export const DEFAULT_DEADLINE_FROM_NOW = 60 * 30
// used for rewards deadlines
export const BIG_INT_SECONDS_IN_WEEK = JSBI.BigInt(60 * 60 * 24 * 7)
export const BIG_INT_ZERO = JSBI.BigInt(0)
// one basis JSBI.BigInt
export const ONE_BIPS = new Percent(JSBI.BigInt(1), JSBI.BigInt(10))
export const BIPS_BASE = JSBI.BigInt(10000)
// used for warning states
export const ALLOWED_PRICE_IMPACT_LOW: Percent = new Percent(JSBI.BigInt(100), BIPS_BASE) // 1%
export const ALLOWED_PRICE_IMPACT_MEDIUM: Percent = new Percent(JSBI.BigInt(300), BIPS_BASE) // 3%
export const ALLOWED_PRICE_IMPACT_HIGH: Percent = new Percent(JSBI.BigInt(500), BIPS_BASE) // 5%
// if the price slippage exceeds this number, force the user to type 'confirm' to execute
export const PRICE_IMPACT_WITHOUT_FEE_CONFIRM_MIN: Percent = new Percent(JSBI.BigInt(1000), BIPS_BASE) // 10%
// for non expert mode disable swaps above this
export const BLOCKED_PRICE_IMPACT_NON_EXPERT: Percent = new Percent(JSBI.BigInt(1500), BIPS_BASE) // 15%
// used to ensure the user doesn't send so much ETH so they end up with <.01
export const MIN_ETH: JSBI = JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(16)) // .01 ETH
export const BETTER_TRADE_LESS_HOPS_THRESHOLD = new Percent(JSBI.BigInt(50), JSBI.BigInt(10000))
export const ZERO_PERCENT = new Percent('0')
export const ONE_HUNDRED_PERCENT = new Percent('1')
// SDN OFAC addresses
export const BLOCKED_ADDRESSES: string[] = [
'0x7F367cC41522cE07553e823bf3be79A889DEbe1B',
'0xd882cFc20F52f2599D84b8e8D58C7FB62cfE344b',
'0x901bb9583b24D97e995513C6778dc6888AB6870e',
'0xA7e5d5A720f06526557c513402f2e6B5fA20b008',
'0x8576aCC5C05D6Ce88f4e49bf65BdF0C62F91353C',
]
export const ARGENT_WALLET_DETECTOR_MAINNET_ADDRESS = '0xeca4B0bDBf7c55E9b7925919d03CbF8Dc82537E8'
export const V1_MIGRATOR_ADDRESS = '0x16D4F26C15f3658ec65B1126ff27DD3dF2a2996b'

33
src/constants/misc.ts Normal file
View File

@@ -0,0 +1,33 @@
import { Percent } from '@uniswap/sdk-core'
import JSBI from 'jsbi'
export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'
export const NetworkContextName = 'NETWORK'
// 30 minutes, denominated in seconds
export const DEFAULT_DEADLINE_FROM_NOW = 60 * 30
// used for rewards deadlines
export const BIG_INT_SECONDS_IN_WEEK = JSBI.BigInt(60 * 60 * 24 * 7)
export const BIG_INT_ZERO = JSBI.BigInt(0)
// one basis JSBI.BigInt
export const ONE_BIPS = new Percent(JSBI.BigInt(1), JSBI.BigInt(10000))
export const BIPS_BASE = JSBI.BigInt(10000)
// used for warning states
export const ALLOWED_PRICE_IMPACT_LOW: Percent = new Percent(JSBI.BigInt(100), BIPS_BASE) // 1%
export const ALLOWED_PRICE_IMPACT_MEDIUM: Percent = new Percent(JSBI.BigInt(300), BIPS_BASE) // 3%
export const ALLOWED_PRICE_IMPACT_HIGH: Percent = new Percent(JSBI.BigInt(500), BIPS_BASE) // 5%
// if the price slippage exceeds this number, force the user to type 'confirm' to execute
export const PRICE_IMPACT_WITHOUT_FEE_CONFIRM_MIN: Percent = new Percent(JSBI.BigInt(1000), BIPS_BASE) // 10%
// for non expert mode disable swaps above this
export const BLOCKED_PRICE_IMPACT_NON_EXPERT: Percent = new Percent(JSBI.BigInt(1500), BIPS_BASE) // 15%
// used to ensure the user doesn't send so much ETH so they end up with <.01
export const MIN_ETH: JSBI = JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(16)) // .01 ETH
export const BETTER_TRADE_LESS_HOPS_THRESHOLD = new Percent(JSBI.BigInt(50), JSBI.BigInt(10000))
export const ZERO_PERCENT = new Percent('0')
export const ONE_HUNDRED_PERCENT = new Percent('1')

View File

@@ -1,4 +1,6 @@
import { UNISWAP_GRANTS } from './uniswap_grants'
import { UNISWAP_GRANTS_PROPOSAL_DESCRIPTION } from './uniswap_grants_proposal_description'
// Proposals are 0-indexed
export const PRELOADED_PROPOSALS = new Map([[2, UNISWAP_GRANTS]])
export const PROPOSAL_DESCRIPTION_TEXT: { [proposalId: number]: string } = {
[2]: UNISWAP_GRANTS_PROPOSAL_DESCRIPTION,
}

View File

@@ -1,4 +1,4 @@
export const UNISWAP_GRANTS = `# Uniswap Grants Program v0.1
export const UNISWAP_GRANTS_PROPOSAL_DESCRIPTION = `# Uniswap Grants Program v0.1
*co-authored with [Ken Ng](https://twitter.com/nkennethk?lang=en)*

81
src/constants/routing.ts Normal file
View File

@@ -0,0 +1,81 @@
// a list of tokens by chain
import { ChainId, Token, WETH9 } from '@uniswap/sdk-core'
import { AMPL, DAI, FEI, FRAX, FXS, MIR, renBTC, TRIBE, UMA, UNI, USDC, USDT, UST, WBTC } from './tokens'
type ChainTokenList = {
readonly [chainId in ChainId]: Token[]
}
// List of all mirror's assets addresses.
// Last pulled from : https://whitelist.mirror.finance/eth/tokenlists.json
// TODO: Generate this programmatically ?
const mAssetsAdditionalBases: { [tokenAddress: string]: Token[] } = {
[UST.address]: [MIR],
[MIR.address]: [UST],
'0xd36932143F6eBDEDD872D5Fb0651f4B72Fd15a84': [MIR, UST], // mAAPL
'0x59A921Db27Dd6d4d974745B7FfC5c33932653442': [MIR, UST], // mGOOGL
'0x21cA39943E91d704678F5D00b6616650F066fD63': [MIR, UST], // mTSLA
'0xC8d674114bac90148d11D3C1d33C61835a0F9DCD': [MIR, UST], // mNFLX
'0x13B02c8dE71680e71F0820c996E4bE43c2F57d15': [MIR, UST], // mQQQ
'0xEdb0414627E6f1e3F082DE65cD4F9C693D78CCA9': [MIR, UST], // mTWTR
'0x41BbEDd7286dAab5910a1f15d12CBda839852BD7': [MIR, UST], // mMSFT
'0x0cae9e4d663793c2a2A0b211c1Cf4bBca2B9cAa7': [MIR, UST], // mAMZN
'0x56aA298a19C93c6801FDde870fA63EF75Cc0aF72': [MIR, UST], // mBABA
'0x1d350417d9787E000cc1b95d70E9536DcD91F373': [MIR, UST], // mIAU
'0x9d1555d8cB3C846Bb4f7D5B1B1080872c3166676': [MIR, UST], // mSLV
'0x31c63146a635EB7465e5853020b39713AC356991': [MIR, UST], // mUSO
'0xf72FCd9DCF0190923Fadd44811E240Ef4533fc86': [MIR, UST], // mVIXY
}
const WETH_ONLY: ChainTokenList = {
[ChainId.MAINNET]: [WETH9[ChainId.MAINNET]],
[ChainId.ROPSTEN]: [WETH9[ChainId.ROPSTEN]],
[ChainId.RINKEBY]: [WETH9[ChainId.RINKEBY]],
[ChainId.GÖRLI]: [WETH9[ChainId.GÖRLI]],
[ChainId.KOVAN]: [WETH9[ChainId.KOVAN]],
}
// used to construct intermediary pairs for trading
export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = {
...WETH_ONLY,
[ChainId.MAINNET]: [...WETH_ONLY[ChainId.MAINNET], DAI, USDC, USDT, WBTC],
}
export const ADDITIONAL_BASES: { [chainId in ChainId]?: { [tokenAddress: string]: Token[] } } = {
[ChainId.MAINNET]: {
...mAssetsAdditionalBases,
'0xA948E86885e12Fb09AfEF8C52142EBDbDf73cD18': [UNI[ChainId.MAINNET]],
'0x561a4717537ff4AF5c687328c0f7E90a319705C0': [UNI[ChainId.MAINNET]],
'0xa6e3454fec677772dd771788a079355e43910638': [UMA],
[FEI.address]: [TRIBE],
[TRIBE.address]: [FEI],
[FRAX.address]: [FXS],
[FXS.address]: [FRAX],
[WBTC.address]: [renBTC],
[renBTC.address]: [WBTC],
},
}
/**
* Some tokens can only be swapped via certain pairs, so we override the list of bases that are considered for these
* tokens.
*/
export const CUSTOM_BASES: { [chainId in ChainId]?: { [tokenAddress: string]: Token[] } } = {
[ChainId.MAINNET]: {
[AMPL.address]: [DAI, WETH9[ChainId.MAINNET]],
},
}
// used for display in the default list when adding liquidity
export const SUGGESTED_BASES: Partial<ChainTokenList> = {
[ChainId.MAINNET]: [DAI, USDC, USDT, WBTC],
}
// used to construct the list of all pairs we consider by default in the frontend
export const BASES_TO_TRACK_LIQUIDITY_FOR: ChainTokenList = {
...WETH_ONLY,
[ChainId.MAINNET]: [...WETH_ONLY[ChainId.MAINNET], DAI, USDC, USDT, WBTC],
}
export const PINNED_PAIRS: { readonly [chainId in ChainId]?: [Token, Token][] } = {
[ChainId.MAINNET]: [
[
new Token(ChainId.MAINNET, '0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643', 8, 'cDAI', 'Compound Dai'),
new Token(ChainId.MAINNET, '0x39AA39c021dfbaE8faC545936693aC917d5E7563', 8, 'cUSDC', 'Compound USD Coin'),
],
[USDC, USDT],
[DAI, USDT],
],
}

30
src/constants/tokens.ts Normal file
View File

@@ -0,0 +1,30 @@
import { ChainId, Token } from '@uniswap/sdk-core'
import { UNI_ADDRESS } from './addresses'
export const AMPL = new Token(ChainId.MAINNET, '0xD46bA6D942050d489DBd938a2C909A5d5039A161', 9, 'AMPL', 'Ampleforth')
export const DAI = new Token(ChainId.MAINNET, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'Dai Stablecoin')
export const USDC = new Token(ChainId.MAINNET, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'USDC', 'USD//C')
export const USDT = new Token(ChainId.MAINNET, '0xdAC17F958D2ee523a2206206994597C13D831ec7', 6, 'USDT', 'Tether USD')
export const WBTC = new Token(ChainId.MAINNET, '0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599', 8, 'WBTC', 'Wrapped BTC')
export const FEI = new Token(ChainId.MAINNET, '0x956F47F50A910163D8BF957Cf5846D573E7f87CA', 18, 'FEI', 'Fei USD')
export const TRIBE = new Token(ChainId.MAINNET, '0xc7283b66Eb1EB5FB86327f08e1B5816b0720212B', 18, 'TRIBE', 'Tribe')
export const FRAX = new Token(ChainId.MAINNET, '0x853d955aCEf822Db058eb8505911ED77F175b99e', 18, 'FRAX', 'Frax')
export const FXS = new Token(ChainId.MAINNET, '0x3432B6A60D23Ca0dFCa7761B7ab56459D9C964D0', 18, 'FXS', 'Frax Share')
export const renBTC = new Token(ChainId.MAINNET, '0xEB4C2781e4ebA804CE9a9803C67d0893436bB27D', 8, 'renBTC', 'renBTC')
export const UMA = new Token(
ChainId.MAINNET,
'0x04Fa0d235C4abf4BcF4787aF4CF447DE572eF828',
18,
'UMA',
'UMA Voting Token v1'
)
// Mirror Protocol compat.
export const UST = new Token(ChainId.MAINNET, '0xa47c8bf37f92abed4a126bda807a7b7498661acd', 18, 'UST', 'Wrapped UST')
export const MIR = new Token(ChainId.MAINNET, '0x09a3ecafa817268f77be1283176b946c4ff2e608', 18, 'MIR', 'Wrapped MIR')
export const UNI: { [chainId in ChainId]: Token } = {
[ChainId.MAINNET]: new Token(ChainId.MAINNET, UNI_ADDRESS[ChainId.MAINNET], 18, 'UNI', 'Uniswap'),
[ChainId.RINKEBY]: new Token(ChainId.RINKEBY, UNI_ADDRESS[ChainId.RINKEBY], 18, 'UNI', 'Uniswap'),
[ChainId.ROPSTEN]: new Token(ChainId.ROPSTEN, UNI_ADDRESS[ChainId.ROPSTEN], 18, 'UNI', 'Uniswap'),
[ChainId.GÖRLI]: new Token(ChainId.GÖRLI, UNI_ADDRESS[ChainId.GÖRLI], 18, 'UNI', 'Uniswap'),
[ChainId.KOVAN]: new Token(ChainId.KOVAN, UNI_ADDRESS[ChainId.KOVAN], 18, 'UNI', 'Uniswap'),
}

View File

@@ -1,26 +0,0 @@
import { ChainId } from '@uniswap/sdk-core'
import { FACTORY_ADDRESS } from '@uniswap/v3-sdk'
function constructSameAddressMap(address: string): { [chainId in ChainId]: string } {
return {
[ChainId.MAINNET]: address,
[ChainId.ROPSTEN]: address,
[ChainId.KOVAN]: address,
[ChainId.RINKEBY]: address,
[ChainId.GÖRLI]: address,
}
}
export const V3_CORE_FACTORY_ADDRESSES = constructSameAddressMap(FACTORY_ADDRESS)
export const QUOTER_ADDRESSES = constructSameAddressMap('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6')
export const TICK_LENS_ADDRESSES = constructSameAddressMap('0xbfd8137f7d1516D3ea5cA83523914859ec47F573')
export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES = constructSameAddressMap(
'0xC36442b4a4522E871399CD717aBDD847Ab11FE88'
)
export const SWAP_ROUTER_ADDRESSES = constructSameAddressMap('0xE592427A0AEce92De3Edee1F18E0157C05861564')
export const V3_MIGRATOR_ADDRESSES = constructSameAddressMap('0xA5644E29708357803b5A882D272c41cC0dF92B34')

84
src/constants/wallet.ts Normal file
View File

@@ -0,0 +1,84 @@
import { AbstractConnector } from '@web3-react/abstract-connector'
import INJECTED_ICON_URL from '../assets/images/arrow-right.svg'
import COINBASE_ICON_URL from '../assets/images/coinbaseWalletIcon.svg'
import FORTMATIC_ICON_URL from '../assets/images/fortmaticIcon.png'
import METAMASK_ICON_URL from '../assets/images/metamask.png'
import PORTIS_ICON_URL from '../assets/images/portisIcon.png'
import WALLETCONNECT_ICON_URL from '../assets/images/walletConnectIcon.svg'
import { fortmatic, injected, portis, walletconnect, walletlink } from '../connectors'
export interface WalletInfo {
connector?: AbstractConnector
name: string
iconURL: string
description: string
href: string | null
color: string
primary?: true
mobile?: true
mobileOnly?: true
}
export const SUPPORTED_WALLETS: { [key: string]: WalletInfo } = {
INJECTED: {
connector: injected,
name: 'Injected',
iconURL: INJECTED_ICON_URL,
description: 'Injected web3 provider.',
href: null,
color: '#010101',
primary: true,
},
METAMASK: {
connector: injected,
name: 'MetaMask',
iconURL: METAMASK_ICON_URL,
description: 'Easy-to-use browser extension.',
href: null,
color: '#E8831D',
},
WALLET_CONNECT: {
connector: walletconnect,
name: 'WalletConnect',
iconURL: WALLETCONNECT_ICON_URL,
description: 'Connect to Trust Wallet, Rainbow Wallet and more...',
href: null,
color: '#4196FC',
mobile: true,
},
WALLET_LINK: {
connector: walletlink,
name: 'Coinbase Wallet',
iconURL: COINBASE_ICON_URL,
description: 'Use Coinbase Wallet app on mobile device',
href: null,
color: '#315CF5',
},
COINBASE_LINK: {
name: 'Open in Coinbase Wallet',
iconURL: COINBASE_ICON_URL,
description: 'Open in Coinbase Wallet app.',
href: 'https://go.cb-w.com/mtUDhEZPy1',
color: '#315CF5',
mobile: true,
mobileOnly: true,
},
FORTMATIC: {
connector: fortmatic,
name: 'Fortmatic',
iconURL: FORTMATIC_ICON_URL,
description: 'Login using Fortmatic hosted wallet',
href: null,
color: '#6748FF',
mobile: true,
},
Portis: {
connector: portis,
name: 'Portis',
iconURL: PORTIS_ICON_URL,
description: 'Login using Portis hosted wallet',
href: null,
color: '#4A6C9B',
mobile: true,
},
}

View File

@@ -10,7 +10,7 @@ import { useUserAddedTokens } from '../state/user/hooks'
import { isAddress } from '../utils'
import { TokenAddressMap, useUnsupportedTokenList } from './../state/lists/hooks'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useBytes32TokenContract, useTokenContract } from './useContract'
// reduce token map into standard address <-> Token mapping, optionally include user added tokens

View File

@@ -2,7 +2,7 @@ import { getTokenLogoURL } from './../components/CurrencyLogo/index'
import { wrappedCurrency } from 'utils/wrappedCurrency'
import { Currency, Token } from '@uniswap/sdk-core'
import { useCallback, useState } from 'react'
import { useActiveWeb3React } from 'hooks'
import { useActiveWeb3React } from 'hooks/web3'
export default function useAddTokenToMetamask(
currencyToAdd: Currency | undefined

View File

@@ -1,9 +1,9 @@
import { Currency, Token } from '@uniswap/sdk-core'
import flatMap from 'lodash.flatmap'
import { useMemo } from 'react'
import { ADDITIONAL_BASES, BASES_TO_CHECK_TRADES_AGAINST, CUSTOM_BASES } from '../constants'
import { ADDITIONAL_BASES, BASES_TO_CHECK_TRADES_AGAINST, CUSTOM_BASES } from '../constants/routing'
import { wrappedCurrency } from '../utils/wrappedCurrency'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
export function useAllCurrencyCombinations(currencyA?: Currency, currencyB?: Currency): [Token, Token][] {
const { chainId } = useActiveWeb3React()

View File

@@ -3,7 +3,7 @@ import { Pool, Route } from '@uniswap/v3-sdk'
import { useMemo } from 'react'
import { useUserSingleHopOnly } from '../state/user/hooks'
import { wrappedCurrency } from '../utils/wrappedCurrency'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useV3SwapPools } from './useV3SwapPools'
function computeAllRoutes(

View File

@@ -1,113 +0,0 @@
import { Token } from '@uniswap/sdk-core'
import { FeeAmount, TICK_SPACINGS } from '@uniswap/v3-sdk'
import { nearestUsableTick, TickMath } from '@uniswap/v3-sdk/dist/'
import { ZERO_ADDRESS } from '../constants'
import { useEffect, useMemo, useState } from 'react'
import { Result, useSingleCallResult, useSingleContractMultipleData } from 'state/multicall/hooks'
import { useTickLens, useV3Factory } from './useContract'
function bitmapIndex(tick: number, tickSpacing: number) {
return Math.floor(tick / tickSpacing / 256)
}
const REFRESH_FREQUENCY = { blocksPerFetch: 2 }
interface TickData {
tick: number
liquidityNet: number
liquidityGross: number
}
// for now, reconsider using this function, it consumes a lot of data and cpu to fetch all the ticks.
export function useAllV3Ticks(
token0: Token | undefined,
token1: Token | undefined,
feeAmount: FeeAmount | undefined
): {
loading: boolean
syncing: boolean
error: boolean
valid: boolean
tickData: TickData[]
} {
const tickSpacing = feeAmount && TICK_SPACINGS[feeAmount]
const minIndex = useMemo(
() => (tickSpacing ? bitmapIndex(nearestUsableTick(TickMath.MIN_TICK, tickSpacing), tickSpacing) : undefined),
[tickSpacing]
)
const maxIndex = useMemo(
() => (tickSpacing ? bitmapIndex(nearestUsableTick(TickMath.MAX_TICK, tickSpacing), tickSpacing) : undefined),
[tickSpacing]
)
const [tickDataLatestSynced, setTickDataLatestSynced] = useState<TickData[]>([])
// fetch the pool address
const factoryContract = useV3Factory()
const poolAddress = useSingleCallResult(factoryContract, 'getPool', [token0?.address, token1?.address, feeAmount])
.result?.[0]
const tickLensArgs: [string, number][] = useMemo(
() =>
maxIndex && minIndex && poolAddress && poolAddress !== ZERO_ADDRESS
? new Array(maxIndex - minIndex + 1)
.fill(0)
.map((_, i) => i + minIndex)
.map((wordIndex) => [poolAddress, wordIndex])
: [],
[minIndex, maxIndex, poolAddress]
)
const tickLens = useTickLens()
const callStates = useSingleContractMultipleData(
tickLensArgs.length > 0 ? tickLens : undefined,
'getPopulatedTicksInWord',
tickLensArgs,
REFRESH_FREQUENCY,
3_000_000
)
const error = useMemo(() => callStates.some(({ error }) => error), [callStates])
const loading = useMemo(() => callStates.some(({ loading }) => loading), [callStates])
const syncing = useMemo(() => callStates.some(({ syncing }) => syncing), [callStates])
const valid = useMemo(() => callStates.some(({ valid }) => valid), [callStates])
const tickData = useMemo(
() =>
callStates
.map(({ result }) => (result as Result)?.populatedTicks)
.reduce(
(accumulator, current) => [
...accumulator,
...(current?.map((tickData: TickData) => {
return {
tick: tickData.tick,
liquidityNet: tickData.liquidityNet,
liquidityGross: tickData.liquidityGross,
}
}) ?? []),
],
[]
),
[callStates]
)
// return the latest synced tickdata even if we are still loading the newest data
useEffect(() => {
if (!syncing && !loading && !error && valid) {
setTickDataLatestSynced(tickData)
}
}, [error, loading, syncing, tickData, valid])
return useMemo(
() => ({
loading,
syncing,
error,
valid,
tickData: tickDataLatestSynced,
}),
[loading, syncing, error, valid, tickDataLatestSynced]
)
}

View File

@@ -4,12 +4,11 @@ import { CurrencyAmount, ChainId, Percent, Currency, TradeType } from '@uniswap/
import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk'
import { useCallback, useMemo } from 'react'
import { V2_ROUTER_ADDRESS } from '../constants'
import { SWAP_ROUTER_ADDRESSES } from '../constants/v3'
import { SWAP_ROUTER_ADDRESSES, V2_ROUTER_ADDRESS } from '../constants/addresses'
import { useTransactionAdder, useHasPendingApproval } from '../state/transactions/hooks'
import { calculateGasMargin } from '../utils'
import { calculateGasMargin } from '../utils/calculateGasMargin'
import { useTokenContract } from './useContract'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useTokenAllowance } from './useTokenAllowance'
export enum ApprovalState {
@@ -104,13 +103,19 @@ export function useApproveCallbackFromTrade(
allowedSlippage: Percent
) {
const { chainId } = useActiveWeb3React()
const swapRouterAddress = SWAP_ROUTER_ADDRESSES[chainId as ChainId]
const v3SwapRouterAddress = SWAP_ROUTER_ADDRESSES[chainId as ChainId]
const amountToApprove = useMemo(
() => (trade && trade.inputAmount.currency.isToken ? trade.maximumAmountIn(allowedSlippage) : undefined),
[trade, allowedSlippage]
)
return useApproveCallback(
amountToApprove,
trade instanceof V2Trade ? V2_ROUTER_ADDRESS : trade instanceof V3Trade ? swapRouterAddress : undefined
chainId
? trade instanceof V2Trade
? V2_ROUTER_ADDRESS[chainId]
: trade instanceof V3Trade
? v3SwapRouterAddress
: undefined
: undefined
)
}

View File

@@ -9,7 +9,6 @@ import { abi as V3FactoryABI } from '@uniswap/v3-core/artifacts/contracts/Uniswa
import { abi as V3PoolABI } from '@uniswap/v3-core/artifacts/contracts/UniswapV3Pool.sol/UniswapV3Pool.json'
import { abi as QuoterABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
import { abi as V2MigratorABI } from '@uniswap/v3-periphery/artifacts/contracts/V3Migrator.sol/V3Migrator.json'
import { abi as TickLensABI } from '@uniswap/v3-periphery/artifacts/contracts/lens/TickLens.sol/TickLens.json'
import { abi as IUniswapV2Router02ABI } from '@uniswap/v2-periphery/build/IUniswapV2Router02.json'
import ARGENT_WALLET_DETECTOR_ABI from 'abis/argent-wallet-detector.json'
@@ -17,7 +16,6 @@ import ENS_PUBLIC_RESOLVER_ABI from 'abis/ens-public-resolver.json'
import ENS_ABI from 'abis/ens-registrar.json'
import ERC20_ABI from 'abis/erc20.json'
import ERC20_BYTES32_ABI from 'abis/erc20_bytes32.json'
import MIGRATOR_ABI from 'abis/migrator.json'
import MULTICALL_ABI from 'abis/multicall2.json'
import { Unisocks } from 'abis/types/Unisocks'
import UNISOCKS_ABI from 'abis/unisocks.json'
@@ -25,91 +23,74 @@ import WETH_ABI from 'abis/weth.json'
import EIP_2612 from 'abis/eip_2612.json'
import {
ARGENT_WALLET_DETECTOR_MAINNET_ADDRESS,
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
QUOTER_ADDRESSES,
V3_CORE_FACTORY_ADDRESSES,
V3_MIGRATOR_ADDRESSES,
ARGENT_WALLET_DETECTOR_ADDRESS,
GOVERNANCE_ADDRESS,
MERKLE_DISTRIBUTOR_ADDRESS,
V1_MIGRATOR_ADDRESS,
UNI,
MULTICALL2_ADDRESSES,
V2_ROUTER_ADDRESS,
} from 'constants/index'
ENS_REGISTRAR_ADDRESSES,
SOCKS_CONTROLLER_ADDRESSES,
} from 'constants/addresses'
import { abi as NFTPositionManagerABI } from '@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json'
import {
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
V3_CORE_FACTORY_ADDRESSES,
TICK_LENS_ADDRESSES,
V3_MIGRATOR_ADDRESSES,
QUOTER_ADDRESSES,
} from 'constants/v3'
import { useMemo } from 'react'
import { Quoter, TickLens, UniswapV3Factory, UniswapV3Pool } from 'types/v3'
import { Quoter, UniswapV3Factory, UniswapV3Pool } from 'types/v3'
import { NonfungiblePositionManager } from 'types/v3/NonfungiblePositionManager'
import { V3Migrator } from 'types/v3/V3Migrator'
import { getContract } from 'utils'
import { Multicall2 } from '../abis/types'
import { useActiveWeb3React } from './index'
import { ArgentWalletDetector, EnsPublicResolver, EnsRegistrar, Erc20, Multicall2, Weth } from '../abis/types'
import { UNI } from '../constants/tokens'
import { useActiveWeb3React } from './web3'
// returns null on errors
export function useContract(address: string | undefined, ABI: any, withSignerIfPossible = true): Contract | null {
const { library, account } = useActiveWeb3React()
export function useContract<T extends Contract = Contract>(
addressOrAddressMap: string | { [chainId in ChainId]?: string } | undefined,
ABI: any,
withSignerIfPossible = true
): T | null {
const { library, account, chainId } = useActiveWeb3React()
return useMemo(() => {
if (!address || !ABI || !library) return null
if (!addressOrAddressMap || !ABI || !library || !chainId) return null
let address: string | undefined
if (typeof addressOrAddressMap === 'string') address = addressOrAddressMap
else address = addressOrAddressMap[chainId]
if (!address) return null
try {
return getContract(address, ABI, library, withSignerIfPossible && account ? account : undefined)
} catch (error) {
console.error('Failed to get contract', error)
return null
}
}, [address, ABI, library, withSignerIfPossible, account])
}, [addressOrAddressMap, ABI, library, chainId, withSignerIfPossible, account]) as T
}
export function useV1MigratorContract(): Contract | null {
return useContract(V1_MIGRATOR_ADDRESS, MIGRATOR_ABI, true)
export function useV2MigratorContract() {
return useContract<V3Migrator>(V3_MIGRATOR_ADDRESSES, V2MigratorABI, true)
}
export function useV2MigratorContract(): V3Migrator | null {
export function useTokenContract(tokenAddress?: string, withSignerIfPossible?: boolean) {
return useContract<Erc20>(tokenAddress, ERC20_ABI, withSignerIfPossible)
}
export function useWETHContract(withSignerIfPossible?: boolean) {
const { chainId } = useActiveWeb3React()
return useContract(chainId && V3_MIGRATOR_ADDRESSES[chainId], V2MigratorABI, true) as V3Migrator | null
return useContract<Weth>(chainId ? WETH9[chainId]?.address : undefined, WETH_ABI, withSignerIfPossible)
}
export function useTokenContract(tokenAddress?: string, withSignerIfPossible?: boolean): Contract | null {
return useContract(tokenAddress, ERC20_ABI, withSignerIfPossible)
export function useArgentWalletDetectorContract() {
return useContract<ArgentWalletDetector>(ARGENT_WALLET_DETECTOR_ADDRESS, ARGENT_WALLET_DETECTOR_ABI, false)
}
export function useWETHContract(withSignerIfPossible?: boolean): Contract | null {
const { chainId } = useActiveWeb3React()
const address = chainId && chainId in WETH9 ? WETH9[chainId].address : undefined
return useContract(address, WETH_ABI, withSignerIfPossible)
export function useENSRegistrarContract(withSignerIfPossible?: boolean) {
return useContract<EnsRegistrar>(ENS_REGISTRAR_ADDRESSES, ENS_ABI, withSignerIfPossible)
}
export function useArgentWalletDetectorContract(): Contract | null {
const { chainId } = useActiveWeb3React()
return useContract(
chainId === ChainId.MAINNET ? ARGENT_WALLET_DETECTOR_MAINNET_ADDRESS : undefined,
ARGENT_WALLET_DETECTOR_ABI,
false
)
}
export function useENSRegistrarContract(withSignerIfPossible?: boolean): Contract | null {
const { chainId } = useActiveWeb3React()
let address: string | undefined
if (chainId) {
switch (chainId) {
case ChainId.MAINNET:
case ChainId.GÖRLI:
case ChainId.ROPSTEN:
case ChainId.RINKEBY:
address = '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e'
break
}
}
return useContract(address, ENS_ABI, withSignerIfPossible)
}
export function useENSResolverContract(address: string | undefined, withSignerIfPossible?: boolean): Contract | null {
return useContract(address, ENS_PUBLIC_RESOLVER_ABI, withSignerIfPossible)
export function useENSResolverContract(address: string | undefined, withSignerIfPossible?: boolean) {
return useContract<EnsPublicResolver>(address, ENS_PUBLIC_RESOLVER_ABI, withSignerIfPossible)
}
export function useBytes32TokenContract(tokenAddress?: string, withSignerIfPossible?: boolean): Contract | null {
@@ -128,61 +109,47 @@ export function useV2RouterContract(): Contract | null {
return useContract(V2_ROUTER_ADDRESS, IUniswapV2Router02ABI, true)
}
export function useMulticall2Contract(): Multicall2 | null {
const { chainId } = useActiveWeb3React()
return useContract(chainId && MULTICALL2_ADDRESSES[chainId], MULTICALL_ABI, false) as Multicall2
export function useMulticall2Contract() {
return useContract<Multicall2>(MULTICALL2_ADDRESSES, MULTICALL_ABI, false) as Multicall2
}
export function useMerkleDistributorContract(): Contract | null {
const { chainId } = useActiveWeb3React()
return useContract(chainId ? MERKLE_DISTRIBUTOR_ADDRESS[chainId] : undefined, MERKLE_DISTRIBUTOR_ABI, true)
export function useMerkleDistributorContract() {
return useContract(MERKLE_DISTRIBUTOR_ADDRESS, MERKLE_DISTRIBUTOR_ABI, true)
}
export function useGovernanceContract(): Contract | null {
export function useGovernanceContract() {
return useContract(GOVERNANCE_ADDRESS, GOVERNANCE_ABI, true)
}
export function useUniContract(): Contract | null {
export function useUniContract() {
const { chainId } = useActiveWeb3React()
return useContract(chainId ? UNI[chainId].address : undefined, UNI_ABI, true)
return useContract(chainId ? UNI[chainId]?.address : undefined, UNI_ABI, true)
}
export function useStakingContract(stakingAddress?: string, withSignerIfPossible?: boolean): Contract | null {
export function useStakingContract(stakingAddress?: string, withSignerIfPossible?: boolean) {
return useContract(stakingAddress, STAKING_REWARDS_ABI, withSignerIfPossible)
}
export function useSocksController(): Unisocks | null {
const { chainId } = useActiveWeb3React()
return useContract(
chainId === ChainId.MAINNET ? '0x65770b5283117639760beA3F867b69b3697a91dd' : undefined,
UNISOCKS_ABI,
false
) as Unisocks | null
return useContract<Unisocks>(SOCKS_CONTROLLER_ADDRESSES, UNISOCKS_ABI, false)
}
export function useV3NFTPositionManagerContract(withSignerIfPossible?: boolean): NonfungiblePositionManager | null {
const { chainId } = useActiveWeb3React()
const address = chainId ? NONFUNGIBLE_POSITION_MANAGER_ADDRESSES[chainId] : undefined
return useContract(address, NFTPositionManagerABI, withSignerIfPossible) as NonfungiblePositionManager | null
return useContract<NonfungiblePositionManager>(
NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
NFTPositionManagerABI,
withSignerIfPossible
)
}
export function useV3Factory(): UniswapV3Factory | null {
const { chainId } = useActiveWeb3React()
const address = chainId ? V3_CORE_FACTORY_ADDRESSES[chainId] : undefined
return useContract(address, V3FactoryABI) as UniswapV3Factory | null
export function useV3Factory() {
return useContract<UniswapV3Factory>(V3_CORE_FACTORY_ADDRESSES, V3FactoryABI) as UniswapV3Factory | null
}
export function useV3Pool(address: string | undefined): UniswapV3Pool | null {
return useContract(address, V3PoolABI) as UniswapV3Pool | null
export function useV3Pool(address: string | undefined) {
return useContract<UniswapV3Pool>(address, V3PoolABI)
}
export function useV3Quoter(): Quoter | null {
const { chainId } = useActiveWeb3React()
return useContract(chainId ? QUOTER_ADDRESSES[chainId] : undefined, QuoterABI) as Quoter | null
}
export function useTickLens(): TickLens | null {
const { chainId } = useActiveWeb3React()
const address = chainId ? TICK_LENS_ADDRESSES[chainId] : undefined
return useContract(address, TickLensABI) as TickLens | null
export function useV3Quoter() {
return useContract<Quoter>(QUOTER_ADDRESSES, QuoterABI)
}

View File

@@ -4,10 +4,10 @@ import { Trade as V2Trade } from '@uniswap/v2-sdk'
import { Trade as V3Trade } from '@uniswap/v3-sdk'
import { splitSignature } from 'ethers/lib/utils'
import { useMemo, useState } from 'react'
import { UNI, USDC, DAI } from '../constants'
import { SWAP_ROUTER_ADDRESSES } from '../constants/v3'
import { SWAP_ROUTER_ADDRESSES } from '../constants/addresses'
import { DAI, UNI, USDC } from '../constants/tokens'
import { useSingleCallResult } from '../state/multicall/hooks'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useEIP2612Contract } from './useContract'
import useIsArgentWallet from './useIsArgentWallet'
import useTransactionDeadline from './useTransactionDeadline'

View File

@@ -8,7 +8,7 @@ import { AppDispatch } from '../state'
import { fetchTokenList } from '../state/lists/actions'
import getTokenList from '../utils/getTokenList'
import resolveENSContentHash from '../utils/resolveENSContentHash'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
export function useFetchListCallback(): (listUrl: string, sendDispatch?: boolean) => Promise<TokenList> {
const { chainId, library } = useActiveWeb3React()

View File

@@ -1,5 +1,5 @@
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useArgentWalletDetectorContract } from './useContract'
export default function useIsArgentWallet(): boolean {

View File

@@ -1,12 +1,12 @@
import { computePoolAddress } from '@uniswap/v3-sdk'
import { V3_CORE_FACTORY_ADDRESSES } from '../constants/addresses'
import { IUniswapV3PoolStateInterface } from '../types/v3/IUniswapV3PoolState'
import { Token, Currency } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useMultipleContractSingleData } from '../state/multicall/hooks'
import { wrappedCurrency } from '../utils/wrappedCurrency'
import { Pool, FeeAmount } from '@uniswap/v3-sdk'
import { V3_CORE_FACTORY_ADDRESSES } from 'constants/v3'
import { abi as IUniswapV3PoolStateABI } from '@uniswap/v3-core/artifacts/contracts/interfaces/pool/IUniswapV3PoolState.sol/IUniswapV3PoolState.json'
import { Interface } from '@ethersproject/abi'

View File

@@ -1,7 +1,7 @@
import JSBI from 'jsbi'
import { useMemo } from 'react'
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useSocksController } from './useContract'
export default function useSocksBalance(): JSBI | undefined {

View File

@@ -3,12 +3,13 @@ import { Router, Trade as V2Trade } from '@uniswap/v2-sdk'
import { SwapRouter, Trade as V3Trade } from '@uniswap/v3-sdk'
import { ChainId, Currency, Percent, TradeType } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { SWAP_ROUTER_ADDRESSES } from '../constants/v3'
import { SWAP_ROUTER_ADDRESSES } from '../constants/addresses'
import { calculateGasMargin } from '../utils/calculateGasMargin'
import { getTradeVersion } from '../utils/getTradeVersion'
import { useTransactionAdder } from '../state/transactions/hooks'
import { calculateGasMargin, isAddress, shortenAddress } from '../utils'
import { isAddress, shortenAddress } from '../utils'
import isZero from '../utils/isZero'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useV2RouterContract } from './useContract'
import { SignatureData } from './useERC20Permit'
import useTransactionDeadline from './useTransactionDeadline'
@@ -166,7 +167,13 @@ export function swapErrorToUserReadableMessage(error: any): string {
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${reason ? `: "${reason}"` : ''}. Please join the Discord to get help.`
if (reason?.indexOf('undefined is not an object') !== -1) {
console.error(error, reason)
return 'An error occurred when trying to execute this swap. You may need to increase your slippage tolerance. If that does not work, there may be an incompatibility with the token you are trading. Note fee on transfer and rebase tokens are incompatible with Uniswap V3.'
}
return `Unknown error${
reason ? `: "${reason}"` : ''
}. Try increasing your slippage tolerance. Note fee on transfer and rebase tokens are incompatible with Uniswap V3.`
}
}

View File

@@ -1,19 +0,0 @@
import { useActiveWeb3React } from '.'
import { useState, useEffect } from 'react'
export function useTimestampFromBlock(block: number | undefined): number | undefined {
const { library } = useActiveWeb3React()
const [timestamp, setTimestamp] = useState<number>()
useEffect(() => {
async function fetchTimestamp() {
if (block) {
const blockData = await library?.getBlock(block)
blockData && setTimestamp(blockData.timestamp)
}
}
if (!timestamp) {
fetchTimestamp()
}
}, [block, library, timestamp])
return timestamp
}

View File

@@ -1,10 +1,13 @@
import { ChainId, Currency, CurrencyAmount, currencyEquals, Price, Token, WETH9 } from '@uniswap/sdk-core'
import JSBI from 'jsbi'
import { ChainId, Currency, CurrencyAmount, Price, Token } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { USDC } from '../constants'
import { PairState, useV2Pairs } from './useV2Pairs'
import { useActiveWeb3React } from '../hooks'
import { wrappedCurrency } from '../utils/wrappedCurrency'
import { USDC } from '../constants/tokens'
import { useV2TradeExactOut } from './useV2Trade'
import { useBestV3TradeExactOut, V3TradeState } from './useBestV3Trade'
import { useActiveWeb3React } from './web3'
// USDC amount used when calculating spot price for a given currency.
// The amount is large enough to filter low liquidity pairs.
const usdcCurrencyAmount = CurrencyAmount.fromRawAmount(USDC, 100_000e6)
/**
* Returns the price in USDC of the input currency
@@ -12,23 +15,17 @@ import { wrappedCurrency } from '../utils/wrappedCurrency'
*/
export default function useUSDCPrice(currency?: Currency): Price<Currency, Token> | undefined {
const { chainId } = useActiveWeb3React()
const wrapped = wrappedCurrency(currency, chainId)
const weth = WETH9[chainId as ChainId]
const tokenPairs: [Currency | undefined, Currency | undefined][] = useMemo(
() => [
[chainId && wrapped && currencyEquals(weth, wrapped) ? undefined : currency, chainId ? weth : undefined],
[wrapped?.equals(USDC) ? undefined : wrapped, chainId === ChainId.MAINNET ? USDC : undefined],
[chainId ? weth : undefined, chainId === ChainId.MAINNET ? USDC : undefined],
],
[chainId, currency, weth, wrapped]
)
const [[ethPairState, ethPair], [usdcPairState, usdcPair], [usdcEthPairState, usdcEthPair]] = useV2Pairs(tokenPairs)
const v2USDCTrade = useV2TradeExactOut(currency, chainId === ChainId.MAINNET ? usdcCurrencyAmount : undefined, {
maxHops: 2,
})
const v3USDCTrade = useBestV3TradeExactOut(currency, chainId === ChainId.MAINNET ? usdcCurrencyAmount : undefined)
return useMemo(() => {
if (!currency || !wrapped || !chainId) {
if (!currency || !chainId) {
return undefined
}
// return some fake price data for non-mainnet
if (chainId !== ChainId.MAINNET) {
const fakeUSDC = new Token(chainId, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 6, 'fUSDC', 'Fake USDC')
@@ -40,42 +37,17 @@ export default function useUSDCPrice(currency?: Currency): Price<Currency, Token
)
}
// handle weth/eth
if (wrapped.equals(weth)) {
if (usdcPair) {
const price = usdcPair.priceOf(weth)
return new Price(currency, USDC, price.denominator, price.numerator)
} else {
return undefined
}
}
// handle usdc
if (wrapped.equals(USDC)) {
return new Price(USDC, USDC, '1', '1')
// use v2 price if available, v3 as fallback
if (v2USDCTrade) {
const { numerator, denominator } = v2USDCTrade.route.midPrice
return new Price(currency, USDC, denominator, numerator)
} else if (v3USDCTrade.state === V3TradeState.VALID && v3USDCTrade.trade) {
const { numerator, denominator } = v3USDCTrade.trade.route.midPrice
return new Price(currency, USDC, denominator, numerator)
}
const ethPairETHAmount = ethPair?.reserveOf(weth)
const ethPairETHUSDCValue: JSBI =
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
if (usdcPairState === PairState.EXISTS && usdcPair && usdcPair.reserveOf(USDC).greaterThan(ethPairETHUSDCValue)) {
const price = usdcPair.priceOf(wrapped)
return new Price(currency, USDC, price.denominator, price.numerator)
}
if (ethPairState === PairState.EXISTS && ethPair && usdcEthPairState === PairState.EXISTS && usdcEthPair) {
if (usdcEthPair.reserveOf(USDC).greaterThan('0') && ethPair.reserveOf(weth).greaterThan('0')) {
const ethUsdcPrice = usdcEthPair.priceOf(USDC)
const currencyEthPrice = ethPair.priceOf(weth)
const usdcPrice = ethUsdcPrice.multiply(currencyEthPrice).invert()
return new Price(currency, USDC, usdcPrice.denominator, usdcPrice.numerator)
}
}
return undefined
}, [chainId, currency, ethPair, ethPairState, usdcEthPair, usdcEthPairState, usdcPair, usdcPairState, weth, wrapped])
}, [chainId, currency, v2USDCTrade, v3USDCTrade])
}
export function useUSDCValue(currencyAmount: CurrencyAmount<Currency> | undefined | null) {

View File

@@ -2,7 +2,7 @@ import { Pair } from '@uniswap/v2-sdk'
import { useMemo } from 'react'
import { abi as IUniswapV2PairABI } from '@uniswap/v2-core/build/IUniswapV2Pair.json'
import { Interface } from '@ethersproject/abi'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useMultipleContractSingleData } from '../state/multicall/hooks'
import { wrappedCurrency } from '../utils/wrappedCurrency'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
@@ -61,5 +61,6 @@ export function useV2Pairs(currencies: [Currency | undefined, Currency | undefin
}
export function useV2Pair(tokenA?: Currency, tokenB?: Currency): [PairState, Pair | null] {
return useV2Pairs([[tokenA, tokenB]])[0]
const inputs: [[Currency | undefined, Currency | undefined]] = useMemo(() => [[tokenA, tokenB]], [tokenA, tokenB])
return useV2Pairs(inputs)[0]
}

View File

@@ -1,9 +1,8 @@
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { Pair, Trade } from '@uniswap/v2-sdk'
import { useMemo } from 'react'
import { useUserSingleHopOnly } from 'state/user/hooks'
import { isTradeBetter } from 'utils/isTradeBetter'
import { BETTER_TRADE_LESS_HOPS_THRESHOLD } from '../constants'
import { BETTER_TRADE_LESS_HOPS_THRESHOLD } from '../constants/misc'
import { useAllCurrencyCombinations } from './useAllCurrencyCombinations'
import { PairState, useV2Pairs } from './useV2Pairs'
@@ -36,15 +35,14 @@ const MAX_HOPS = 3
*/
export function useV2TradeExactIn(
currencyAmountIn?: CurrencyAmount<Currency>,
currencyOut?: Currency
currencyOut?: Currency,
{ maxHops = MAX_HOPS } = {}
): Trade<Currency, Currency, TradeType.EXACT_INPUT> | null {
const allowedPairs = useAllCommonPairs(currencyAmountIn?.currency, currencyOut)
const [singleHopOnly] = useUserSingleHopOnly()
return useMemo(() => {
if (currencyAmountIn && currencyOut && allowedPairs.length > 0) {
if (singleHopOnly) {
if (maxHops === 1) {
return (
Trade.bestTradeExactIn(allowedPairs, currencyAmountIn, currencyOut, { maxHops: 1, maxNumResults: 1 })[0] ??
null
@@ -52,7 +50,7 @@ export function useV2TradeExactIn(
}
// search through trades with varying hops, find best trade out of them
let bestTradeSoFar: Trade<Currency, Currency, TradeType.EXACT_INPUT> | null = null
for (let i = 1; i <= MAX_HOPS; i++) {
for (let i = 1; i <= maxHops; i++) {
const currentTrade: Trade<Currency, Currency, TradeType.EXACT_INPUT> | null =
Trade.bestTradeExactIn(allowedPairs, currencyAmountIn, currencyOut, { maxHops: i, maxNumResults: 1 })[0] ??
null
@@ -65,7 +63,7 @@ export function useV2TradeExactIn(
}
return null
}, [allowedPairs, currencyAmountIn, currencyOut, singleHopOnly])
}, [allowedPairs, currencyAmountIn, currencyOut, maxHops])
}
/**
@@ -73,15 +71,14 @@ export function useV2TradeExactIn(
*/
export function useV2TradeExactOut(
currencyIn?: Currency,
currencyAmountOut?: CurrencyAmount<Currency>
currencyAmountOut?: CurrencyAmount<Currency>,
{ maxHops = MAX_HOPS } = {}
): Trade<Currency, Currency, TradeType.EXACT_OUTPUT> | null {
const allowedPairs = useAllCommonPairs(currencyIn, currencyAmountOut?.currency)
const [singleHopOnly] = useUserSingleHopOnly()
return useMemo(() => {
if (currencyIn && currencyAmountOut && allowedPairs.length > 0) {
if (singleHopOnly) {
if (maxHops === 1) {
return (
Trade.bestTradeExactOut(allowedPairs, currencyIn, currencyAmountOut, { maxHops: 1, maxNumResults: 1 })[0] ??
null
@@ -89,7 +86,7 @@ export function useV2TradeExactOut(
}
// search through trades with varying hops, find best trade out of them
let bestTradeSoFar: Trade<Currency, Currency, TradeType.EXACT_OUTPUT> | null = null
for (let i = 1; i <= MAX_HOPS; i++) {
for (let i = 1; i <= maxHops; i++) {
const currentTrade =
Trade.bestTradeExactOut(allowedPairs, currencyIn, currencyAmountOut, { maxHops: i, maxNumResults: 1 })[0] ??
null
@@ -100,5 +97,5 @@ export function useV2TradeExactOut(
return bestTradeSoFar
}
return null
}, [currencyIn, currencyAmountOut, allowedPairs, singleHopOnly])
}, [currencyIn, currencyAmountOut, allowedPairs, maxHops])
}

View File

@@ -3,7 +3,7 @@ import { useMemo } from 'react'
import { tryParseAmount } from '../state/swap/hooks'
import { useTransactionAdder } from '../state/transactions/hooks'
import { useCurrencyBalance } from '../state/wallet/hooks'
import { useActiveWeb3React } from './index'
import { useActiveWeb3React } from './web3'
import { useWETHContract } from './useContract'
export enum WrapType {

View File

@@ -5,7 +5,7 @@ import { Web3ReactContextInterface } from '@web3-react/core/dist/types'
import { useEffect, useState } from 'react'
import { isMobile } from 'react-device-detect'
import { injected } from '../connectors'
import { NetworkContextName } from '../constants'
import { NetworkContextName } from '../constants/misc'
export function useActiveWeb3React(): Web3ReactContextInterface<Web3Provider> & { chainId?: ChainId } {
const context = useWeb3ReactCore<Web3Provider>()

View File

@@ -7,7 +7,7 @@ import ReactGA from 'react-ga'
import { Provider } from 'react-redux'
import { HashRouter } from 'react-router-dom'
import Blocklist from './components/Blocklist'
import { NetworkContextName } from './constants'
import { NetworkContextName } from './constants/misc'
import './i18n'
import App from './pages/App'
import store from './state'

View File

@@ -4,7 +4,7 @@ import { Text } from 'rebass'
import { ThemeContext } from 'styled-components'
import { AutoColumn } from '../../components/Column'
import { AutoRow } from '../../components/Row'
import { ONE_BIPS } from '../../constants'
import { ONE_BIPS } from '../../constants/misc'
import { Field } from '../../state/mint/v3/actions'
import { TYPE } from '../../theme'

View File

@@ -1,10 +1,11 @@
import React, { useCallback, useContext, useMemo, useState, useEffect } from 'react'
import React, { useCallback, useContext, useMemo, useState } from 'react'
import { TransactionResponse } from '@ethersproject/providers'
import { Currency, CurrencyAmount, currencyEquals, Percent } from '@uniswap/sdk-core'
import { WETH9 } from '@uniswap/sdk-core'
import { AlertTriangle, AlertCircle } from 'react-feather'
import ReactGA from 'react-ga'
import { ZERO_PERCENT } from '../../constants'
import { ZERO_PERCENT } from '../../constants/misc'
import { NONFUNGIBLE_POSITION_MANAGER_ADDRESSES } from '../../constants/addresses'
import { useV3NFTPositionManagerContract } from '../../hooks/useContract'
import { RouteComponentProps } from 'react-router-dom'
import { Text } from 'rebass'
@@ -17,8 +18,9 @@ import CurrencyInputPanel from '../../components/CurrencyInputPanel'
import { RowBetween, RowFixed } from '../../components/Row'
import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import Review from './Review'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useCurrency } from '../../hooks/Tokens'
import { ApprovalState, useApproveCallback } from '../../hooks/useApproveCallback'
import useTransactionDeadline from '../../hooks/useTransactionDeadline'
@@ -42,7 +44,6 @@ import {
useV3DerivedMintInfo,
} from 'state/mint/v3/hooks'
import { FeeAmount, NonfungiblePositionManager } from '@uniswap/v3-sdk'
import { NONFUNGIBLE_POSITION_MANAGER_ADDRESSES } from 'constants/v3'
import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import { useDerivedPositionInfo } from 'hooks/useDerivedPositionInfo'
import { PositionPreview } from 'components/PositionPreview'
@@ -50,7 +51,6 @@ import FeeSelector from 'components/FeeSelector'
import RangeSelector from 'components/RangeSelector'
import RateToggle from 'components/RateToggle'
import { BigNumber } from '@ethersproject/bignumber'
import { calculateGasMargin } from 'utils'
import { AddRemoveTabs } from 'components/NavigationTabs'
import HoverInlineText from 'components/HoverInlineText'
@@ -88,7 +88,7 @@ export default function AddLiquidity({
const currencyB = useCurrency(currencyIdB)
// keep track for UI display purposes of user selected base currency
const [baseCurrency, setBaseCurrency] = useState(currencyA)
const baseCurrency = currencyA
const quoteCurrency = useMemo(
() =>
currencyA && currencyB && baseCurrency
@@ -99,14 +99,6 @@ export default function AddLiquidity({
[currencyA, currencyB, baseCurrency]
)
// url params are the source truth, so we have to do this
useEffect(() => {
setBaseCurrency(currencyA)
return () => {
setBaseCurrency(undefined)
}
}, [currencyA, currencyB])
// mint state
const { independentField, typedValue, startPriceTypedValue } = useV3MintState()

View File

@@ -1,4 +1,4 @@
import { useActiveWeb3React } from 'hooks'
import { useActiveWeb3React } from 'hooks/web3'
import React from 'react'
import { Redirect, RouteComponentProps } from 'react-router-dom'
import AddLiquidity from './index'

View File

@@ -4,7 +4,7 @@ import { Text } from 'rebass'
import { ThemeContext } from 'styled-components'
import { AutoColumn } from '../../components/Column'
import { AutoRow } from '../../components/Row'
import { ONE_BIPS } from '../../constants'
import { ONE_BIPS } from '../../constants/misc'
import { Field } from '../../state/mint/actions'
import { TYPE } from '../../theme'

View File

@@ -17,10 +17,10 @@ import { AddRemoveTabs } from '../../components/NavigationTabs'
import { MinimalPositionCard } from '../../components/PositionCard'
import Row, { RowBetween, RowFlat } from '../../components/Row'
import { V2_ROUTER_ADDRESS, ZERO_PERCENT } from '../../constants'
import { ZERO_PERCENT } from '../../constants/misc'
import { useV2RouterContract } from '../../hooks/useContract'
import { PairState } from '../../hooks/useV2Pairs'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useCurrency } from '../../hooks/Tokens'
import { ApprovalState, useApproveCallback } from '../../hooks/useApproveCallback'
import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported'
@@ -32,7 +32,8 @@ import { useDerivedMintInfo, useMintActionHandlers, useMintState } from '../../s
import { useTransactionAdder } from '../../state/transactions/hooks'
import { useIsExpertMode, useUserSlippageToleranceWithDefault } from '../../state/user/hooks'
import { TYPE } from '../../theme'
import { calculateGasMargin, calculateSlippageAmount } from '../../utils'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { calculateSlippageAmount } from '../../utils/calculateSlippageAmount'
import { maxAmountSpend } from '../../utils/maxAmountSpend'
import { wrappedCurrency } from '../../utils/wrappedCurrency'
import AppBody from '../AppBody'
@@ -122,14 +123,14 @@ export default function AddLiquidity({
{}
)
const router = useV2RouterContract()
// check whether the user has approved the router on the tokens
const [approvalA, approveACallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_A], V2_ROUTER_ADDRESS)
const [approvalB, approveBCallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_B], V2_ROUTER_ADDRESS)
const [approvalA, approveACallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_A], router?.address)
const [approvalB, approveBCallback] = useApproveCallback(parsedAmounts[Field.CURRENCY_B], router?.address)
const addTransaction = useTransactionAdder()
const router = useV2RouterContract()
async function onAdd() {
if (!chainId || !library || !account || !router) return

View File

@@ -18,7 +18,7 @@ import { useStakingInfo } from '../../state/stake/hooks'
import UnstakingModal from '../../components/earn/UnstakingModal'
import ClaimRewardModal from '../../components/earn/ClaimRewardModal'
import { useTokenBalance } from '../../state/wallet/hooks'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useColor } from '../../hooks/useColor'
import { CountUp } from 'use-count-up'
@@ -28,7 +28,7 @@ import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useV2Pair } from '../../hooks/useV2Pairs'
import usePrevious from '../../hooks/usePrevious'
import useUSDCPrice from '../../hooks/useUSDCPrice'
import { BIG_INT_ZERO, BIG_INT_SECONDS_IN_WEEK } from '../../constants'
import { BIG_INT_ZERO, BIG_INT_SECONDS_IN_WEEK } from '../../constants/misc'
const PageWrapper = styled(AutoColumn)`
max-width: 640px;

View File

@@ -9,8 +9,8 @@ import { RowBetween } from '../../components/Row'
import { CardSection, DataCard, CardNoise, CardBGImage } from '../../components/earn/styled'
import { Countdown } from './Countdown'
import Loader from '../../components/Loader'
import { useActiveWeb3React } from '../../hooks'
import { BIG_INT_ZERO } from '../../constants'
import { useActiveWeb3React } from '../../hooks/web3'
import { BIG_INT_ZERO } from '../../constants/misc'
import { OutlineCard } from '../../components/Card'
const PageWrapper = styled(AutoColumn)`

View File

@@ -10,15 +10,16 @@ import FormattedCurrencyAmount from '../../components/FormattedCurrencyAmount'
import { AutoRow, RowBetween, RowFixed } from '../../components/Row'
import { useV2LiquidityTokenPermit } from '../../hooks/useERC20Permit'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useToken } from '../../hooks/Tokens'
import { usePairContract, useV2MigratorContract } from '../../hooks/useContract'
import { NEVER_RELOAD, useSingleCallResult } from '../../state/multicall/hooks'
import { useTokenBalance } from '../../state/wallet/hooks'
import { BackArrow, ExternalLink, TYPE } from '../../theme'
import { calculateGasMargin, getEtherscanLink, isAddress } from '../../utils'
import { isAddress } from '../../utils'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { getExplorerLink, ExplorerDataType } from '../../utils/getExplorerLink'
import { BodyWrapper } from '../AppBody'
import { V3_MIGRATOR_ADDRESSES } from 'constants/v3'
import { PoolState, usePool } from 'hooks/usePools'
import { FeeAmount, Pool, Position, priceToClosestTick, TickMath } from '@uniswap/v3-sdk'
import { BlueCard, DarkGreyCard, LightCard, YellowCard } from 'components/Card'
@@ -208,6 +209,7 @@ function V2PairMigration({
tickUpper,
amount0: token0Value.quotient,
amount1: token1Value.quotient,
useFullPrecision: false, // we don't want full precision as this is used to calculate slippage amounts
})
: undefined
@@ -253,9 +255,8 @@ function V2PairMigration({
const migrator = useV2MigratorContract()
// approvals
const migratorAddress = chainId && V3_MIGRATOR_ADDRESSES[chainId]
const [approval, approveManually] = useApproveCallback(pairBalance, migratorAddress)
const { signatureData, gatherPermitSignature } = useV2LiquidityTokenPermit(pairBalance, migratorAddress)
const [approval, approveManually] = useApproveCallback(pairBalance, migrator?.address)
const { signatureData, gatherPermitSignature } = useV2LiquidityTokenPermit(pairBalance, migrator?.address)
const approve = useCallback(async () => {
if (isNotUniswap) {
@@ -395,8 +396,8 @@ function V2PairMigration({
<TYPE.body my={9} style={{ fontWeight: 400 }}>
This tool will safely migrate your {isNotUniswap ? 'SushiSwap' : 'V2'} liquidity to V3. The process is
completely trustless thanks to the{' '}
{chainId && migratorAddress && (
<ExternalLink href={getEtherscanLink(chainId, migratorAddress, 'address')}>
{chainId && migrator && (
<ExternalLink href={getExplorerLink(chainId, migrator.address, ExplorerDataType.ADDRESS)}>
<TYPE.blue display="inline">Uniswap migration contract</TYPE.blue>
</ExternalLink>
)}

View File

@@ -5,7 +5,7 @@ import { ThemeContext } from 'styled-components'
import { AutoColumn } from '../../components/Column'
import { AutoRow } from '../../components/Row'
import { Text } from 'rebass'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTokenBalancesWithLoadingIndicator } from '../../state/wallet/hooks'
import { BackArrow, StyledInternalLink, TYPE } from '../../theme'
import { LightCard } from '../../components/Card'

View File

@@ -7,6 +7,8 @@ import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import { Link, RouteComponentProps } from 'react-router-dom'
import { unwrappedToken, wrappedCurrencyAmount } from 'utils/wrappedCurrency'
import { usePositionTokenURI } from '../../hooks/usePositionTokenURI'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { getExplorerLink, ExplorerDataType } from '../../utils/getExplorerLink'
import { LoadingRows } from './styleds'
import styled from 'styled-components/macro'
import { AutoColumn } from 'components/Column'
@@ -14,7 +16,6 @@ import { RowBetween, RowFixed } from 'components/Row'
import DoubleCurrencyLogo from 'components/DoubleLogo'
import { ExternalLink, HideExtraSmall, TYPE } from 'theme'
import Badge from 'components/Badge'
import { calculateGasMargin, getEtherscanLink } from 'utils'
import { ButtonConfirmed, ButtonPrimary, ButtonGray } from 'components/Button'
import { DarkCard, LightCard } from 'components/Card'
import CurrencyLogo from 'components/CurrencyLogo'
@@ -23,8 +24,18 @@ import { currencyId } from 'utils/currencyId'
import { formatTokenAmount } from 'utils/formatTokenAmount'
import { useV3PositionFees } from 'hooks/useV3PositionFees'
import { BigNumber } from '@ethersproject/bignumber'
import { Token, Currency, CurrencyAmount, Percent, Fraction, Price, Ether } from '@uniswap/sdk-core'
import { useActiveWeb3React } from 'hooks'
import {
Token,
Currency,
CurrencyAmount,
Percent,
Fraction,
Price,
Ether,
currencyEquals,
ETHER,
} from '@uniswap/sdk-core'
import { useActiveWeb3React } from 'hooks/web3'
import { useV3NFTPositionManagerContract } from 'hooks/useContract'
import { useIsTransactionPending, useTransactionAdder } from 'state/transactions/hooks'
import ReactGA from 'react-ga'
@@ -173,6 +184,28 @@ function CurrentPriceCard({
)
}
function LinkedCurrency({ chainId, currency }: { chainId?: number; currency?: Currency }) {
const address = (currency as Token)?.address
if (typeof chainId === 'number' && address) {
return (
<ExternalLink href={getExplorerLink(chainId, address, ExplorerDataType.ADDRESS)}>
<RowFixed>
<CurrencyLogo currency={currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main>{currency?.symbol} </TYPE.main>
</RowFixed>
</ExternalLink>
)
}
return (
<RowFixed>
<CurrencyLogo currency={currency} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main>{currency?.symbol}</TYPE.main>
</RowFixed>
)
}
function getRatio(
lower: Price<Currency, Currency>,
current: Price<Currency, Currency>,
@@ -535,7 +568,7 @@ export function PositionPage({
<NFT image={metadata.result.image} height={400} />
</div>
{typeof chainId === 'number' && owner && !ownsNFT ? (
<ExternalLink href={getEtherscanLink(chainId, owner, 'address')}>Owner</ExternalLink>
<ExternalLink href={getExplorerLink(chainId, owner, ExplorerDataType.ADDRESS)}>Owner</ExternalLink>
) : null}
</DarkCard>
) : (
@@ -557,7 +590,7 @@ export function PositionPage({
<Label>Liquidity</Label>
{fiatValueOfLiquidity?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader fontSize="36px" fontWeight={500}>
${fiatValueOfLiquidity.toFixed(2)}
${fiatValueOfLiquidity.toFixed(2, { groupSeparator: ',' })}
</TYPE.largeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
@@ -568,10 +601,7 @@ export function PositionPage({
<LightCard padding="12px 16px">
<AutoColumn gap="md">
<RowBetween>
<RowFixed>
<CurrencyLogo currency={currencyQuote} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main>{currencyQuote?.symbol}</TYPE.main>
</RowFixed>
<LinkedCurrency chainId={chainId} currency={currencyQuote} />
<RowFixed>
<TYPE.main>
{inverted ? position?.amount0.toSignificant(4) : position?.amount1.toSignificant(4)}
@@ -584,10 +614,7 @@ export function PositionPage({
</RowFixed>
</RowBetween>
<RowBetween>
<RowFixed>
<CurrencyLogo currency={currencyBase} size={'20px'} style={{ marginRight: '0.5rem' }} />
<TYPE.main>{currencyBase?.symbol}</TYPE.main>
</RowFixed>
<LinkedCurrency chainId={chainId} currency={currencyBase} />
<RowFixed>
<TYPE.main>
{inverted ? position?.amount1.toSignificant(4) : position?.amount0.toSignificant(4)}
@@ -613,7 +640,7 @@ export function PositionPage({
<Label>Unclaimed fees</Label>
{fiatValueOfFees?.greaterThan(new Fraction(1, 100)) ? (
<TYPE.largeHeader color={theme.green1} fontSize="36px" fontWeight={500}>
${fiatValueOfFees.toFixed(2)}
${fiatValueOfFees.toFixed(2, { groupSeparator: ',' })}
</TYPE.largeHeader>
) : (
<TYPE.largeHeader color={theme.text1} fontSize="36px" fontWeight={500}>
@@ -676,7 +703,12 @@ export function PositionPage({
</RowBetween>
</AutoColumn>
</LightCard>
{ownsNFT && (feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) && !collectMigrationHash ? (
{ownsNFT &&
(feeValue0?.greaterThan(0) || feeValue1?.greaterThan(0)) &&
currency0 &&
currency1 &&
(currencyEquals(currency0, ETHER) || currencyEquals(currency1, ETHER)) &&
!collectMigrationHash ? (
<AutoColumn gap="md">
<RowBetween>
<TYPE.main>Collect as WETH</TYPE.main>

View File

@@ -5,7 +5,7 @@ import { FlyoutAlignment, NewMenu } from 'components/Menu'
import { SwapPoolTabs } from 'components/NavigationTabs'
import PositionList from 'components/PositionList'
import { RowBetween, RowFixed } from 'components/Row'
import { useActiveWeb3React } from 'hooks'
import { useActiveWeb3React } from 'hooks/web3'
import { useV3Positions } from 'hooks/useV3Positions'
import { BookOpen, ChevronDown, Download, Inbox, PlusCircle, ChevronsRight, Layers } from 'react-feather'
import { useTranslation } from 'react-i18next'

View File

@@ -14,13 +14,13 @@ import { ChevronsRight } from 'react-feather'
import { AutoColumn } from '../../components/Column'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useV2Pairs } from '../../hooks/useV2Pairs'
import { toV2LiquidityToken, useTrackedTokenPairs } from '../../state/user/hooks'
import { Dots } from '../../components/swap/styleds'
import { CardSection, DataCard, CardNoise, CardBGImage } from '../../components/earn/styled'
import { useStakingInfo } from '../../state/stake/hooks'
import { BIG_INT_ZERO } from '../../constants'
import { BIG_INT_ZERO } from '../../constants/misc'
import { Pair } from '@uniswap/v2-sdk'
const PageWrapper = styled(AutoColumn)`

View File

@@ -12,7 +12,7 @@ import { MinimalPositionCard } from '../../components/PositionCard'
import Row from '../../components/Row'
import CurrencySearchModal from '../../components/SearchModal/CurrencySearchModal'
import { PairState, useV2Pair } from '../../hooks/useV2Pairs'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { usePairAdder } from '../../state/user/hooks'
import { useTokenBalance } from '../../state/wallet/hooks'
import { StyledInternalLink } from '../../theme'

View File

@@ -1,6 +1,7 @@
import React, { useCallback, useMemo, useState } from 'react'
import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import { Redirect, RouteComponentProps } from 'react-router-dom'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import AppBody from '../AppBody'
import { BigNumber } from '@ethersproject/bignumber'
import useDebouncedChangeHandler from 'hooks/useDebouncedChangeHandler'
@@ -18,21 +19,21 @@ import { useV3NFTPositionManagerContract } from 'hooks/useContract'
import { useUserSlippageToleranceWithDefault } from 'state/user/hooks'
import useTransactionDeadline from 'hooks/useTransactionDeadline'
import ReactGA from 'react-ga'
import { useActiveWeb3React } from 'hooks'
import { useActiveWeb3React } from 'hooks/web3'
import { TransactionResponse } from '@ethersproject/providers'
import { useTransactionAdder } from 'state/transactions/hooks'
import { Percent } from '@uniswap/sdk-core'
import { Percent, currencyEquals, Token, ETHER } from '@uniswap/sdk-core'
import { TYPE } from 'theme'
import { Wrapper, SmallMaxButton, ResponsiveHeaderText } from './styled'
import Loader from 'components/Loader'
import DoubleCurrencyLogo from 'components/DoubleLogo'
import { Break } from 'components/earn/styled'
import { NonfungiblePositionManager } from '@uniswap/v3-sdk'
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'
import { unwrappedToken } from 'utils/wrappedCurrency'
export const UINT128MAX = BigNumber.from(2).pow(128).sub(1)
@@ -369,14 +370,21 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
</AutoColumn>
</LightCard>
<RowBetween>
<TYPE.main>Collect as WETH</TYPE.main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
/>
</RowBetween>
{liquidityValue0?.currency &&
liquidityValue1?.currency &&
(liquidityValue0.currency.isEther ||
liquidityValue1.currency.isEther ||
currencyEquals(unwrappedToken(liquidityValue0.currency as Token), ETHER) ||
currencyEquals(unwrappedToken(liquidityValue1.currency as Token), ETHER)) ? (
<RowBetween>
<TYPE.main>Collect as WETH</TYPE.main>
<Toggle
id="receive-as-weth"
isActive={receiveWETH}
toggle={() => setReceiveWETH((receiveWETH) => !receiveWETH)}
/>
</RowBetween>
) : null}
<div style={{ display: 'flex' }}>
<AutoColumn gap="12px" style={{ flex: '1' }}>

View File

@@ -19,8 +19,7 @@ import Row, { RowBetween, RowFixed } from '../../components/Row'
import Slider from '../../components/Slider'
import CurrencyLogo from '../../components/CurrencyLogo'
import { V2_ROUTER_ADDRESS } from '../../constants'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useCurrency } from '../../hooks/Tokens'
import { usePairContract, useV2RouterContract } from '../../hooks/useContract'
import { useV2LiquidityTokenPermit } from '../../hooks/useERC20Permit'
@@ -28,7 +27,8 @@ import useTransactionDeadline from '../../hooks/useTransactionDeadline'
import { useTransactionAdder } from '../../state/transactions/hooks'
import { StyledInternalLink, TYPE } from '../../theme'
import { calculateGasMargin, calculateSlippageAmount } from '../../utils'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { calculateSlippageAmount } from '../../utils/calculateSlippageAmount'
import { currencyId } from '../../utils/currencyId'
import useDebouncedChangeHandler from '../../hooks/useDebouncedChangeHandler'
import { wrappedCurrency } from '../../utils/wrappedCurrency'
@@ -99,12 +99,14 @@ export default function RemoveLiquidity({
// pair contract
const pairContract: Contract | null = usePairContract(pair?.liquidityToken?.address)
const router = useV2RouterContract()
// allowance handling
const { gatherPermitSignature, signatureData } = useV2LiquidityTokenPermit(
parsedAmounts[Field.LIQUIDITY],
V2_ROUTER_ADDRESS
router?.address
)
const [approval, approveCallback] = useApproveCallback(parsedAmounts[Field.LIQUIDITY], V2_ROUTER_ADDRESS)
const [approval, approveCallback] = useApproveCallback(parsedAmounts[Field.LIQUIDITY], router?.address)
async function onAttemptToApprove() {
if (!pairContract || !pair || !library || !deadline) throw new Error('missing dependencies')
@@ -145,7 +147,6 @@ export default function RemoveLiquidity({
// tx sending
const addTransaction = useTransactionAdder()
const router = useV2RouterContract()
async function onRemove() {
if (!chainId || !library || !account || !deadline || !router) throw new Error('missing dependencies')

View File

@@ -27,7 +27,7 @@ import { ArrowWrapper, BottomGrouping, Dots, SwapCallbackError, Wrapper } from '
import SwapHeader from '../../components/swap/SwapHeader'
import TradePrice from '../../components/swap/TradePrice'
import TokenWarningModal from '../../components/TokenWarningModal'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { useAllTokens, useCurrency } from '../../hooks/Tokens'
import { ApprovalState, useApproveCallbackFromTrade } from '../../hooks/useApproveCallback'
import { V3TradeState } from '../../hooks/useBestV3Trade'

View File

@@ -1,14 +1,31 @@
import { CurrencyAmount, Token } from '@uniswap/sdk-core'
import { BigNumber } from 'ethers'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import JSBI from 'jsbi'
import { DateTime } from 'luxon'
import React, { useState } from 'react'
import { AutoColumn } from '../../components/Column'
import styled from 'styled-components/macro'
import { ArrowLeft } from 'react-feather'
import ReactMarkdown from 'react-markdown'
import { RouteComponentProps } from 'react-router-dom'
import { ExternalLink, StyledInternalLink, TYPE } from '../../theme'
import { RowBetween, RowFixed } from '../../components/Row'
import { CardSection, DataCard } from '../../components/earn/styled'
import { ArrowLeft } from 'react-feather'
import styled from 'styled-components/macro'
import { ButtonPrimary } from '../../components/Button'
import { ProposalStatus } from './styled'
import { GreyCard } from '../../components/Card'
import { AutoColumn } from '../../components/Column'
import { CardSection, DataCard } from '../../components/earn/styled'
import { RowBetween, RowFixed } from '../../components/Row'
import DelegateModal from '../../components/vote/DelegateModal'
import VoteModal from '../../components/vote/VoteModal'
import {
AVERAGE_BLOCK_TIME_IN_SECS,
COMMON_CONTRACT_NAMES,
DEFAULT_AVERAGE_BLOCK_TIME_IN_SECS,
} from '../../constants/governance'
import { ZERO_ADDRESS } from '../../constants/misc'
import { UNI } from '../../constants/tokens'
import { useActiveWeb3React } from '../../hooks/web3'
import { ApplicationModal } from '../../state/application/actions'
import { useBlockNumber, useModalOpen, useToggleDelegateModal, useToggleVoteModal } from '../../state/application/hooks'
import {
ProposalData,
ProposalState,
@@ -16,21 +33,11 @@ import {
useUserDelegatee,
useUserVotesAsOfBlock,
} from '../../state/governance/hooks'
import { DateTime } from 'luxon'
import ReactMarkdown from 'react-markdown'
import VoteModal from '../../components/vote/VoteModal'
import { Token, CurrencyAmount } from '@uniswap/sdk-core'
import JSBI from 'jsbi'
import { useActiveWeb3React } from '../../hooks'
import { AVERAGE_BLOCK_TIME_IN_SECS, COMMON_CONTRACT_NAMES, UNI, ZERO_ADDRESS } from '../../constants'
import { getEtherscanLink, isAddress } from '../../utils'
import { ApplicationModal } from '../../state/application/actions'
import { useBlockNumber, useModalOpen, useToggleDelegateModal, useToggleVoteModal } from '../../state/application/hooks'
import DelegateModal from '../../components/vote/DelegateModal'
import { useTokenBalance } from '../../state/wallet/hooks'
import useCurrentBlockTimestamp from 'hooks/useCurrentBlockTimestamp'
import { BigNumber } from 'ethers'
import { GreyCard } from '../../components/Card'
import { ExternalLink, StyledInternalLink, TYPE } from '../../theme'
import { isAddress } from '../../utils'
import { ExplorerDataType, getExplorerLink } from '../../utils/getExplorerLink'
import { ProposalStatus } from './styled'
const PageWrapper = styled(AutoColumn)`
width: 100%;
@@ -138,7 +145,11 @@ export default function VotePage({
proposalData && currentTimestamp && currentBlock
? DateTime.fromSeconds(
currentTimestamp
.add(BigNumber.from(AVERAGE_BLOCK_TIME_IN_SECS).mul(BigNumber.from(proposalData.endBlock - currentBlock)))
.add(
BigNumber.from(
(chainId && AVERAGE_BLOCK_TIME_IN_SECS[chainId]) ?? DEFAULT_AVERAGE_BLOCK_TIME_IN_SECS
).mul(BigNumber.from(proposalData.endBlock - currentBlock))
)
.toNumber()
)
: undefined
@@ -176,8 +187,10 @@ export default function VotePage({
// if content is contract with common name, replace address with common name
const linkIfAddress = (content: string) => {
if (isAddress(content) && chainId) {
const commonName = COMMON_CONTRACT_NAMES[content] ?? content
return <ExternalLink href={getEtherscanLink(chainId, content, 'address')}>{commonName}</ExternalLink>
const commonName = COMMON_CONTRACT_NAMES[chainId]?.[content] ?? content
return (
<ExternalLink href={getExplorerLink(chainId, content, ExplorerDataType.ADDRESS)}>{commonName}</ExternalLink>
)
}
return <span>{content}</span>
}
@@ -307,7 +320,11 @@ export default function VotePage({
<AutoColumn gap="md">
<TYPE.mediumHeader fontWeight={600}>Proposer</TYPE.mediumHeader>
<ProposerAddressLink
href={proposalData?.proposer && chainId ? getEtherscanLink(chainId, proposalData?.proposer, 'address') : ''}
href={
proposalData?.proposer && chainId
? getExplorerLink(chainId, proposalData?.proposer, ExplorerDataType.ADDRESS)
: ''
}
>
<ReactMarkdown source={proposalData?.proposer} />
</ProposerAddressLink>

View File

@@ -1,9 +1,11 @@
import React from 'react'
import { AutoColumn } from '../../components/Column'
import styled from 'styled-components/macro'
import { UNI } from '../../constants/tokens'
import { ExternalLink, TYPE } from '../../theme'
import { RowBetween, RowFixed } from '../../components/Row'
import { Link } from 'react-router-dom'
import { getExplorerLink, ExplorerDataType } from '../../utils/getExplorerLink'
import { ProposalStatus } from './styled'
import { ButtonPrimary } from '../../components/Button'
import { Button } from 'rebass/styled-components'
@@ -18,11 +20,11 @@ import {
} from '../../state/governance/hooks'
import DelegateModal from '../../components/vote/DelegateModal'
import { useTokenBalance } from '../../state/wallet/hooks'
import { useActiveWeb3React } from '../../hooks'
import { UNI, ZERO_ADDRESS } from '../../constants'
import { useActiveWeb3React } from '../../hooks/web3'
import { ZERO_ADDRESS } from '../../constants/misc'
import { Token, CurrencyAmount, ChainId } from '@uniswap/sdk-core'
import JSBI from 'jsbi'
import { shortenAddress, getEtherscanLink } from '../../utils'
import { shortenAddress } from '../../utils'
import Loader from '../../components/Loader'
import FormattedCurrencyAmount from '../../components/FormattedCurrencyAmount'
import { useModalOpen, useToggleDelegateModal } from '../../state/application/hooks'
@@ -204,7 +206,7 @@ export default function Vote() {
</TYPE.body>
<AddressButton>
<StyledExternalLink
href={getEtherscanLink(ChainId.MAINNET, userDelegatee, 'address')}
href={getExplorerLink(ChainId.MAINNET, userDelegatee, ExplorerDataType.ADDRESS)}
style={{ margin: '0 4px' }}
>
{userDelegatee === account ? 'Self' : shortenAddress(userDelegatee)}

View File

@@ -1,6 +1,6 @@
import { useCallback, useMemo } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { AppDispatch, AppState } from '../index'
import { addPopup, ApplicationModal, PopupContent, removePopup, setOpenModal } from './actions'

View File

@@ -1,5 +1,5 @@
import { useCallback, useEffect, useState } from 'react'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import useDebounce from '../../hooks/useDebounce'
import useIsWindowVisible from '../../hooks/useIsWindowVisible'
import { updateBlockNumber } from './actions'

View File

@@ -6,7 +6,7 @@ import { useDispatch, useSelector } from 'react-redux'
import { useV2Pair } from '../../hooks/useV2Pairs'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import { useActiveWeb3React } from '../../hooks'
import { useActiveWeb3React } from '../../hooks/web3'
import { wrappedCurrency } from '../../utils/wrappedCurrency'
import { AppDispatch, AppState } from '../index'
import { tryParseAmount } from '../swap/hooks'

Some files were not shown because too many files have changed in this diff Show More