refactor(L2): Arbitrum Kovan testnet and Arbitrum One support (#1716)

* experimental! point at a kovan arbitrum deployment

* remove the unwrapped token from mint hook

* fix explorer links

* Etherscan -> Explorer

* move chains to constant file

* use NETWORK_URLS instead

* temporary fix to the syncing issue

* fix tests

* fix unknown chain id crash

* use a multicall that returns arbitrum block numbers

* lower polling interval for layer 2

* use a better multicall

* remove unused import

* fixed multicall2

* make some v2 code chain specific

* fix build

* line number changes

* update keys

* fix the locale parsing of full locale string

* extract

* fix lint

* add arbitrum one

* add arbitrum one to supported chains

* add missing arbitrum one label

* refactor: remove storybook

* point to the arbitrum explorer address

* fix arbitrum mainnet links

* fix how weth shows up in the interface

* make the usdc price feature more cross chain compatible

* missing translation

* clean up some governance code so it doesn't crash on unsupported networks

* improve how we check for transaction receipts for sequencer networks

* improve it a bit more
This commit is contained in:
Moody Salem 2021-06-02 15:14:34 -05:00 committed by GitHub
parent ad53da5efe
commit 02d80e07dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 959 additions and 352 deletions

@ -366,7 +366,7 @@ export default function AccountDetails({
>
<LinkIcon size={16} />
<span style={{ marginLeft: '4px' }}>
<Trans>View on Etherscan</Trans>
<Trans>View on Explorer</Trans>
</span>
</AddressLink>
)}
@ -392,7 +392,7 @@ export default function AccountDetails({
>
<LinkIcon size={16} />
<span style={{ marginLeft: '4px' }}>
<Trans>View on Etherscan</Trans>
<Trans>View on Explorer</Trans>
</span>
</AddressLink>
)}

@ -106,7 +106,7 @@ export default function AddressInputPanel({
href={getExplorerLink(chainId, name ?? address, ExplorerDataType.ADDRESS)}
style={{ fontSize: '14px' }}
>
(View on Etherscan)
(View on Explorer)
</ExternalLink>
)}
</RowBetween>

@ -9,6 +9,7 @@ import styled from 'styled-components/macro'
import Logo from '../../assets/svg/logo.svg'
import LogoDark from '../../assets/svg/logo_white.svg'
import { SupportedChainId } from '../../constants/chains'
import { useActiveWeb3React } from '../../hooks/web3'
import { useDarkModeManager } from '../../state/user/hooks'
@ -301,11 +302,14 @@ export const StyledMenuButton = styled.button`
}
`
const NETWORK_LABELS: { [chainId: number]: string } = {
[4]: 'Rinkeby',
[3]: 'Ropsten',
[5]: 'Görli',
[42]: 'Kovan',
const NETWORK_LABELS: { [chainId in SupportedChainId | number]: string } = {
[SupportedChainId.MAINNET]: 'Mainnet',
[SupportedChainId.RINKEBY]: 'Rinkeby',
[SupportedChainId.ROPSTEN]: 'Ropsten',
[SupportedChainId.GOERLI]: 'Görli',
[SupportedChainId.KOVAN]: 'Kovan',
[SupportedChainId.ARBITRUM_KOVAN]: 'kArbitrum',
[SupportedChainId.ARBITRUM_ONE]: 'Arbitrum One',
}
export default function Header() {
@ -367,7 +371,7 @@ export default function Header() {
<HeaderControls>
<HeaderElement>
<HideSmall>
{chainId && NETWORK_LABELS[chainId] && (
{chainId && chainId !== SupportedChainId.MAINNET && NETWORK_LABELS[chainId] && (
<NetworkCard title={NETWORK_LABELS[chainId]}>{NETWORK_LABELS[chainId]}</NetworkCard>
)}
</HideSmall>

@ -70,7 +70,7 @@ export function SubmittedView({
style={{ marginLeft: '4px' }}
>
<TYPE.subHeader>
<Trans>View transaction on Etherscan</Trans>
<Trans>View transaction on Explorer</Trans>
</TYPE.subHeader>
</ExternalLink>
)}

@ -34,7 +34,7 @@ export default function TransactionPopup({
<TYPE.body fontWeight={500}>{summary ?? 'Hash: ' + hash.slice(0, 8) + '...' + hash.slice(58, 65)}</TYPE.body>
{chainId && (
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}>
View on Etherscan
View on Explorer
</ExternalLink>
)}
</AutoColumn>

@ -8,14 +8,14 @@ import { Link } from 'react-router-dom'
import styled from 'styled-components/macro'
import { HideSmall, MEDIA_WIDTHS, SmallOnly } from 'theme'
import { PositionDetails } from 'types/position'
import { WETH9, Price, Token, Percent } from '@uniswap/sdk-core'
import { Price, Token, Percent } from '@uniswap/sdk-core'
import { formatPrice } from 'utils/formatCurrencyAmount'
import Loader from 'components/Loader'
import { unwrappedToken } from 'utils/unwrappedToken'
import RangeBadge from 'components/Badge/RangeBadge'
import { RowFixed } from 'components/Row'
import HoverInlineText from 'components/HoverInlineText'
import { DAI, USDC, USDT, WBTC } from '../../constants/tokens'
import { DAI, USDC, USDT, WBTC, WETH9_EXTENDED } from '../../constants/tokens'
import { Trans } from '@lingui/macro'
const LinkRow = styled(Link)`
@ -146,7 +146,7 @@ export function getPriceOrderingFromPositionForUI(position?: Position): {
}
// if token1 is an ETH-/BTC-stable asset, set it as the base token
const bases = [...Object.values(WETH9), WBTC]
const bases = [...Object.values(WETH9_EXTENDED), WBTC]
if (bases.some((base) => base.equals(token1))) {
return {
priceLower: position.token0PriceUpper.invert(),

@ -1,3 +1,4 @@
import { Trans } from '@lingui/macro'
import React from 'react'
import { Currency } from '@uniswap/sdk-core'
import { ToggleElement, ToggleWrapper } from 'components/Toggle/MultiToggle'
@ -19,13 +20,13 @@ export default function RateToggle({
const isSorted = tokenA && tokenB && tokenA.sortsBefore(tokenB)
return tokenA && tokenB ? (
<div style={{ width: 'fit-content', display: 'flex', alignItems: 'center' }}>
<div style={{ width: 'fit-content', display: 'flex', alignItems: 'center' }} onClick={handleRateToggle}>
<ToggleWrapper width="fit-content">
<ToggleElement isActive={isSorted} fontSize="12px" onClick={handleRateToggle}>
{isSorted ? currencyA.symbol + ' price ' : currencyB.symbol + ' price '}
<ToggleElement isActive={isSorted} fontSize="12px">
<Trans>{isSorted ? currencyA.symbol : currencyB.symbol} price</Trans>
</ToggleElement>
<ToggleElement isActive={!isSorted} fontSize="12px" onClick={handleRateToggle}>
{isSorted ? currencyB.symbol + ' price ' : currencyA.symbol + ' price '}
<ToggleElement isActive={!isSorted} fontSize="12px">
{isSorted ? currencyB.symbol : currencyA.symbol} price
</ToggleElement>
</ToggleWrapper>
</div>

@ -1,9 +1,10 @@
import { Currency, Ether, Token } from '@uniswap/sdk-core'
import { Currency, Token } from '@uniswap/sdk-core'
import React, { KeyboardEvent, RefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'
import ReactGA from 'react-ga'
import { t, Trans } from '@lingui/macro'
import { FixedSizeList } from 'react-window'
import { Text } from 'rebass'
import { ExtendedEther } from '../../constants/tokens'
import { useActiveWeb3React } from '../../hooks/web3'
import { useAllTokens, useToken, useIsUserAddedToken, useSearchInactiveTokenLists } from '../../hooks/Tokens'
import { CloseIcon, TYPE, ButtonText, IconWrapper } from '../../theme'
@ -105,7 +106,7 @@ export function CurrencySearch({
const filteredSortedTokens = useSortedTokensByQuery(sortedTokens, debouncedQuery)
const ether = useMemo(() => chainId && Ether.onChain(chainId), [chainId])
const ether = useMemo(() => chainId && ExtendedEther.onChain(chainId), [chainId])
const filteredSortedTokensWithETH: Currency[] = useMemo(() => {
const s = debouncedQuery.toLowerCase().trim()

@ -116,7 +116,7 @@ export function TransactionSubmittedContent({
{chainId && hash && (
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)}>
<Text fontWeight={500} fontSize={14} color={theme.primary1}>
<Trans>View on Etherscan</Trans>
<Trans>View on Explorer</Trans>
</Text>
</ExternalLink>
)}

@ -192,7 +192,7 @@ export default function AddressClaimModal({ isOpen, onDismiss }: { isOpen: boole
)}
{attempting && hash && !claimConfirmed && chainId && hash && (
<ExternalLink href={getExplorerLink(chainId, hash, ExplorerDataType.TRANSACTION)} style={{ zIndex: 99 }}>
<Trans>View transaction on Etherscan</Trans>
<Trans>View transaction on Explorer</Trans>
</ExternalLink>
)}
</AutoColumn>

@ -221,7 +221,7 @@ export default function ClaimModal() {
href={getExplorerLink(chainId, claimTxn?.hash, ExplorerDataType.TRANSACTION)}
style={{ zIndex: 99 }}
>
<Trans>View transaction on Etherscan</Trans>
<Trans>View transaction on Explorer</Trans>
</ExternalLink>
)}
</AutoColumn>

@ -155,7 +155,7 @@ export default function VoteModal({ isOpen, onDismiss, proposalId, support }: Vo
style={{ marginLeft: '4px' }}
>
<TYPE.subHeader>
<Trans>View transaction on Etherscan</Trans>
<Trans>View transaction on Explorer</Trans>
</TYPE.subHeader>
</ExternalLink>
)}

@ -3,6 +3,7 @@ import { InjectedConnector } from '@web3-react/injected-connector'
import { WalletConnectConnector } from '@web3-react/walletconnect-connector'
import { WalletLinkConnector } from '@web3-react/walletlink-connector'
import { PortisConnector } from '@web3-react/portis-connector'
import { SupportedChainId } from '../constants/chains'
import getLibrary from '../utils/getLibrary'
import { FortmaticConnector } from './Fortmatic'
@ -19,16 +20,26 @@ if (typeof INFURA_KEY === 'undefined') {
}
const NETWORK_URLS: {
[chainId: number]: string
[chainId in SupportedChainId]: string
} = {
[1]: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
[4]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
[3]: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
[5]: `https://goerli.infura.io/v3/${INFURA_KEY}`,
[42]: `https://kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.MAINNET]: `https://mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.RINKEBY]: `https://rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ROPSTEN]: `https://ropsten.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.GOERLI]: `https://goerli.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.KOVAN]: `https://kovan.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.ARBITRUM_KOVAN]: `https://kovan5.arbitrum.io/rpc`,
[SupportedChainId.ARBITRUM_ONE]: `https://arb1.arbitrum.io/rpc`,
}
const SUPPORTED_CHAIN_IDS = [1, 4, 3, 42, 5]
const SUPPORTED_CHAIN_IDS: SupportedChainId[] = [
SupportedChainId.MAINNET,
SupportedChainId.KOVAN,
SupportedChainId.GOERLI,
SupportedChainId.RINKEBY,
SupportedChainId.ROPSTEN,
SupportedChainId.ARBITRUM_KOVAN,
SupportedChainId.ARBITRUM_ONE,
]
export const network = new NetworkConnector({
urls: NETWORK_URLS,
@ -46,7 +57,7 @@ export const injected = new InjectedConnector({
export const walletconnect = new WalletConnectConnector({
supportedChainIds: SUPPORTED_CHAIN_IDS,
infuraId: INFURA_KEY, // obviously a hack
rpc: NETWORK_URLS,
bridge: WALLETCONNECT_BRIDGE_URL,
qrcode: true,
pollingInterval: 15000,

@ -1,30 +1,58 @@
import { FACTORY_ADDRESS as V2_FACTORY_ADDRESS } from '@uniswap/v2-sdk'
import { FACTORY_ADDRESS as V3_FACTORY_ADDRESS } from '@uniswap/v3-sdk'
import { constructSameAddressMap } from '../utils/constructSameAddressMap'
import { SupportedChainId } from './chains'
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: number]: string } = {
[1]: '0x090D4613473dEE047c3f2706764f49E0821D256e',
type AddressMap = { [chainId: number]: string }
export const UNI_ADDRESS: AddressMap = constructSameAddressMap('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984', false)
export const MULTICALL2_ADDRESSES: AddressMap = {
...constructSameAddressMap('0x5BA1e12693Dc8F9c48aAD8770482f4739bEeD696', false),
[SupportedChainId.ARBITRUM_KOVAN]: '0xc80e33a6f02cf08557a0ca3d94d1474d73f64bc1',
[SupportedChainId.ARBITRUM_ONE]: '0x021CeAC7e681dBCE9b5039d2535ED97590eB395c',
}
export const ARGENT_WALLET_DETECTOR_ADDRESS: { [chainId: number]: string } = {
[1]: '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 V2_FACTORY_ADDRESSES: AddressMap = constructSameAddressMap(V2_FACTORY_ADDRESS, false)
export const V2_ROUTER_ADDRESS: AddressMap = constructSameAddressMap(
'0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
false
)
export const ENS_REGISTRAR_ADDRESSES = {
[1]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[5]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[4]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[3]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
export const GOVERNANCE_ADDRESS: AddressMap = constructSameAddressMap(
'0x5e4be8Bc9637f0EAA1A755019e06A68ce081D58F',
false
)
export const TIMELOCK_ADDRESS: AddressMap = constructSameAddressMap('0x1a9C8182C09F50C8318d769245beA52c32BE35BC', false)
export const MERKLE_DISTRIBUTOR_ADDRESS: AddressMap = {
[SupportedChainId.MAINNET]: '0x090D4613473dEE047c3f2706764f49E0821D256e',
}
export const SOCKS_CONTROLLER_ADDRESSES = {
[1]: '0x65770b5283117639760beA3F867b69b3697a91dd',
export const ARGENT_WALLET_DETECTOR_ADDRESS: AddressMap = {
[SupportedChainId.MAINNET]: '0xeca4B0bDBf7c55E9b7925919d03CbF8Dc82537E8',
}
export const SWAP_ROUTER_ADDRESSES = constructSameAddressMap('0xE592427A0AEce92De3Edee1F18E0157C05861564')
export const V3_MIGRATOR_ADDRESSES = constructSameAddressMap('0xA5644E29708357803b5A882D272c41cC0dF92B34')
export const V3_CORE_FACTORY_ADDRESSES: AddressMap = {
...constructSameAddressMap(V3_FACTORY_ADDRESS, true),
[SupportedChainId.ARBITRUM_KOVAN]: '0xf594DEF7751440197879149f46E98b334E6DF1fa',
}
export const QUOTER_ADDRESSES: AddressMap = {
...constructSameAddressMap('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6', true),
[SupportedChainId.ARBITRUM_KOVAN]: '0xAC06b88FA9adB7584A659b190F37F085352cB783',
}
export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES: AddressMap = {
...constructSameAddressMap('0xC36442b4a4522E871399CD717aBDD847Ab11FE88', true),
[SupportedChainId.ARBITRUM_KOVAN]: '0x9E1498aE1F508E86462e8A0F213CF385A6622464',
}
export const ENS_REGISTRAR_ADDRESSES: AddressMap = {
[SupportedChainId.MAINNET]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[SupportedChainId.ROPSTEN]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[SupportedChainId.GOERLI]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
[SupportedChainId.RINKEBY]: '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e',
}
export const SOCKS_CONTROLLER_ADDRESSES: AddressMap = {
[SupportedChainId.MAINNET]: '0x65770b5283117639760beA3F867b69b3697a91dd',
}
export const SWAP_ROUTER_ADDRESSES: AddressMap = {
...constructSameAddressMap('0xE592427A0AEce92De3Edee1F18E0157C05861564', true),
[SupportedChainId.ARBITRUM_KOVAN]: '0x6ae2DE23F2BE35B3921ba15DA52e4b173667dCb9',
}
export const V3_MIGRATOR_ADDRESSES: AddressMap = constructSameAddressMap(
'0xA5644E29708357803b5A882D272c41cC0dF92B34',
true
)

9
src/constants/chains.ts Normal file

@ -0,0 +1,9 @@
export enum SupportedChainId {
MAINNET = 1,
ROPSTEN = 3,
RINKEBY = 4,
GOERLI = 5,
KOVAN = 42,
ARBITRUM_KOVAN = 144545313136048,
ARBITRUM_ONE = 42161,
}

@ -26,7 +26,6 @@ export const PRICE_IMPACT_WITHOUT_FEE_CONFIRM_MIN: Percent = new Percent(JSBI.Bi
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')

@ -1,6 +1,25 @@
// a list of tokens by chain
import { Currency, Ether, Token, WETH9 } from '@uniswap/sdk-core'
import { AMPL, DAI, ETH2X_FLI, FEI, FRAX, FXS, MIR, renBTC, TRIBE, UMA, UNI, USDC, USDT, UST, WBTC } from './tokens'
import { Currency, Token } from '@uniswap/sdk-core'
import { SupportedChainId } from './chains'
import {
AMPL,
DAI,
ExtendedEther,
FEI,
FRAX,
FXS,
MIR,
renBTC,
TRIBE,
UMA,
UNI,
USDC,
USDT,
UST,
WBTC,
ETH2X_FLI,
WETH9_EXTENDED,
} from './tokens'
type ChainTokenList = {
readonly [chainId: number]: Token[]
@ -31,11 +50,13 @@ const mAssetsAdditionalBases: { [tokenAddress: string]: Token[] } = {
'0xf72FCd9DCF0190923Fadd44811E240Ef4533fc86': [MIR, UST], // mVIXY
}
const WETH_ONLY: ChainTokenList = {
[1]: [WETH9[1]],
[3]: [WETH9[3]],
[4]: [WETH9[4]],
[5]: [WETH9[5]],
[42]: [WETH9[42]],
[SupportedChainId.MAINNET]: [WETH9_EXTENDED[SupportedChainId.MAINNET]],
[SupportedChainId.ROPSTEN]: [WETH9_EXTENDED[SupportedChainId.ROPSTEN]],
[SupportedChainId.RINKEBY]: [WETH9_EXTENDED[SupportedChainId.RINKEBY]],
[SupportedChainId.GOERLI]: [WETH9_EXTENDED[SupportedChainId.GOERLI]],
[SupportedChainId.KOVAN]: [WETH9_EXTENDED[SupportedChainId.KOVAN]],
[SupportedChainId.ARBITRUM_KOVAN]: [WETH9_EXTENDED[SupportedChainId.ARBITRUM_KOVAN]],
[SupportedChainId.ARBITRUM_ONE]: [WETH9_EXTENDED[SupportedChainId.ARBITRUM_ONE]],
}
// used to construct intermediary pairs for trading
export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = {
@ -65,7 +86,7 @@ export const ADDITIONAL_BASES: { [chainId: number]: { [tokenAddress: string]: To
*/
export const CUSTOM_BASES: { [chainId: number]: { [tokenAddress: string]: Token[] } } = {
[1]: {
[AMPL.address]: [DAI, WETH9[1]],
[AMPL.address]: [DAI, WETH9_EXTENDED[1]],
},
}
@ -73,11 +94,19 @@ export const CUSTOM_BASES: { [chainId: number]: { [tokenAddress: string]: Token[
* Shows up in the currency select for swap and add liquidity
*/
export const COMMON_BASES: ChainCurrencyList = {
[1]: [Ether.onChain(1), DAI, USDC, USDT, WBTC, WETH9[1]],
[3]: [Ether.onChain(3), WETH9[3]],
[4]: [Ether.onChain(4), WETH9[4]],
[5]: [Ether.onChain(5), WETH9[5]],
[42]: [Ether.onChain(42), WETH9[42]],
[1]: [ExtendedEther.onChain(1), DAI, USDC, USDT, WBTC, WETH9_EXTENDED[1]],
[3]: [ExtendedEther.onChain(3), WETH9_EXTENDED[3]],
[4]: [ExtendedEther.onChain(4), WETH9_EXTENDED[4]],
[5]: [ExtendedEther.onChain(5), WETH9_EXTENDED[5]],
[42]: [ExtendedEther.onChain(42), WETH9_EXTENDED[42]],
[SupportedChainId.ARBITRUM_KOVAN]: [
ExtendedEther.onChain(SupportedChainId.ARBITRUM_KOVAN),
WETH9_EXTENDED[SupportedChainId.ARBITRUM_KOVAN],
],
[SupportedChainId.ARBITRUM_ONE]: [
ExtendedEther.onChain(SupportedChainId.ARBITRUM_ONE),
WETH9_EXTENDED[SupportedChainId.ARBITRUM_ONE],
],
}
// used to construct the list of all pairs we consider by default in the frontend

@ -1,5 +1,6 @@
import { Token } from '@uniswap/sdk-core'
import { WETH9, Token, Ether } from '@uniswap/sdk-core'
import { UNI_ADDRESS } from './addresses'
import { SupportedChainId } from './chains'
export const AMPL = new Token(1, '0xD46bA6D942050d489DBd938a2C909A5d5039A161', 9, 'AMPL', 'Ampleforth')
export const DAI = new Token(1, '0x6B175474E89094C44Da98b954EedeAC495271d0F', 18, 'DAI', 'Dai Stablecoin')
@ -23,9 +24,37 @@ export const ETH2X_FLI = new Token(
export const UST = new Token(1, '0xa47c8bf37f92abed4a126bda807a7b7498661acd', 18, 'UST', 'Wrapped UST')
export const MIR = new Token(1, '0x09a3ecafa817268f77be1283176b946c4ff2e608', 18, 'MIR', 'Wrapped MIR')
export const UNI: { [chainId: number]: Token } = {
[1]: new Token(1, UNI_ADDRESS[1], 18, 'UNI', 'Uniswap'),
[4]: new Token(4, UNI_ADDRESS[4], 18, 'UNI', 'Uniswap'),
[3]: new Token(3, UNI_ADDRESS[3], 18, 'UNI', 'Uniswap'),
[5]: new Token(5, UNI_ADDRESS[5], 18, 'UNI', 'Uniswap'),
[42]: new Token(42, UNI_ADDRESS[42], 18, 'UNI', 'Uniswap'),
[SupportedChainId.MAINNET]: new Token(SupportedChainId.MAINNET, UNI_ADDRESS[1], 18, 'UNI', 'Uniswap'),
[SupportedChainId.RINKEBY]: new Token(SupportedChainId.RINKEBY, UNI_ADDRESS[4], 18, 'UNI', 'Uniswap'),
[SupportedChainId.ROPSTEN]: new Token(SupportedChainId.ROPSTEN, UNI_ADDRESS[3], 18, 'UNI', 'Uniswap'),
[SupportedChainId.GOERLI]: new Token(SupportedChainId.GOERLI, UNI_ADDRESS[5], 18, 'UNI', 'Uniswap'),
[SupportedChainId.KOVAN]: new Token(SupportedChainId.KOVAN, UNI_ADDRESS[42], 18, 'UNI', 'Uniswap'),
}
export const WETH9_EXTENDED: { [chainId: number]: Token } = {
...WETH9,
[SupportedChainId.ARBITRUM_KOVAN]: new Token(
SupportedChainId.ARBITRUM_KOVAN,
'0x4A5e4A42dC430f669086b417AADf2B128beFEfac',
18,
'WETH9',
'Wrapped Ether'
),
[SupportedChainId.ARBITRUM_ONE]: new Token(
SupportedChainId.ARBITRUM_ONE,
'0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
18,
'WETH',
'Wrapped Ether'
),
}
export class ExtendedEther extends Ether {
public get wrapped(): Token {
if (this.chainId in WETH9_EXTENDED) return WETH9_EXTENDED[this.chainId]
throw new Error('Unsupported chain ID')
}
public static onChain(chainId: number): ExtendedEther {
return new ExtendedEther(chainId)
}
}

@ -1,8 +1,9 @@
import { parseBytes32String } from '@ethersproject/strings'
import { Currency, Ether, Token } from '@uniswap/sdk-core'
import { Currency, Token } from '@uniswap/sdk-core'
import { arrayify } from 'ethers/lib/utils'
import { useMemo } from 'react'
import { createTokenFilterFunction } from '../components/SearchModal/filtering'
import { ExtendedEther, WETH9_EXTENDED } from '../constants/tokens'
import { useAllLists, useCombinedActiveList, useInactiveListUrls } from '../state/lists/hooks'
import { WrappedTokenInfo } from '../state/lists/wrappedTokenInfo'
import { NEVER_RELOAD, useSingleCallResult } from '../state/multicall/hooks'
@ -22,10 +23,13 @@ function useTokensFromMap(tokenMap: TokenAddressMap, includeUserAdded: boolean):
if (!chainId) return {}
// reduce to just tokens
const mapWithoutUrls = Object.keys(tokenMap[chainId]).reduce<{ [address: string]: Token }>((newMap, address) => {
newMap[address] = tokenMap[chainId][address].token
return newMap
}, {})
const mapWithoutUrls = Object.keys(tokenMap[chainId] ?? {}).reduce<{ [address: string]: Token }>(
(newMap, address) => {
newMap[address] = tokenMap[chainId][address].token
return newMap
},
{}
)
if (includeUserAdded) {
return (
@ -175,5 +179,7 @@ export function useCurrency(currencyId: string | undefined): Currency | null | u
const { chainId } = useActiveWeb3React()
const isETH = currencyId?.toUpperCase() === 'ETH'
const token = useToken(isETH ? undefined : currencyId)
return isETH ? (chainId ? Ether.onChain(chainId) : undefined) : token
const weth = chainId ? WETH9_EXTENDED[chainId] : undefined
if (weth?.address?.toLowerCase() === currencyId?.toLowerCase()) return weth
return isETH ? (chainId ? ExtendedEther.onChain(chainId) : undefined) : token
}

@ -1,5 +1,4 @@
import { Contract } from '@ethersproject/contracts'
import { WETH9 } from '@uniswap/sdk-core'
import { abi as GOVERNANCE_ABI } from '@uniswap/governance/build/GovernorAlpha.json'
import { abi as UNI_ABI } from '@uniswap/governance/build/Uni.json'
import { abi as STAKING_REWARDS_ABI } from '@uniswap/liquidity-staker/build/StakingRewards.json'
@ -42,7 +41,7 @@ import { NonfungiblePositionManager } from 'types/v3/NonfungiblePositionManager'
import { V3Migrator } from 'types/v3/V3Migrator'
import { getContract } from 'utils'
import { Erc20, ArgentWalletDetector, EnsPublicResolver, EnsRegistrar, Multicall2, Weth } from '../abis/types'
import { UNI } from '../constants/tokens'
import { UNI, WETH9_EXTENDED } from '../constants/tokens'
import { useActiveWeb3React } from './web3'
// returns null on errors
@ -78,7 +77,7 @@ export function useTokenContract(tokenAddress?: string, withSignerIfPossible?: b
export function useWETHContract(withSignerIfPossible?: boolean) {
const { chainId } = useActiveWeb3React()
return useContract<Weth>(chainId ? WETH9[chainId]?.address : undefined, WETH_ABI, withSignerIfPossible)
return useContract<Weth>(chainId ? WETH9_EXTENDED[chainId]?.address : undefined, WETH_ABI, withSignerIfPossible)
}
export function useArgentWalletDetectorContract() {

@ -131,7 +131,7 @@ export function useERC20Permit(
const nonceInputs = useMemo(() => [account ?? undefined], [account])
const tokenNonceState = useSingleCallResult(eip2612Contract, 'nonces', nonceInputs)
const permitInfo =
overridePermitInfo ?? (chainId && tokenAddress ? PERMITTABLE_TOKENS[chainId][tokenAddress] : undefined)
overridePermitInfo ?? (chainId && tokenAddress ? PERMITTABLE_TOKENS[chainId]?.[tokenAddress] : undefined)
const [signatureData, setSignatureData] = useState<SignatureData | null>(null)

@ -1,13 +1,16 @@
import { Currency, CurrencyAmount, Price, Token } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { SupportedChainId } from '../constants/chains'
import { USDC } from '../constants/tokens'
import { useV2TradeExactOut } from './useV2Trade'
import { useBestV3TradeExactOut } from './useBestV3Trade'
import { useActiveWeb3React } from './web3'
// USDC amount used when calculating spot price for a given currency.
// Stablecoin amounts used when calculating spot price for a given currency.
// The amount is large enough to filter low liquidity pairs.
const USDC_CURRENCY_AMOUNT_OUT = CurrencyAmount.fromRawAmount(USDC, 100_000e6)
const STABLECOIN_AMOUNT_OUT: { [chainId: number]: CurrencyAmount<Token> } = {
[SupportedChainId.MAINNET]: CurrencyAmount.fromRawAmount(USDC, 100_000e6),
}
/**
* Returns the price in USDC of the input currency
@ -16,36 +19,35 @@ const USDC_CURRENCY_AMOUNT_OUT = CurrencyAmount.fromRawAmount(USDC, 100_000e6)
export default function useUSDCPrice(currency?: Currency): Price<Currency, Token> | undefined {
const { chainId } = useActiveWeb3React()
const v2USDCTrade = useV2TradeExactOut(currency, chainId === 1 ? USDC_CURRENCY_AMOUNT_OUT : undefined, {
const amountOut = chainId ? STABLECOIN_AMOUNT_OUT[chainId] : undefined
const stablecoin = amountOut?.currency
const v2USDCTrade = useV2TradeExactOut(currency, amountOut, {
maxHops: 2,
})
const v3USDCTrade = useBestV3TradeExactOut(currency, chainId === 1 ? USDC_CURRENCY_AMOUNT_OUT : undefined)
const v3USDCTrade = useBestV3TradeExactOut(currency, amountOut)
return useMemo(() => {
if (!currency || !chainId) {
return undefined
}
if (chainId !== 1) {
if (!currency || !stablecoin) {
return undefined
}
// handle usdc
if (currency?.wrapped.equals(USDC)) {
return new Price(USDC, USDC, '1', '1')
if (currency?.wrapped.equals(stablecoin)) {
return new Price(stablecoin, stablecoin, '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)
return new Price(currency, stablecoin, denominator, numerator)
} else if (v3USDCTrade.trade) {
const { numerator, denominator } = v3USDCTrade.trade.route.midPrice
return new Price(currency, USDC, denominator, numerator)
return new Price(currency, stablecoin, denominator, numerator)
}
return undefined
}, [chainId, currency, v2USDCTrade, v3USDCTrade])
}, [currency, stablecoin, v2USDCTrade, v3USDCTrade.trade])
}
export function useUSDCValue(currencyAmount: CurrencyAmount<Currency> | undefined | null) {

@ -1,7 +1,8 @@
import { Pair } from '@uniswap/v2-sdk'
import { computePairAddress, 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 { V2_FACTORY_ADDRESSES } from '../constants/addresses'
import { useMultipleContractSingleData } from '../state/multicall/hooks'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
@ -23,7 +24,13 @@ export function useV2Pairs(currencies: [Currency | undefined, Currency | undefin
const pairAddresses = useMemo(
() =>
tokens.map(([tokenA, tokenB]) => {
return tokenA && tokenB && !tokenA.equals(tokenB) ? Pair.getAddress(tokenA, tokenB) : undefined
return tokenA &&
tokenB &&
tokenA.chainId === tokenB.chainId &&
!tokenA.equals(tokenB) &&
V2_FACTORY_ADDRESSES[tokenA.chainId]
? computePairAddress({ factoryAddress: V2_FACTORY_ADDRESSES[tokenA.chainId], tokenA, tokenB })
: undefined
}),
[tokens]
)

@ -1,5 +1,6 @@
import { Currency, WETH9 } from '@uniswap/sdk-core'
import { Currency } from '@uniswap/sdk-core'
import { useMemo } from 'react'
import { WETH9_EXTENDED } from '../constants/tokens'
import { tryParseAmount } from '../state/swap/hooks'
import { useTransactionAdder } from '../state/transactions/hooks'
import { useCurrencyBalance } from '../state/wallet/hooks'
@ -33,7 +34,7 @@ export default function useWrapCallback(
return useMemo(() => {
if (!wethContract || !chainId || !inputCurrency || !outputCurrency) return NOT_APPLICABLE
const weth = WETH9[chainId]
const weth = WETH9_EXTENDED[chainId]
if (!weth) return NOT_APPLICABLE
const hasInputAmount = Boolean(inputAmount?.greaterThan('0'))

@ -1574,18 +1574,31 @@ msgstr "Kyk na opgelope fooie en analise <0> ↗</0>"
msgid "View list"
msgstr "Kyk na lys"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Uitsig op Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Uitsig op Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Besigtig transaksie op Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Besigtig transaksie op Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~ $ <0 />"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Terug na swembaddens"

@ -1574,18 +1574,31 @@ msgstr "عرض الرسوم المتراكمة والتحليلات <0>↗</0>"
msgid "View list"
msgstr "عرض القائمة"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "عرض على المسح الضوئي"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "عرض على المسح الضوئي"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "عرض المعاملة على المسح الضوئي"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "عرض المعاملة على المسح الضوئي"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← العودة إلى نظرة عامة للمتجمعات"

@ -1574,18 +1574,31 @@ msgstr "Consulteu els honoraris i les taxes acumulades <0> ↗</0>"
msgid "View list"
msgstr "Veure llista"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Veure a Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Veure a Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Veure transacció a Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Veure transacció a Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~ $ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Torna a la descripció general de les piscines"

@ -1574,18 +1574,31 @@ msgstr "Zobrazit naběhlé poplatky a analýzy<0>↗</0>"
msgid "View list"
msgstr "Zobrazit seznam"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Zobrazit při Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Zobrazit při Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Zobrazit transakci v etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Zobrazit transakci v etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "Přehled zpátky do bazénu"

@ -1574,18 +1574,31 @@ msgstr "Se påløbne gebyrer og analytiker<0>:up-Χ:</0>"
msgid "View list"
msgstr "Vis liste"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Se på Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Se på Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Se transaktion på Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Se transaktion på Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Tilbage til Pools Oversigt"

@ -1574,18 +1574,31 @@ msgstr "Angenommene Gebühren und Analysen anzeigen<0>:up-right_pfeil anzeigen:<
msgid "View list"
msgstr "Liste anzeigen"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Auf Etherscan anzeigen"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Auf Etherscan anzeigen"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Transaktion auf Etherscan anzeigen"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Transaktion auf Etherscan anzeigen"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Zurück zu Pools Übersicht"

@ -1574,18 +1574,31 @@ msgstr "Προβολή δεδουλευμένων τελών και αναλύσ
msgid "View list"
msgstr "Προβολή λίστας"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Προβολή στην Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Προβολή στην Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Προβολή συναλλαγής στην Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Προβολή συναλλαγής στην Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Επιστροφή στις πισίνες"

@ -1574,18 +1574,31 @@ msgstr "Ver comisiones acumuladas y analíticas<0>↗</0>"
msgid "View list"
msgstr "Ver lista"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Ver en Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Ver en Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Ver transacción en Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Ver transacción en Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Volver a la vista general de las piscinas"

@ -1574,18 +1574,31 @@ msgstr "Näytä kertynyt maksu ja analytiikka<0>↗</0>"
msgid "View list"
msgstr "Näytä lista"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Näytä Etherscanissa"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Näytä Etherscanissa"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Näytä tapahtuma Etherscanissa"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Näytä tapahtuma Etherscanissa"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Takaisin altaisiin Yleiskatsaus"

@ -1574,18 +1574,31 @@ msgstr "Voir les frais et les analyses accumulés<0>↗</0>"
msgid "View list"
msgstr "Voir la liste"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Voir sur Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Voir sur Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Voir la transaction sur Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Voir la transaction sur Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "Aperçu du retour aux pools"

@ -1574,18 +1574,31 @@ msgstr "צפו בעמלות וניתוחים צבורים <0> ↗</0>"
msgid "View list"
msgstr "רשימת צפיה"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "מבט על אתרסקאן"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "מבט על אתרסקאן"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "צפה בעסקה ב- Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "צפה בעסקה ב- Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~ $ <0 />"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← חזרה לסקירת בריכות"

@ -1574,18 +1574,31 @@ msgstr "Tekintse meg az elhatárolt díjakat és elemzéseket <0> ↗</0>"
msgid "View list"
msgstr "Lista megtekintése"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Nézd meg az Etherscan webhelyen"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Nézd meg az Etherscan webhelyen"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Tranzakció megtekintése az Etherscan webhelyen"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Tranzakció megtekintése az Etherscan webhelyen"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~ $ <0 />"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Vissza a medencék áttekintéséhez"

@ -1574,18 +1574,31 @@ msgstr "Visualizza le commissioni e le analisi accumulate<0>↗</0>"
msgid "View list"
msgstr "Visualizza elenco"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Visualizza su Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Visualizza su Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Visualizza la transazione su Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Visualizza la transazione su Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Torna alla panoramica delle piscine"

@ -1574,18 +1574,31 @@ msgstr "発生した手数料と分析を表示<0>↗</0>"
msgid "View list"
msgstr "リストを表示"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Etherscan で表示"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Etherscan で表示"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Etherscan で取引を表示"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Etherscan で取引を表示"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "荷物の概要に戻る"

@ -1574,18 +1574,31 @@ msgstr "발생한 수수료 및 분석보기 <0> ↗</0>"
msgid "View list"
msgstr "목록보기"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Etherscan에서보기"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Etherscan에서보기"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Etherscan에서 거래보기"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Etherscan에서 거래보기"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~ $ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← 풀 개요로 돌아 가기"

@ -1574,18 +1574,31 @@ msgstr "Opgebouwde kosten en analytics weergeven<0>↗</0>"
msgid "View list"
msgstr "Lijst bekijken"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Bekijk op Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Bekijk op Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Bekijk transactie op Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Bekijk transactie op Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Terug naar Pools overzicht"

@ -1574,18 +1574,31 @@ msgstr "Vis påløpte gebyrer og analytiker<0>:opp' :</0>"
msgid "View list"
msgstr "Vis liste"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Vis ved Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Vis ved Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Vis transaksjon ved Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Vis transaksjon ved Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr " Tilbake til Pooloversikt"

@ -1574,18 +1574,31 @@ msgstr "Zobacz naliczone opłaty i analizy<0>↗</0>"
msgid "View list"
msgstr "Zobacz listę"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Zobacz na Etherskanie"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Zobacz na Etherskanie"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Zobacz transakcję na Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Zobacz transakcję na Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "◆ Powrót do podsumowania pul"

@ -1574,18 +1574,31 @@ msgstr "Veja taxas acumuladas e análises<0>↗</0>"
msgid "View list"
msgstr "Ver lista"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Ver no Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Ver no Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Ver transação em Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Ver transação em Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "Retorna a Visão Geral de Pools"

@ -1574,18 +1574,31 @@ msgstr "Veja taxas acumuladas e análises<0>↗</0>"
msgid "View list"
msgstr "Ver lista"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Ver no Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Ver no Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Ver transação em Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Ver transação em Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "Retorna a Visão Geral de Pools"

@ -1574,18 +1574,31 @@ msgstr "Vezi taxele acumulate și analizele<0>:up-~:</0>"
msgid "View list"
msgstr "Vezi lista"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Vezi pe Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Vezi pe Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Vizualizați tranzacția pe Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Vizualizați tranzacția pe Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "Înapoi la panouri de ansamblu"

@ -1574,18 +1574,31 @@ msgstr "Посмотреть начисленные комиссии и анал
msgid "View list"
msgstr "Просмотр списка"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Смотреть на Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Смотреть на Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Просмотреть транзакцию на Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Просмотреть транзакцию на Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Назад к пулам"

@ -1574,18 +1574,31 @@ msgstr "Погледајте обрачунате накнаде и аналит
msgid "View list"
msgstr "Погледајте листу"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Поглед на Етхерсцан-у"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Поглед на Етхерсцан-у"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Погледајте трансакцију на Етхерсцан-у"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Погледајте трансакцију на Етхерсцан-у"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~ $ <0 />"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Повратак на Преглед базена"

@ -1574,18 +1574,31 @@ msgstr "Visa upplupna avgifter och analytiker<0>↗</0>"
msgid "View list"
msgstr "Visa lista"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Visa på Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Visa på Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Visa transaktionen på Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Visa transaktionen på Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Tillbaka till Poolernas översikt"

@ -1574,18 +1574,31 @@ msgstr "Tahakkuk eden ücretleri ve analizleri görüntüleyin <0> ↗</0>"
msgid "View list"
msgstr "Listeyi görüntüle"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Etherscan üzerinde görüntüle"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Etherscan üzerinde görüntüle"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Etherscan'da işlemi görüntüle"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Etherscan'da işlemi görüntüle"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~ $ <0 />"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Havuzlara Genel Bakış'e geri dön"

@ -1574,18 +1574,31 @@ msgstr "Перегляд нарахованих комісій і аналіти
msgid "View list"
msgstr "Переглянути список"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Дивитись на Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Дивитись на Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Дивитись операцію на Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Дивитись операцію на Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Назад до пулів огляд"

@ -1574,18 +1574,31 @@ msgstr "Xem phí đã tích lũy và số liệu phân tích <0> ↗</0>"
msgid "View list"
msgstr "Danh sách xem"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "Xem trên Etherscan"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "Xem trên Etherscan"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "Xem giao dịch trên Etherscan"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "Xem giao dịch trên Etherscan"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~ $ <0 />"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "← Quay lại Tổng quan về Hồ bơi"

@ -1574,18 +1574,31 @@ msgstr "查看累积费用和分析<0>↗</0>"
msgid "View list"
msgstr "查看列表"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "在以太扫描上查看"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "在以太扫描上查看"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "在以太扫描上查看交易"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "在以太扫描上查看交易"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "~$ <0/>"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "format@@0 返回池概览"

@ -1574,18 +1574,31 @@ msgstr "查看應計費用和分析<0>↗</0>"
msgid "View list"
msgstr "查看清單"
#:
#:
#:
#~ msgid "View on Etherscan"
#~ msgstr "在Etherscan上查看"
#: src/components/AccountDetails/index.tsx
#: src/components/AccountDetails/index.tsx
#: src/components/TransactionConfirmationModal/index.tsx
msgid "View on Etherscan"
msgstr "在Etherscan上查看"
msgid "View on Explorer"
msgstr ""
#:
#:
#:
#:
#~ msgid "View transaction on Etherscan"
#~ msgstr "在Etherscan上查看交易"
#: src/components/ModalViews/index.tsx
#: src/components/claim/AddressClaimModal.tsx
#: src/components/claim/ClaimModal.tsx
#: src/components/vote/VoteModal.tsx
msgid "View transaction on Etherscan"
msgstr "在Etherscan上查看交易"
msgid "View transaction on Explorer"
msgstr ""
#: src/components/Header/index.tsx
msgid "Vote"
@ -1964,4 +1977,3 @@ msgstr "〜$ <0 />"
#: src/pages/Pool/PositionPage.tsx
msgid "← Back to Pools Overview"
msgstr "←返回泳池總覽"

@ -1,11 +1,11 @@
import React, { useCallback, useContext, useMemo, useState } from 'react'
import { TransactionResponse } from '@ethersproject/providers'
import { Currency, CurrencyAmount, 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/misc'
import { NONFUNGIBLE_POSITION_MANAGER_ADDRESSES } from '../../constants/addresses'
import { WETH9_EXTENDED } from '../../constants/tokens'
import { useArgentWalletContract } from '../../hooks/useArgentWalletContract'
import { useV3NFTPositionManagerContract } from '../../hooks/useContract'
import { RouteComponentProps } from 'react-router-dom'
@ -299,10 +299,10 @@ export default function AddLiquidity({
} else {
// prevent weth + eth
const isETHOrWETHNew =
currencyIdNew === 'ETH' || (chainId !== undefined && currencyIdNew === WETH9[chainId]?.address)
currencyIdNew === 'ETH' || (chainId !== undefined && currencyIdNew === WETH9_EXTENDED[chainId]?.address)
const isETHOrWETHOther =
currencyIdOther !== undefined &&
(currencyIdOther === 'ETH' || (chainId !== undefined && currencyIdOther === WETH9[chainId]?.address))
(currencyIdOther === 'ETH' || (chainId !== undefined && currencyIdOther === WETH9_EXTENDED[chainId]?.address))
if (isETHOrWETHNew && isETHOrWETHOther) {
return [currencyIdNew, undefined]

@ -1,8 +1,8 @@
import { useActiveWeb3React } from 'hooks/web3'
import React from 'react'
import { Redirect, RouteComponentProps } from 'react-router-dom'
import { WETH9_EXTENDED } from '../../constants/tokens'
import AddLiquidity from './index'
import { WETH9 } from '@uniswap/sdk-core'
export function RedirectDuplicateTokenIds(
props: RouteComponentProps<{ currencyIdA: string; currencyIdB: string; feeAmount?: string }>
@ -16,8 +16,10 @@ export function RedirectDuplicateTokenIds(
const { chainId } = useActiveWeb3React()
// prevent weth + eth
const isETHOrWETHA = currencyIdA === 'ETH' || (chainId !== undefined && currencyIdA === WETH9[chainId]?.address)
const isETHOrWETHB = currencyIdB === 'ETH' || (chainId !== undefined && currencyIdB === WETH9[chainId]?.address)
const isETHOrWETHA =
currencyIdA === 'ETH' || (chainId !== undefined && currencyIdA === WETH9_EXTENDED[chainId]?.address)
const isETHOrWETHB =
currencyIdB === 'ETH' || (chainId !== undefined && currencyIdB === WETH9_EXTENDED[chainId]?.address)
if (
currencyIdA &&

@ -1,6 +1,6 @@
import { BigNumber } from '@ethersproject/bignumber'
import { TransactionResponse } from '@ethersproject/providers'
import { Currency, CurrencyAmount, Percent, WETH9 } from '@uniswap/sdk-core'
import { Currency, CurrencyAmount, Percent } from '@uniswap/sdk-core'
import React, { useCallback, useContext, useState } from 'react'
import { Plus } from 'react-feather'
import ReactGA from 'react-ga'
@ -18,6 +18,7 @@ import { MinimalPositionCard } from '../../components/PositionCard'
import Row, { RowBetween, RowFlat } from '../../components/Row'
import { ZERO_PERCENT } from '../../constants/misc'
import { WETH9_EXTENDED } from '../../constants/tokens'
import { useV2RouterContract } from '../../hooks/useContract'
import { PairState } from '../../hooks/useV2Pairs'
import { useActiveWeb3React } from '../../hooks/web3'
@ -58,7 +59,9 @@ export default function AddLiquidity({
const currencyB = useCurrency(currencyIdB)
const oneCurrencyIsWETH = Boolean(
chainId && ((currencyA && currencyA.equals(WETH9[chainId])) || (currencyB && currencyB.equals(WETH9[chainId])))
chainId &&
((currencyA && currencyA.equals(WETH9_EXTENDED[chainId])) ||
(currencyB && currencyB.equals(WETH9_EXTENDED[chainId])))
)
const toggleWalletModal = useWalletModalToggle() // toggle wallet when disconnected

@ -1,13 +1,14 @@
import JSBI from 'jsbi'
import React, { useCallback, useMemo, useState, useEffect, ReactNode } from 'react'
import { Fraction, Percent, Price, Token, CurrencyAmount, WETH9 } from '@uniswap/sdk-core'
import { FACTORY_ADDRESS } from '@uniswap/v2-sdk'
import { Fraction, Percent, Price, Token, CurrencyAmount } from '@uniswap/sdk-core'
import { Redirect, RouteComponentProps } from 'react-router'
import { Text } from 'rebass'
import { AutoColumn } from '../../components/Column'
import CurrencyLogo from '../../components/CurrencyLogo'
import FormattedCurrencyAmount from '../../components/FormattedCurrencyAmount'
import { AutoRow, RowBetween, RowFixed } from '../../components/Row'
import { V2_FACTORY_ADDRESSES } from '../../constants/addresses'
import { WETH9_EXTENDED } from '../../constants/tokens'
import { useV2LiquidityTokenPermit } from '../../hooks/useERC20Permit'
import useIsArgentWallet from '../../hooks/useIsArgentWallet'
import { useTotalSupply } from '../../hooks/useTotalSupply'
@ -123,9 +124,10 @@ function V2PairMigration({
}) {
const { chainId, account } = useActiveWeb3React()
const theme = useTheme()
const v2FactoryAddress = chainId ? V2_FACTORY_ADDRESSES[chainId] : undefined
const pairFactory = useSingleCallResult(pair, 'factory')
const isNotUniswap = pairFactory.result?.[0] && pairFactory.result[0] !== FACTORY_ADDRESS
const isNotUniswap = pairFactory.result?.[0] && pairFactory.result[0] !== v2FactoryAddress
const deadline = useTransactionDeadline() // custom from users settings
const blockTimestamp = useCurrentBlockTimestamp()
@ -593,9 +595,10 @@ function V2PairMigration({
<TYPE.black fontSize={12}>
<Trans>
At least {formatCurrencyAmount(refund0, 4)}{' '}
{token0.equals(WETH9[chainId]) ? 'ETH' : token0.symbol} and {formatCurrencyAmount(refund1, 4)}{' '}
{token1.equals(WETH9[chainId]) ? 'ETH' : token1.symbol} will be refunded to your wallet due to
selected price range.
{token0.equals(WETH9_EXTENDED[chainId]) ? 'ETH' : token0.symbol} and{' '}
{formatCurrencyAmount(refund1, 4)}{' '}
{token1.equals(WETH9_EXTENDED[chainId]) ? 'ETH' : token1.symbol} will be refunded to your wallet
due to selected price range.
</Trans>
</TYPE.black>
) : null}

@ -5,6 +5,7 @@ import { ThemeContext } from 'styled-components'
import { AutoColumn } from '../../components/Column'
import { AutoRow } from '../../components/Row'
import { Text } from 'rebass'
import { V2_FACTORY_ADDRESSES } from '../../constants/addresses'
import { useActiveWeb3React } from '../../hooks/web3'
import { useTokenBalancesWithLoadingIndicator } from '../../state/wallet/hooks'
import { BackArrow, StyledInternalLink, TYPE } from '../../theme'
@ -51,6 +52,8 @@ export default function MigrateV2() {
const theme = useContext(ThemeContext)
const { account, chainId } = useActiveWeb3React()
const v2FactoryAddress = chainId ? V2_FACTORY_ADDRESSES[chainId] : undefined
// fetch the user's balances of all tracked V2 LP tokens
const trackedTokenPairs = useTrackedTokenPairs()
@ -61,12 +64,12 @@ export default function MigrateV2() {
// sushi liquidity token or null
const sushiLiquidityToken = chainId === 1 ? toSushiLiquidityToken(tokens) : null
return {
v2liquidityToken: toV2LiquidityToken(tokens),
v2liquidityToken: v2FactoryAddress ? toV2LiquidityToken(tokens) : undefined,
sushiLiquidityToken,
tokens,
}
}),
[trackedTokenPairs, chainId]
[trackedTokenPairs, chainId, v2FactoryAddress]
)
// get pair liquidity token addresses for balance-fetching purposes
@ -90,7 +93,7 @@ export default function MigrateV2() {
if (fetchingPairBalances) return []
return tokenPairsWithLiquidityTokens
.filter(({ v2liquidityToken }) => pairBalances[v2liquidityToken.address]?.greaterThan(0))
.filter(({ v2liquidityToken }) => v2liquidityToken && pairBalances[v2liquidityToken.address]?.greaterThan(0))
.map((tokenPairsWithLiquidityTokens) => tokenPairsWithLiquidityTokens.tokens)
}, [fetchingPairBalances, tokenPairsWithLiquidityTokens, pairBalances])

@ -1,4 +1,4 @@
import { Currency, CurrencyAmount, Ether, Token } from '@uniswap/sdk-core'
import { Currency, CurrencyAmount, Token } from '@uniswap/sdk-core'
import JSBI from 'jsbi'
import React, { useCallback, useEffect, useState } from 'react'
import { Plus } from 'react-feather'
@ -11,6 +11,7 @@ import { FindPoolTabs } from '../../components/NavigationTabs'
import { MinimalPositionCard } from '../../components/PositionCard'
import Row from '../../components/Row'
import CurrencySearchModal from '../../components/SearchModal/CurrencySearchModal'
import { ExtendedEther } from '../../constants/tokens'
import { PairState, useV2Pair } from '../../hooks/useV2Pairs'
import { useActiveWeb3React } from '../../hooks/web3'
import { usePairAdder } from '../../state/user/hooks'
@ -41,7 +42,7 @@ export default function PoolFinder() {
const [showSearch, setShowSearch] = useState<boolean>(false)
const [activeField, setActiveField] = useState<number>(Fields.TOKEN1)
const [currency0, setCurrency0] = useState<Currency | null>(() => (chainId ? Ether.onChain(chainId) : null))
const [currency0, setCurrency0] = useState<Currency | null>(() => (chainId ? ExtendedEther.onChain(chainId) : null))
const [currency1, setCurrency1] = useState<Currency | null>(null)
const [pairState, pair] = useV2Pair(currency0 ?? undefined, currency1 ?? undefined)

@ -1,6 +1,7 @@
import React, { useCallback, useMemo, useState } from 'react'
import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import { Redirect, RouteComponentProps } from 'react-router-dom'
import { WETH9_EXTENDED } from '../../constants/tokens'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import AppBody from '../AppBody'
import { BigNumber } from '@ethersproject/bignumber'
@ -22,7 +23,7 @@ import ReactGA from 'react-ga'
import { useActiveWeb3React } from 'hooks/web3'
import { TransactionResponse } from '@ethersproject/providers'
import { useTransactionAdder } from 'state/transactions/hooks'
import { Percent, WETH9 } from '@uniswap/sdk-core'
import { Percent } from '@uniswap/sdk-core'
import { TYPE } from 'theme'
import { Wrapper, SmallMaxButton, ResponsiveHeaderText } from './styled'
import Loader from 'components/Loader'
@ -378,8 +379,8 @@ function Remove({ tokenId }: { tokenId: BigNumber }) {
liquidityValue1?.currency &&
(liquidityValue0.currency.isNative ||
liquidityValue1.currency.isNative ||
liquidityValue0.currency.wrapped.equals(WETH9[liquidityValue0.currency.chainId]) ||
liquidityValue1.currency.wrapped.equals(WETH9[liquidityValue1.currency.chainId])) ? (
liquidityValue0.currency.wrapped.equals(WETH9_EXTENDED[liquidityValue0.currency.chainId]) ||
liquidityValue1.currency.wrapped.equals(WETH9_EXTENDED[liquidityValue1.currency.chainId])) ? (
<RowBetween>
<TYPE.main>
<Trans>Collect as WETH</Trans>

@ -1,6 +1,6 @@
import { Contract } from '@ethersproject/contracts'
import { TransactionResponse } from '@ethersproject/providers'
import { Currency, Percent, WETH9 } from '@uniswap/sdk-core'
import { Currency, Percent } from '@uniswap/sdk-core'
import React, { useCallback, useContext, useMemo, useState } from 'react'
import { ArrowDown, Plus } from 'react-feather'
import ReactGA from 'react-ga'
@ -19,6 +19,7 @@ import Row, { RowBetween, RowFixed } from '../../components/Row'
import Slider from '../../components/Slider'
import CurrencyLogo from '../../components/CurrencyLogo'
import { WETH9_EXTENDED } from '../../constants/tokens'
import { useActiveWeb3React } from '../../hooks/web3'
import { useCurrency } from '../../hooks/Tokens'
import { usePairContract, useV2RouterContract } from '../../hooks/useContract'
@ -382,7 +383,9 @@ export default function RemoveLiquidity({
const oneCurrencyIsETH = currencyA?.isNative || currencyB?.isNative
const oneCurrencyIsWETH = Boolean(
chainId && WETH9[chainId] && (currencyA?.equals(WETH9[chainId]) || currencyB?.equals(WETH9[chainId]))
chainId &&
WETH9_EXTENDED[chainId] &&
(currencyA?.equals(WETH9_EXTENDED[chainId]) || currencyB?.equals(WETH9_EXTENDED[chainId]))
)
const handleSelectCurrencyA = useCallback(
@ -525,16 +528,16 @@ export default function RemoveLiquidity({
<RowBetween style={{ justifyContent: 'flex-end' }}>
{oneCurrencyIsETH ? (
<StyledInternalLink
to={`/remove/v2/${currencyA?.isNative ? WETH9[chainId].address : currencyIdA}/${
currencyB?.isNative ? WETH9[chainId].address : currencyIdB
to={`/remove/v2/${currencyA?.isNative ? WETH9_EXTENDED[chainId].address : currencyIdA}/${
currencyB?.isNative ? WETH9_EXTENDED[chainId].address : currencyIdB
}`}
>
Receive WETH
</StyledInternalLink>
) : oneCurrencyIsWETH ? (
<StyledInternalLink
to={`/remove/v2/${currencyA?.equals(WETH9[chainId]) ? 'ETH' : currencyIdA}/${
currencyB?.equals(WETH9[chainId]) ? 'ETH' : currencyIdB
to={`/remove/v2/${currencyA?.equals(WETH9_EXTENDED[chainId]) ? 'ETH' : currencyIdA}/${
currencyB?.equals(WETH9_EXTENDED[chainId]) ? 'ETH' : currencyIdB
}`}
>
Receive ETH

@ -3,6 +3,7 @@ import { isAddress } from 'ethers/lib/utils'
import { PROPOSAL_DESCRIPTION_TEXT } from '../../constants/proposals'
import { UNI } from '../../constants/tokens'
import { useGovernanceContract, useUniContract } from '../../hooks/useContract'
import usePrevious from '../../hooks/usePrevious'
import { calculateGasMargin } from '../../utils/calculateGasMargin'
import { useSingleCallResult, useSingleContractMultipleData } from '../multicall/hooks'
import { useActiveWeb3React } from '../../hooks/web3'
@ -59,47 +60,62 @@ export function useProposalCount(): number | undefined {
*/
const eventParser = new ethers.utils.Interface(GOV_ABI)
export function useDataFromEventLogs() {
const { library } = useActiveWeb3React()
const [formattedEvents, setFormattedEvents] = useState<any>()
const { library, chainId } = useActiveWeb3React()
const [formattedEvents, setFormattedEvents] =
useState<{ description: string; details: { target: string; functionSig: string; callData: string }[] }[]>()
const govContract = useGovernanceContract()
// create filter for these specific events
const filter = useMemo(
() => ({ ...govContract?.filters?.['ProposalCreated'](), fromBlock: 0, toBlock: 'latest' }),
() => (govContract ? { ...govContract.filters.ProposalCreated(), fromBlock: 0, toBlock: 'latest' } : undefined),
[govContract]
)
const previousChainId = usePrevious(chainId)
useEffect(() => {
async function fetchData() {
const pastEvents = await library?.getLogs(filter)
// reverse events to get them from newest to odlest
const formattedEventData = pastEvents
?.map((event) => {
const eventParsed = eventParser.parseLog(event).args
return {
description: eventParsed.description,
details: eventParsed.targets.map((target: string, i: number) => {
const signature = eventParsed.signatures[i]
const [name, types] = signature.substr(0, signature.length - 1).split('(')
if (!filter || !library || chainId === previousChainId) return
let stale = false
const calldata = eventParsed.calldatas[i]
const decoded = utils.defaultAbiCoder.decode(types.split(','), calldata)
return {
target,
functionSig: name,
callData: decoded.join(', '),
}
}),
}
})
.reverse()
setFormattedEvents(formattedEventData)
}
if (!formattedEvents) {
fetchData()
library
.getLogs(filter)
.then((proposalEvents) => {
if (stale) return
// reverse events to get them from newest to odlest
const formattedEventData = proposalEvents
?.map((event) => {
const eventParsed = eventParser.parseLog(event).args
return {
description: eventParsed.description,
details: eventParsed.targets.map((target: string, i: number) => {
const signature = eventParsed.signatures[i]
const [name, types] = signature.substr(0, signature.length - 1).split('(')
const calldata = eventParsed.calldatas[i]
const decoded = utils.defaultAbiCoder.decode(types.split(','), calldata)
return {
target,
functionSig: name,
callData: decoded.join(', '),
}
}),
}
})
.reverse()
setFormattedEvents(formattedEventData)
})
.catch((error) => {
console.error('Failed to fetch proposals', error)
})
return () => {
stale = true
}
}
}, [filter, library, formattedEvents])
return
}, [filter, library, formattedEvents, chainId, previousChainId])
return formattedEvents
}

@ -45,8 +45,9 @@ async function fetchChunk(
throw error
}
if (resultsBlockNumber < minBlockNumber) {
console.debug(`Fetched results for old block number: ${resultsBlockNumber.toString()} vs. ${minBlockNumber}`)
throw new RetryableError('Fetched for old block number')
const retryMessage = `Fetched results for old block number: ${resultsBlockNumber.toString()} vs. ${minBlockNumber}`
console.debug(retryMessage)
throw new RetryableError(retryMessage)
}
return { results, blockNumber: resultsBlockNumber }
}

@ -1,9 +1,9 @@
import { t } from '@lingui/macro'
import { Token, CurrencyAmount, WETH9 } from '@uniswap/sdk-core'
import { Token, CurrencyAmount } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import JSBI from 'jsbi'
import { useMemo } from 'react'
import { DAI, UNI, USDC, USDT, WBTC } from '../../constants/tokens'
import { DAI, UNI, USDC, USDT, WBTC, WETH9_EXTENDED } from '../../constants/tokens'
import { useActiveWeb3React } from '../../hooks/web3'
import { NEVER_RELOAD, useMultipleContractSingleData } from '../multicall/hooks'
import { tryParseAmount } from '../swap/hooks'
@ -25,19 +25,19 @@ export const STAKING_REWARDS_INFO: {
} = {
[1]: [
{
tokens: [WETH9[1], DAI],
tokens: [WETH9_EXTENDED[1], DAI],
stakingRewardAddress: '0xa1484C3aa22a66C62b77E0AE78E15258bd0cB711',
},
{
tokens: [WETH9[1], USDC],
tokens: [WETH9_EXTENDED[1], USDC],
stakingRewardAddress: '0x7FBa4B8Dc5E7616e59622806932DBea72537A56b',
},
{
tokens: [WETH9[1], USDT],
tokens: [WETH9_EXTENDED[1], USDT],
stakingRewardAddress: '0x6C3e4cb2E96B01F4b866965A91ed4437839A121a',
},
{
tokens: [WETH9[1], WBTC],
tokens: [WETH9_EXTENDED[1], WBTC],
stakingRewardAddress: '0xCA35e32e7926b96A9988f61d510E038108d8068e',
},
],

@ -1,6 +1,8 @@
import { useEffect, useMemo } from 'react'
import { useCallback, useEffect, useMemo } from 'react'
import { useAppDispatch, useAppSelector } from 'state/hooks'
import { SupportedChainId } from '../../constants/chains'
import { useActiveWeb3React } from '../../hooks/web3'
import { retry, RetryableError, RetryOptions } from '../../utils/retry'
import { updateBlockNumber } from '../application/actions'
import { useAddPopup, useBlockNumber } from '../application/hooks'
import { checkedTransaction, finalizeTransaction } from './actions'
@ -29,6 +31,12 @@ export function shouldCheck(lastBlockNumber: number, tx: TxInterface): boolean {
}
}
const RETRY_OPTIONS_BY_CHAIN_ID: { [chainId: number]: RetryOptions } = {
[SupportedChainId.ARBITRUM_ONE]: { n: 10, minWait: 250, maxWait: 1000 },
[SupportedChainId.ARBITRUM_KOVAN]: { n: 10, minWait: 250, maxWait: 1000 },
}
const DEFAULT_RETRY_OPTIONS: RetryOptions = { n: 3, minWait: 1000, maxWait: 3000 }
export default function Updater(): null {
const { chainId, library } = useActiveWeb3React()
@ -42,14 +50,33 @@ export default function Updater(): null {
// show popup on confirm
const addPopup = useAddPopup()
const getReceipt = useCallback(
(hash: string) => {
if (!library || !chainId) throw new Error('No library or chainId')
const retryOptions = RETRY_OPTIONS_BY_CHAIN_ID[chainId] ?? DEFAULT_RETRY_OPTIONS
return retry(
() =>
library.getTransactionReceipt(hash).then((receipt) => {
if (receipt === null) {
console.debug('Retrying for hash', hash)
throw new RetryableError()
}
return receipt
}),
retryOptions
)
},
[chainId, library]
)
useEffect(() => {
if (!chainId || !library || !lastBlockNumber) return
Object.keys(transactions)
const cancels = Object.keys(transactions)
.filter((hash) => shouldCheck(lastBlockNumber, transactions[hash]))
.forEach((hash) => {
library
.getTransactionReceipt(hash)
.map((hash) => {
const { promise, cancel } = getReceipt(hash)
promise
.then((receipt) => {
if (receipt) {
dispatch(
@ -89,10 +116,17 @@ export default function Updater(): null {
}
})
.catch((error) => {
console.error(`failed to check transaction hash: ${hash}`, error)
if (!error.isCancelledError) {
console.error(`Failed to check transaction hash: ${hash}`, error)
}
})
return cancel
})
}, [chainId, library, transactions, lastBlockNumber, dispatch, addPopup])
return () => {
cancels.forEach((cancel) => cancel())
}
}, [chainId, library, transactions, lastBlockNumber, dispatch, addPopup, getReceipt])
return null
}

@ -1,9 +1,10 @@
import { Percent, Token } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import { computePairAddress, Pair } from '@uniswap/v2-sdk'
import JSBI from 'jsbi'
import flatMap from 'lodash.flatmap'
import { useCallback, useMemo } from 'react'
import { shallowEqual } from 'react-redux'
import { V2_FACTORY_ADDRESSES } from '../../constants/addresses'
import { BASES_TO_TRACK_LIQUIDITY_FOR, PINNED_PAIRS } from '../../constants/routing'
import { useActiveWeb3React } from '../../hooks/web3'
@ -260,7 +261,17 @@ export function useURLWarningToggle(): () => void {
* @param tokenB the other token
*/
export function toV2LiquidityToken([tokenA, tokenB]: [Token, Token]): Token {
return new Token(tokenA.chainId, Pair.getAddress(tokenA, tokenB), 18, 'UNI-V2', 'Uniswap V2')
if (tokenA.chainId !== tokenB.chainId) throw new Error('Not matching chain IDs')
if (tokenA.equals(tokenB)) throw new Error('Tokens cannot be equal')
if (!V2_FACTORY_ADDRESSES[tokenA.chainId]) throw new Error('No V2 factory address on this chain')
return new Token(
tokenA.chainId,
computePairAddress({ factoryAddress: V2_FACTORY_ADDRESSES[tokenA.chainId], tokenA, tokenB }),
18,
'UNI-V2',
'Uniswap V2'
)
}
/**

@ -1,9 +1,23 @@
export function constructSameAddressMap<T extends string>(address: T): { [chainId: number]: T } {
import { SupportedChainId } from '../constants/chains'
export function constructSameAddressMap<T extends string>(
address: T,
includeArbitrum: boolean
): { [chainId: number]: T } {
if (includeArbitrum)
return {
[SupportedChainId.MAINNET]: address,
[SupportedChainId.ROPSTEN]: address,
[SupportedChainId.RINKEBY]: address,
[SupportedChainId.GOERLI]: address,
[SupportedChainId.KOVAN]: address,
[SupportedChainId.ARBITRUM_ONE]: address,
}
return {
[1]: address,
[3]: address,
[42]: address,
[4]: address,
[5]: address,
[SupportedChainId.MAINNET]: address,
[SupportedChainId.ROPSTEN]: address,
[SupportedChainId.RINKEBY]: address,
[SupportedChainId.GOERLI]: address,
[SupportedChainId.KOVAN]: address,
}
}

@ -1,9 +1,11 @@
import { SupportedChainId } from '../constants/chains'
const ETHERSCAN_PREFIXES: { [chainId: number]: string } = {
1: '',
3: 'ropsten.',
4: 'rinkeby.',
5: 'goerli.',
42: 'kovan.',
[SupportedChainId.MAINNET]: '',
[SupportedChainId.ROPSTEN]: 'ropsten.',
[SupportedChainId.RINKEBY]: 'rinkeby.',
[SupportedChainId.GOERLI]: 'goerli.',
[SupportedChainId.KOVAN]: 'kovan.',
}
export enum ExplorerDataType {
@ -20,21 +22,47 @@ export enum ExplorerDataType {
* @param type the type of the data
*/
export function getExplorerLink(chainId: number, data: string, type: ExplorerDataType): string {
if (chainId === SupportedChainId.ARBITRUM_KOVAN) {
switch (type) {
case ExplorerDataType.TRANSACTION:
return `https://explorer5.arbitrum.io/#/tx/${data}`
case ExplorerDataType.ADDRESS:
return `https://explorer5.arbitrum.io/#/address/${data}`
case ExplorerDataType.BLOCK:
return `https://explorer5.arbitrum.io/#/block/${data}`
default:
return `https://explorer5.arbitrum.io`
}
}
if (chainId === SupportedChainId.ARBITRUM_ONE) {
switch (type) {
case ExplorerDataType.TRANSACTION:
return `https://mainnet-arb-explorer.netlify.app/tx/${data}`
case ExplorerDataType.ADDRESS:
return `https://mainnet-arb-explorer.netlify.app/address/${data}`
case ExplorerDataType.BLOCK:
return `https://mainnet-arb-explorer.netlify.app/block/${data}`
default:
return `https://mainnet-arb-explorer.netlify.app`
}
}
const prefix = `https://${ETHERSCAN_PREFIXES[chainId] ?? ''}etherscan.io`
switch (type) {
case ExplorerDataType.TRANSACTION: {
case ExplorerDataType.TRANSACTION:
return `${prefix}/tx/${data}`
}
case ExplorerDataType.TOKEN: {
case ExplorerDataType.TOKEN:
return `${prefix}/token/${data}`
}
case ExplorerDataType.BLOCK: {
case ExplorerDataType.BLOCK:
return `${prefix}/block/${data}`
}
case ExplorerDataType.ADDRESS:
default: {
return `${prefix}/address/${data}`
}
default:
return `${prefix}`
}
}

@ -9,6 +9,7 @@ export default function getLibrary(provider: any): Web3Provider {
? parseInt(provider.chainId)
: 'any'
)
library.pollingInterval = 15000
// TODO: this should depend on the network block time
library.pollingInterval = 1000
return library
}

@ -1,7 +1,7 @@
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import JSBI from 'jsbi'
import { MIN_ETH } from '../constants/misc'
const MIN_NATIVE_CURRENCY_FOR_GAS: JSBI = JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(16)) // .01 ETH
/**
* Given some token amount, return the max that can be spent of it
* @param currencyAmount to return max of
@ -9,8 +9,11 @@ import { MIN_ETH } from '../constants/misc'
export function maxAmountSpend(currencyAmount?: CurrencyAmount<Currency>): CurrencyAmount<Currency> | undefined {
if (!currencyAmount) return undefined
if (currencyAmount.currency.isNative) {
if (JSBI.greaterThan(currencyAmount.quotient, MIN_ETH)) {
return CurrencyAmount.fromRawAmount(currencyAmount.currency, JSBI.subtract(currencyAmount.quotient, MIN_ETH))
if (JSBI.greaterThan(currencyAmount.quotient, MIN_NATIVE_CURRENCY_FOR_GAS)) {
return CurrencyAmount.fromRawAmount(
currencyAmount.currency,
JSBI.subtract(currencyAmount.quotient, MIN_NATIVE_CURRENCY_FOR_GAS)
)
} else {
return CurrencyAmount.fromRawAmount(currencyAmount.currency, JSBI.BigInt(0))
}

@ -23,6 +23,12 @@ export class RetryableError extends Error {
public isRetryableError: true = true
}
export interface RetryOptions {
n: number
minWait: number
maxWait: number
}
/**
* Retries the function that returns the promise until the promise successfully resolves up to n retries
* @param fn function to retry
@ -32,7 +38,7 @@ export class RetryableError extends Error {
*/
export function retry<T>(
fn: () => Promise<T>,
{ n, minWait, maxWait }: { n: number; minWait: number; maxWait: number }
{ n, minWait, maxWait }: RetryOptions
): { promise: Promise<T>; cancel: () => void } {
let completed = false
let rejectCancelled: (error: Error) => void

@ -1,10 +1,11 @@
const SUPPORTED_CHAIN_IDS = [1, 3, 4, 5, 42]
import { SupportedChainId } from '../constants/chains'
/**
* Returns the input chain ID if chain is supported. If not, return undefined
* @param chainId a chain ID, which will be returned if it is a supported chain ID
*/
export function supportedChainId(chainId: number): number | undefined {
if (SUPPORTED_CHAIN_IDS.includes(chainId)) {
if (chainId in SupportedChainId) {
return chainId
}
return undefined

@ -1,9 +1,11 @@
import { Currency, WETH9, Ether } from '@uniswap/sdk-core'
import { Currency } from '@uniswap/sdk-core'
import { ExtendedEther, WETH9_EXTENDED } from '../constants/tokens'
import { supportedChainId } from './supportedChainId'
export function unwrappedToken(currency: Currency): Currency {
if (currency.isNative) return currency
const formattedChainId = supportedChainId(currency.chainId)
if (formattedChainId && currency.equals(WETH9[formattedChainId])) return Ether.onChain(currency.chainId)
if (formattedChainId && currency.equals(WETH9_EXTENDED[formattedChainId]))
return ExtendedEther.onChain(currency.chainId)
return currency
}