Commit eb06aef1 authored by Jesse's avatar Jesse Committed by GitHub

feat: add support for Celo (#3915)

* feat: Support for Celo

* fix: wrong condition

* combine celo and alfajores lists

* use celo erc20 representation

* fix: refactor infura.ts to networks.ts & add celo to rpc urls

* feature: add celo contract addresses
fix: remove celo from supported gas estimate chains until feature is available

* refactor: useUSDCPrice to useStablecoinPrice
fix: add celo to supported gas estimate chains

* fix: use unique factory address for getting pool address

* fix: darkmode background graident

* fix: removing a comment left behind

* fix: remove bad import

* fix: remove dead link until the Celo is live on info.uniswap.org

* fix: add asset to common bases & minor refactoring

* fix: celo info links point to root info.uniswap.org

* fix: change celo token bridge to portal

* fix: update redux-multicall to latest version

* refactor: for code readability

* fix: celo banner colors & remove unused alternative logo

* fix: change celo token list to hosted version

* fix: update celo banner colors

* fix: move celo to the bottom of the network selector list

* fix: dedup dependencies @uniswap/router-sdk @uniswap/v3-sdk

* fix: refactoring + move Celo above L2s

* fix: update celo contract addresses

* fix: update celo subgraph

* fix: update v3-sdk and smart-order-router versions

* fix: move Celo to the bottom of the network selector list

* fix: downgrade smart-order-router and add casting fix

* fix: downgrade smart-order-router and add casting fix

* fix: resolve Pool dependency

* fix: bridge chain id types

* fix: explorer link test

* fix: use quoter v2 ABI in useClientSideV3Trade fro Celo

* fix: update connection "infura_rpc" to networks

* fix: revert yarn.lock and force install

* fix: dedup router and v3 sdk

* refactor: mv quoter v2 to client side v3 trade

* build: dedup lockfile

* feature: add portal ether to common bases

* fix: add comment for chains that use QuoterV2

* fix: use token as native asset

* fix: supply correct factory address to getPoolAddress call & refactor nativeOnChain method

* feature: adjust celo tokens presetned

* fix: update celo explorer to celoscan

* fix: celo token casting

* fix: celo celo explorer it

* fix: celo chain info should be consistent with block explorer used.
Co-authored-by: default avatarZach Pomerantz <zzmp@uniswap.org>
parent 1b91e7ce
<svg id="Celo_Rings" data-name="Celo Rings" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 950 950"><defs><style>.cls-1{fill:#fbcc5c;}.cls-2{fill:#35d07f;}.cls-3{fill:#5ea33b;}</style></defs><title>Artboard 1</title><path id="Bottom_Ring" data-name="Bottom Ring" class="cls-1" d="M375,850c151.88,0,275-123.12,275-275S526.88,300,375,300,100,423.12,100,575,223.12,850,375,850Zm0,100C167.9,950,0,782.1,0,575S167.9,200,375,200,750,367.9,750,575,582.1,950,375,950Z"/><path id="Top_Ring" data-name="Top Ring" class="cls-2" d="M575,650c151.88,0,275-123.12,275-275S726.88,100,575,100,300,223.12,300,375,423.12,650,575,650Zm0,100c-207.1,0-375-167.9-375-375S367.9,0,575,0,950,167.9,950,375,782.1,750,575,750Z"/><path id="Rings_Overlap" data-name="Rings Overlap" class="cls-3" d="M587.39,750a274.38,274.38,0,0,0,54.55-108.06A274.36,274.36,0,0,0,750,587.4a373.63,373.63,0,0,1-29.16,133.45A373.62,373.62,0,0,1,587.39,750ZM308.06,308.06A274.36,274.36,0,0,0,200,362.6a373.63,373.63,0,0,1,29.16-133.45A373.62,373.62,0,0,1,362.61,200,274.38,274.38,0,0,0,308.06,308.06Z"/></svg>
\ No newline at end of file
......@@ -10,7 +10,13 @@ export const FEE_AMOUNT_DETAIL: Record<
[FeeAmount.LOWEST]: {
label: '0.01',
description: <Trans>Best for very stable pairs.</Trans>,
supportedChains: [SupportedChainId.MAINNET, SupportedChainId.POLYGON, SupportedChainId.POLYGON_MUMBAI],
supportedChains: [
SupportedChainId.MAINNET,
SupportedChainId.POLYGON,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.CELO,
SupportedChainId.CELO_ALFAJORES,
],
},
[FeeAmount.LOW]: {
label: '0.05',
......
......@@ -157,6 +157,9 @@ const BridgeLabel = ({ chainId }: { chainId: SupportedChainId }) => {
case SupportedChainId.POLYGON:
case SupportedChainId.POLYGON_MUMBAI:
return <Trans>Polygon Bridge</Trans>
case SupportedChainId.CELO:
case SupportedChainId.CELO_ALFAJORES:
return <Trans>Portal Bridge</Trans>
default:
return <Trans>Bridge</Trans>
}
......@@ -172,6 +175,9 @@ const ExplorerLabel = ({ chainId }: { chainId: SupportedChainId }) => {
case SupportedChainId.POLYGON:
case SupportedChainId.POLYGON_MUMBAI:
return <Trans>Polygonscan</Trans>
case SupportedChainId.CELO:
case SupportedChainId.CELO_ALFAJORES:
return <Trans>Blockscout</Trans>
default:
return <Trans>Etherscan</Trans>
}
......@@ -262,6 +268,7 @@ const NETWORK_SELECTOR_CHAINS = [
SupportedChainId.POLYGON,
SupportedChainId.OPTIMISM,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.CELO,
]
export default function NetworkSelector() {
......
......@@ -42,6 +42,8 @@ const SHOULD_SHOW_ALERT = {
[SupportedChainId.ARBITRUM_RINKEBY]: true,
[SupportedChainId.POLYGON]: true,
[SupportedChainId.POLYGON_MUMBAI]: true,
[SupportedChainId.CELO]: true,
[SupportedChainId.CELO_ALFAJORES]: true,
}
type NetworkAlertChains = keyof typeof SHOULD_SHOW_ALERT
......@@ -54,6 +56,10 @@ const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: {
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.1) 0%, rgba(82, 32, 166, 0.1) 100%)',
[SupportedChainId.POLYGON_MUMBAI]:
'radial-gradient(100% 93.36% at 0% 6.64%, rgba(160, 108, 247, 0.1) 0%, rgba(82, 32, 166, 0.1) 100%)',
[SupportedChainId.CELO]:
'radial-gradient(182.71% 150.59% at 2.81% 7.69%, rgba(90, 190, 170, 0.15) 0%, rgba(80, 160, 40, 0.15) 100%)',
[SupportedChainId.CELO_ALFAJORES]:
'radial-gradient(182.71% 150.59% at 2.81% 7.69%, rgba(90, 190, 170, 0.15) 0%, rgba(80, 160, 40, 0.15) 100%)',
[SupportedChainId.OPTIMISM]:
'radial-gradient(948% 292% at 42% 0%, rgba(255, 58, 212, 0.01) 0%, rgba(255, 255, 255, 0.04) 100%),radial-gradient(98% 96% at 2% 0%, rgba(255, 39, 39, 0.01) 0%, rgba(235, 0, 255, 0.01) 96%)',
[SupportedChainId.OPTIMISTIC_KOVAN]:
......@@ -68,6 +74,10 @@ const BG_COLORS_BY_DARK_MODE_AND_CHAIN_ID: {
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.2) 0%, rgba(167, 202, 255, 0.2) 100%)',
[SupportedChainId.POLYGON_MUMBAI]:
'radial-gradient(182.71% 205.59% at 2.81% 7.69%, rgba(130, 71, 229, 0.2) 0%, rgba(167, 202, 255, 0.2) 100%)',
[SupportedChainId.CELO]:
'radial-gradient(182.71% 150.59% at 2.81% 7.69%, rgba(63, 208, 137, 0.15) 0%, rgba(49, 205, 50, 0.15) 100%)',
[SupportedChainId.CELO_ALFAJORES]:
'radial-gradient(182.71% 150.59% at 2.81% 7.69%, rgba(63, 208, 137, 0.15) 0%, rgba(49, 205, 50, 0.15) 100%)',
[SupportedChainId.OPTIMISM]:
'radial-gradient(92% 105% at 50% 7%, rgba(255, 58, 212, 0.04) 0%, rgba(255, 255, 255, 0.03) 100%),radial-gradient(100% 97% at 0% 12%, rgba(235, 0, 255, 0.1) 0%, rgba(243, 19, 19, 0.1) 100%), hsla(0, 0%, 100%, 0.1)',
[SupportedChainId.OPTIMISTIC_KOVAN]:
......@@ -129,6 +139,8 @@ const StyledArrowUpRight = styled(ArrowUpRight)`
const TEXT_COLORS: { [chainId in NetworkAlertChains]: string } = {
[SupportedChainId.POLYGON]: 'rgba(130, 71, 229)',
[SupportedChainId.POLYGON_MUMBAI]: 'rgba(130, 71, 229)',
[SupportedChainId.CELO]: 'rgba(53, 178, 97)',
[SupportedChainId.CELO_ALFAJORES]: 'rgba(53, 178, 97)',
[SupportedChainId.OPTIMISM]: '#ff3856',
[SupportedChainId.OPTIMISTIC_KOVAN]: '#ff3856',
[SupportedChainId.ARBITRUM_ONE]: '#0490ed',
......
......@@ -116,11 +116,15 @@ export function CurrencySearch({
const native = useNativeCurrency()
const filteredSortedTokensWithETH: Currency[] = useMemo(() => {
if (!native) return filteredSortedTokens
// Use Celo ERC20 Implementation and exclude the native asset
if (!native) {
return filteredSortedTokens
}
const s = debouncedQuery.toLowerCase().trim()
if (native.symbol?.toLowerCase()?.indexOf(s) !== -1) {
return native ? [native, ...filteredSortedTokens] : filteredSortedTokens
// Always bump the native token to the top of the list.
return native ? [native, ...filteredSortedTokens.filter((t) => !t.equals(native))] : filteredSortedTokens
}
return filteredSortedTokens
}, [debouncedQuery, native, filteredSortedTokens])
......
......@@ -3,7 +3,7 @@ import { t, Trans } from '@lingui/macro'
import { Percent } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { sendEvent } from 'components/analytics'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import { isSupportedChainId } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import { useContext, useRef, useState } from 'react'
import { Settings, X } from 'react-feather'
import { Text } from 'rebass'
......@@ -199,7 +199,7 @@ export default function SettingsTab({ placeholderSlippage }: { placeholderSlippa
<Text fontWeight={600} fontSize={14}>
<Trans>Interface Settings</Trans>
</Text>
{chainId && AUTO_ROUTER_SUPPORTED_CHAINS.includes(chainId) && (
{isSupportedChainId(chainId) && (
<RowBetween>
<RowFixed>
<ThemedText.Black fontWeight={400} fontSize={14} color={theme.text2}>
......
......@@ -5,8 +5,8 @@ import styled from 'styled-components/macro'
import { BIG_INT_SECONDS_IN_WEEK } from '../../constants/misc'
import { useColor } from '../../hooks/useColor'
import useStablecoinPrice from '../../hooks/useStablecoinPrice'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import useUSDCPrice from '../../hooks/useUSDCPrice'
import { useV2Pair } from '../../hooks/useV2Pairs'
import { StakingInfo } from '../../state/stake/hooks'
import { StyledInternalLink, ThemedText } from '../../theme'
......@@ -104,7 +104,7 @@ export default function PoolCard({ stakingInfo }: { stakingInfo: StakingInfo })
}
// get the USD value of staked WETH
const USDPrice = useUSDCPrice(WETH)
const USDPrice = useStablecoinPrice(WETH)
const valueOfTotalStakedAmountInUSDC =
valueOfTotalStakedAmountInWETH && USDPrice?.quote(valueOfTotalStakedAmountInWETH)
......
......@@ -6,7 +6,7 @@ import { Text } from 'rebass'
import { InterfaceTrade } from 'state/routing/types'
import styled, { ThemeContext } from 'styled-components/macro'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import { useUSDCValue } from '../../hooks/useStablecoinPrice'
import { ThemedText } from '../../theme'
import { isAddress, shortenAddress } from '../../utils'
import { computeFiatValuePriceImpact } from '../../utils/computeFiatValuePriceImpact'
......
import { Trans } from '@lingui/macro'
import { Currency, Price } from '@uniswap/sdk-core'
import useUSDCPrice from 'hooks/useUSDCPrice'
import useStablecoinPrice from 'hooks/useStablecoinPrice'
import { useCallback, useContext } from 'react'
import { Text } from 'rebass'
import styled, { ThemeContext } from 'styled-components/macro'
......@@ -32,7 +32,7 @@ const StyledPriceContainer = styled.button`
export default function TradePrice({ price, showInverted, setShowInverted }: TradePriceProps) {
const theme = useContext(ThemeContext)
const usdcPrice = useUSDCPrice(showInverted ? price.baseCurrency : price.quoteCurrency)
const usdcPrice = useStablecoinPrice(showInverted ? price.baseCurrency : price.quoteCurrency)
/*
* calculate needed amount of decimal prices, for prices between 0.95-1.05 use 4 decimal places
*/
......
......@@ -7,10 +7,10 @@ import { Network } from '@web3-react/network'
import { Connector } from '@web3-react/types'
import { WalletConnect } from '@web3-react/walletconnect'
import { SupportedChainId } from 'constants/chains'
import { INFURA_NETWORK_URLS } from 'constants/infura'
import Fortmatic from 'fortmatic'
import UNISWAP_LOGO_URL from '../assets/svg/logo.svg'
import { RPC_URLS } from '../constants/networks'
export enum ConnectionType {
INJECTED = 'INJECTED',
......@@ -32,7 +32,7 @@ function onError(error: Error) {
}
const [web3Network, web3NetworkHooks] = initializeConnector<Network>(
(actions) => new Network({ actions, urlMap: INFURA_NETWORK_URLS, defaultChainId: 1 })
(actions) => new Network({ actions, urlMap: RPC_URLS, defaultChainId: 1 })
)
export const networkConnection: Connection = {
connector: web3Network,
......@@ -59,7 +59,7 @@ const [web3WalletConnect, web3WalletConnectHooks] = initializeConnector<WalletCo
new WalletConnect({
actions,
options: {
rpc: INFURA_NETWORK_URLS,
rpc: RPC_URLS,
qrcode: true,
},
onError,
......@@ -85,7 +85,7 @@ const [web3CoinbaseWallet, web3CoinbaseWalletHooks] = initializeConnector<Coinba
new CoinbaseWallet({
actions,
options: {
url: INFURA_NETWORK_URLS[SupportedChainId.MAINNET],
url: RPC_URLS[SupportedChainId.MAINNET],
appName: 'Uniswap',
appLogoUrl: UNISWAP_LOGO_URL,
reloadOnDisconnect: false,
......
......@@ -7,35 +7,82 @@ import { SupportedChainId } from './chains'
type AddressMap = { [chainId: number]: string }
export const UNI_ADDRESS: AddressMap = constructSameAddressMap('0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984')
export const MULTICALL_ADDRESS: AddressMap = {
...constructSameAddressMap('0x1F98415757620B543A52E61c46B32eB19261F984', [
SupportedChainId.OPTIMISTIC_KOVAN,
export const V2_FACTORY_ADDRESSES: AddressMap = constructSameAddressMap(V2_FACTORY_ADDRESS)
export const V2_ROUTER_ADDRESS: AddressMap = constructSameAddressMap('0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D')
// celo v3 addresses
const CELO_V3_CORE_FACTORY_ADDRESSES = '0xAfE208a311B21f13EF87E33A90049fC17A7acDEc'
const CELO_V3_ROUTER_ADDRESS = '0x5615CDAb10dc425a742d643d949a7F474C01abc4'
const CELO_V3_MIGRATOR_ADDRESSES = '0x3cFd4d48EDfDCC53D3f173F596f621064614C582'
const CELO_MULTICALL_ADDRESS = '0x633987602DE5C4F337e3DbF265303A1080324204'
const CELO_QUOTER_ADDRESSES = '0x82825d0554fA07f7FC52Ab63c961F330fdEFa8E8'
const CELO_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES = '0x3d79EdAaBC0EaB6F08ED885C05Fc0B014290D95A'
const CELO_TICK_LENS_ADDRESSES = '0x5f115D9113F88e0a0Db1b5033D90D4a9690AcD3D'
/* V3 Contract Addresses */
export const V3_CORE_FACTORY_ADDRESSES: AddressMap = {
...constructSameAddressMap(V3_FACTORY_ADDRESS, [
SupportedChainId.OPTIMISM,
SupportedChainId.OPTIMISTIC_KOVAN,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON,
]),
[SupportedChainId.ARBITRUM_ONE]: '0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB',
[SupportedChainId.ARBITRUM_RINKEBY]: '0xa501c031958F579dB7676fF1CE78AD305794d579',
[SupportedChainId.CELO]: CELO_V3_CORE_FACTORY_ADDRESSES,
[SupportedChainId.CELO_ALFAJORES]: CELO_V3_CORE_FACTORY_ADDRESSES,
}
export const V2_FACTORY_ADDRESSES: AddressMap = constructSameAddressMap(V2_FACTORY_ADDRESS)
export const V2_ROUTER_ADDRESS: AddressMap = constructSameAddressMap('0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D')
export const V3_ROUTER_ADDRESS: AddressMap = constructSameAddressMap('0xE592427A0AEce92De3Edee1F18E0157C05861564', [
export const V3_ROUTER_ADDRESS: AddressMap = {
...constructSameAddressMap('0xE592427A0AEce92De3Edee1F18E0157C05861564', [
SupportedChainId.OPTIMISM,
SupportedChainId.OPTIMISTIC_KOVAN,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.POLYGON,
SupportedChainId.POLYGON_MUMBAI,
])
export const SWAP_ROUTER_ADDRESSES: AddressMap = constructSameAddressMap('0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45', [
]),
[SupportedChainId.CELO]: CELO_V3_ROUTER_ADDRESS,
[SupportedChainId.CELO_ALFAJORES]: CELO_V3_ROUTER_ADDRESS,
}
export const V3_MIGRATOR_ADDRESSES: AddressMap = {
...constructSameAddressMap('0xA5644E29708357803b5A882D272c41cC0dF92B34', [
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON,
]),
[SupportedChainId.CELO]: CELO_V3_MIGRATOR_ADDRESSES,
[SupportedChainId.CELO_ALFAJORES]: CELO_V3_MIGRATOR_ADDRESSES,
}
export const MULTICALL_ADDRESS: AddressMap = {
...constructSameAddressMap('0x1F98415757620B543A52E61c46B32eB19261F984', [
SupportedChainId.OPTIMISTIC_KOVAN,
SupportedChainId.OPTIMISM,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON,
]),
[SupportedChainId.ARBITRUM_ONE]: '0xadF885960B47eA2CD9B55E6DAc6B42b7Cb2806dB',
[SupportedChainId.ARBITRUM_RINKEBY]: '0xa501c031958F579dB7676fF1CE78AD305794d579',
[SupportedChainId.CELO]: CELO_MULTICALL_ADDRESS,
[SupportedChainId.CELO_ALFAJORES]: CELO_MULTICALL_ADDRESS,
}
export const SWAP_ROUTER_ADDRESSES: AddressMap = {
...constructSameAddressMap('0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45', [
SupportedChainId.OPTIMISM,
SupportedChainId.OPTIMISTIC_KOVAN,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.POLYGON,
SupportedChainId.POLYGON_MUMBAI,
])
]),
[SupportedChainId.CELO]: CELO_V3_ROUTER_ADDRESS,
[SupportedChainId.CELO_ALFAJORES]: CELO_V3_ROUTER_ADDRESS,
}
/**
* The oldest V0 governance address
......@@ -61,54 +108,51 @@ export const TIMELOCK_ADDRESS: AddressMap = constructSameAddressMap('0x1a9C8182C
export const MERKLE_DISTRIBUTOR_ADDRESS: AddressMap = {
[SupportedChainId.MAINNET]: '0x090D4613473dEE047c3f2706764f49E0821D256e',
}
export const ARGENT_WALLET_DETECTOR_ADDRESS: AddressMap = {
[SupportedChainId.MAINNET]: '0xeca4B0bDBf7c55E9b7925919d03CbF8Dc82537E8',
}
export const V3_CORE_FACTORY_ADDRESSES: AddressMap = constructSameAddressMap(V3_FACTORY_ADDRESS, [
SupportedChainId.OPTIMISM,
SupportedChainId.OPTIMISTIC_KOVAN,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON,
])
export const QUOTER_ADDRESSES: AddressMap = constructSameAddressMap('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6', [
export const QUOTER_ADDRESSES: AddressMap = {
...constructSameAddressMap('0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6', [
SupportedChainId.OPTIMISM,
SupportedChainId.OPTIMISTIC_KOVAN,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON,
])
export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES: AddressMap = constructSameAddressMap(
'0xC36442b4a4522E871399CD717aBDD847Ab11FE88',
[
]),
[SupportedChainId.CELO]: CELO_QUOTER_ADDRESSES,
[SupportedChainId.CELO_ALFAJORES]: CELO_QUOTER_ADDRESSES,
}
export const NONFUNGIBLE_POSITION_MANAGER_ADDRESSES: AddressMap = {
...constructSameAddressMap('0xC36442b4a4522E871399CD717aBDD847Ab11FE88', [
SupportedChainId.OPTIMISM,
SupportedChainId.OPTIMISTIC_KOVAN,
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON,
]
)
]),
[SupportedChainId.CELO]: CELO_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
[SupportedChainId.CELO_ALFAJORES]: CELO_NONFUNGIBLE_POSITION_MANAGER_ADDRESSES,
}
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 V3_MIGRATOR_ADDRESSES: AddressMap = constructSameAddressMap('0xA5644E29708357803b5A882D272c41cC0dF92B34', [
SupportedChainId.ARBITRUM_ONE,
SupportedChainId.ARBITRUM_RINKEBY,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.POLYGON,
])
export const TICK_LENS_ADDRESSES: AddressMap = {
[SupportedChainId.ARBITRUM_ONE]: '0xbfd8137f7d1516D3ea5cA83523914859ec47F573',
[SupportedChainId.ARBITRUM_RINKEBY]: '0xbfd8137f7d1516D3ea5cA83523914859ec47F573',
[SupportedChainId.CELO]: CELO_TICK_LENS_ADDRESSES,
[SupportedChainId.CELO_ALFAJORES]: CELO_TICK_LENS_ADDRESSES,
}
import ethereumLogoUrl from 'assets/images/ethereum-logo.png'
import arbitrumLogoUrl from 'assets/svg/arbitrum_logo.svg'
import celoLogo from 'assets/svg/celo_logo.svg'
import optimismLogoUrl from 'assets/svg/optimistic_ethereum.svg'
import polygonMaticLogo from 'assets/svg/polygon-matic-logo.svg'
import ms from 'ms.macro'
import { SupportedChainId, SupportedL1ChainId, SupportedL2ChainId } from './chains'
import { ARBITRUM_LIST, OPTIMISM_LIST } from './lists'
import { ARBITRUM_LIST, CELO_LIST, OPTIMISM_LIST } from './lists'
export enum NetworkType {
L1,
......@@ -31,6 +32,7 @@ interface BaseChainInfo {
export interface L1ChainInfo extends BaseChainInfo {
readonly networkType: NetworkType.L1
readonly defaultListUrl?: string
}
export interface L2ChainInfo extends BaseChainInfo {
......@@ -167,4 +169,28 @@ export const CHAIN_INFO: ChainInfoMap = {
logoUrl: polygonMaticLogo,
nativeCurrency: { name: 'Polygon Mumbai Matic', symbol: 'mMATIC', decimals: 18 },
},
[SupportedChainId.CELO]: {
networkType: NetworkType.L1,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://www.portalbridge.com/#/transfer',
docs: 'https://docs.celo.org/',
explorer: 'https://celoscan.io/',
infoLink: 'https://info.uniswap.org/#/celo',
label: 'Celo',
logoUrl: celoLogo,
nativeCurrency: { name: 'Celo', symbol: 'CELO', decimals: 18 },
defaultListUrl: CELO_LIST,
},
[SupportedChainId.CELO_ALFAJORES]: {
networkType: NetworkType.L1,
blockWaitMsBeforeWarning: ms`10m`,
bridge: 'https://www.portalbridge.com/#/transfer',
docs: 'https://docs.celo.org/',
explorer: 'https://alfajores-blockscout.celo-testnet.org/',
infoLink: 'https://info.uniswap.org/#/celo',
label: 'Celo Alfajores',
logoUrl: celoLogo,
nativeCurrency: { name: 'Celo', symbol: 'CELO', decimals: 18 },
defaultListUrl: CELO_LIST,
},
}
......@@ -16,6 +16,9 @@ export enum SupportedChainId {
POLYGON = 137,
POLYGON_MUMBAI = 80001,
CELO = 42220,
CELO_ALFAJORES = 44787,
}
export const CHAIN_IDS_TO_NAMES = {
......@@ -26,6 +29,8 @@ export const CHAIN_IDS_TO_NAMES = {
[SupportedChainId.KOVAN]: 'kovan',
[SupportedChainId.POLYGON]: 'polygon',
[SupportedChainId.POLYGON_MUMBAI]: 'polygon_mumbai',
[SupportedChainId.CELO]: 'celo',
[SupportedChainId.CELO_ALFAJORES]: 'celo_alfajores',
[SupportedChainId.ARBITRUM_ONE]: 'arbitrum',
[SupportedChainId.ARBITRUM_RINKEBY]: 'arbitrum_rinkeby',
[SupportedChainId.OPTIMISM]: 'optimism',
......@@ -42,6 +47,7 @@ export const ALL_SUPPORTED_CHAIN_IDS: SupportedChainId[] = Object.values(Support
export const SUPPORTED_GAS_ESTIMATE_CHAIN_IDS = [
SupportedChainId.MAINNET,
SupportedChainId.POLYGON,
SupportedChainId.CELO,
SupportedChainId.OPTIMISM,
SupportedChainId.ARBITRUM_ONE,
]
......@@ -66,6 +72,8 @@ export const L1_CHAIN_IDS = [
SupportedChainId.KOVAN,
SupportedChainId.POLYGON,
SupportedChainId.POLYGON_MUMBAI,
SupportedChainId.CELO,
SupportedChainId.CELO_ALFAJORES,
] as const
export type SupportedL1ChainId = typeof L1_CHAIN_IDS[number]
......
......@@ -5,13 +5,15 @@ const CMC_ALL_LIST = 'https://api.coinmarketcap.com/data-api/v3/uniswap/all.json
const COINGECKO_LIST = 'https://tokens.coingecko.com/uniswap/all.json'
const COMPOUND_LIST = 'https://raw.githubusercontent.com/compound-finance/token-list/master/compound.tokenlist.json'
const GEMINI_LIST = 'https://www.gemini.com/uniswap/manifest.json'
export const ARBITRUM_LIST = 'https://bridge.arbitrum.io/token-list-42161.json'
const KLEROS_LIST = 't2crtokens.eth'
export const OPTIMISM_LIST = 'https://static.optimism.io/optimism.tokenlist.json'
const ROLL_LIST = 'https://app.tryroll.com/tokens.json'
const SET_LIST = 'https://raw.githubusercontent.com/SetProtocol/uniswap-tokenlist/main/set.tokenlist.json'
const WRAPPED_LIST = 'wrapped.tokensoft.eth'
export const OPTIMISM_LIST = 'https://static.optimism.io/optimism.tokenlist.json'
export const ARBITRUM_LIST = 'https://bridge.arbitrum.io/token-list-42161.json'
export const CELO_LIST = 'https://celo-org.github.io/celo-token-list/celo.tokenlist.json'
export const UNSUPPORTED_LIST_URLS: string[] = [BA_LIST]
// this is the default list of lists that are exposed to users
......@@ -29,6 +31,7 @@ const DEFAULT_LIST_OF_LISTS_TO_DISPLAY: string[] = [
ROLL_LIST,
ARBITRUM_LIST,
OPTIMISM_LIST,
CELO_LIST,
]
export const DEFAULT_LIST_OF_LISTS: string[] = [
......
......@@ -12,7 +12,7 @@ export const MAINNET_PROVIDER = new JsonRpcProvider(`https://mainnet.infura.io/v
/**
* These are the network URLs used by the interface when there is not another available source of chain data
*/
export const INFURA_NETWORK_URLS: { [key in SupportedChainId]: string } = {
export const RPC_URLS: { [key in SupportedChainId]: string } = {
[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}`,
......@@ -24,4 +24,6 @@ export const INFURA_NETWORK_URLS: { [key in SupportedChainId]: string } = {
[SupportedChainId.ARBITRUM_RINKEBY]: `https://arbitrum-rinkeby.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON]: `https://polygon-mainnet.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.POLYGON_MUMBAI]: `https://polygon-mumbai.infura.io/v3/${INFURA_KEY}`,
[SupportedChainId.CELO]: `https://forno.celo.org`,
[SupportedChainId.CELO_ALFAJORES]: `https://alfajores-forno.celo-testnet.org`,
}
......@@ -4,6 +4,11 @@ import { Currency, Token } from '@uniswap/sdk-core'
import { SupportedChainId } from './chains'
import {
AMPL,
CEUR_CELO,
CEUR_CELO_ALFAJORES,
CMC02_CELO,
CUSD_CELO,
CUSD_CELO_ALFAJORES,
DAI,
DAI_ARBITRUM_ONE,
DAI_OPTIMISM,
......@@ -13,6 +18,8 @@ import {
FRAX,
FXS,
nativeOnChain,
PORTAL_ETH_CELO,
PORTAL_USDC_CELO,
renBTC,
rETH2,
sETH2,
......@@ -78,6 +85,7 @@ export const BASES_TO_CHECK_TRADES_AGAINST: ChainTokenList = {
USDT_POLYGON,
WETH_POLYGON,
],
[SupportedChainId.CELO]: [CUSD_CELO, CEUR_CELO, CMC02_CELO, PORTAL_USDC_CELO, PORTAL_ETH_CELO],
}
export const ADDITIONAL_BASES: { [chainId: number]: { [tokenAddress: string]: Token[] } } = {
[SupportedChainId.MAINNET]: {
......@@ -163,6 +171,20 @@ export const COMMON_BASES: ChainCurrencyList = {
WRAPPED_NATIVE_CURRENCY[SupportedChainId.POLYGON_MUMBAI] as Token,
WETH_POLYGON_MUMBAI,
],
[SupportedChainId.CELO]: [
nativeOnChain(SupportedChainId.CELO),
CEUR_CELO,
CUSD_CELO,
PORTAL_ETH_CELO,
PORTAL_USDC_CELO,
CMC02_CELO,
],
[SupportedChainId.CELO_ALFAJORES]: [
nativeOnChain(SupportedChainId.CELO_ALFAJORES),
CUSD_CELO_ALFAJORES,
CEUR_CELO_ALFAJORES,
],
}
// used to construct the list of all pairs we consider by default in the frontend
......
......@@ -81,7 +81,20 @@ export const USDC_POLYGON_MUMBAI = new Token(
'USDC',
'USD//C'
)
export const PORTAL_USDC_CELO = new Token(
SupportedChainId.CELO,
'0x37f750B7cC259A2f741AF45294f6a16572CF5cAd',
6,
'USDCet',
'USDC (Portal from Ethereum)'
)
export const USDC_CELO_ALFAJORES = new Token(
SupportedChainId.CELO_ALFAJORES,
'0x41F4a5d2632b019Ae6CE9625bE3c9CaC143AcC7D',
6,
'USDC',
'USD//C'
)
export const AMPL = new Token(
SupportedChainId.MAINNET,
'0xD46bA6D942050d489DBd938a2C909A5d5039A161',
......@@ -118,6 +131,8 @@ export const USDC: { [chainId in SupportedChainId]: Token } = {
[SupportedChainId.OPTIMISTIC_KOVAN]: USDC_OPTIMISTIC_KOVAN,
[SupportedChainId.POLYGON]: USDC_POLYGON,
[SupportedChainId.POLYGON_MUMBAI]: USDC_POLYGON_MUMBAI,
[SupportedChainId.CELO]: PORTAL_USDC_CELO,
[SupportedChainId.CELO_ALFAJORES]: USDC_CELO_ALFAJORES,
[SupportedChainId.GOERLI]: USDC_GOERLI,
[SupportedChainId.RINKEBY]: USDC_RINKEBY,
[SupportedChainId.KOVAN]: USDC_KOVAN,
......@@ -264,6 +279,63 @@ export const WETH_POLYGON = new Token(
'WETH',
'Wrapped Ether'
)
export const CELO_CELO = new Token(
SupportedChainId.CELO,
'0x471EcE3750Da237f93B8E339c536989b8978a438',
18,
'CELO',
'Celo'
)
export const CUSD_CELO = new Token(
SupportedChainId.CELO,
'0x765DE816845861e75A25fCA122bb6898B8B1282a',
18,
'cUSD',
'Celo Dollar'
)
export const CEUR_CELO = new Token(
SupportedChainId.CELO,
'0xD8763CBa276a3738E6DE85b4b3bF5FDed6D6cA73',
18,
'cEUR',
'Celo Euro Stablecoin'
)
export const PORTAL_ETH_CELO = new Token(
SupportedChainId.CELO,
'0x66803FB87aBd4aaC3cbB3fAd7C3aa01f6F3FB207',
18,
'ETH',
'Portal Ether'
)
export const CMC02_CELO = new Token(
SupportedChainId.CELO,
'0x32A9FE697a32135BFd313a6Ac28792DaE4D9979d',
18,
'cMCO2',
'Celo Moss Carbon Credit'
)
export const CELO_CELO_ALFAJORES = new Token(
SupportedChainId.CELO_ALFAJORES,
'0xF194afDf50B03e69Bd7D057c1Aa9e10c9954E4C9',
18,
'CELO',
'Celo'
)
export const CUSD_CELO_ALFAJORES = new Token(
SupportedChainId.CELO_ALFAJORES,
'0x874069Fa1Eb16D44d622F2e0Ca25eeA172369bC1',
18,
'CUSD',
'Celo Dollar'
)
export const CEUR_CELO_ALFAJORES = new Token(
SupportedChainId.CELO_ALFAJORES,
'0x10c892A6EC43a53E45D0B916B4b7D383B1b78C0F',
18,
'CEUR',
'Celo Euro Stablecoin'
)
export const UNI: { [chainId: number]: Token } = {
[SupportedChainId.MAINNET]: new Token(SupportedChainId.MAINNET, UNI_ADDRESS[1], 18, 'UNI', 'Uniswap'),
[SupportedChainId.RINKEBY]: new Token(SupportedChainId.RINKEBY, UNI_ADDRESS[4], 18, 'UNI', 'Uniswap'),
......@@ -318,6 +390,21 @@ export const WRAPPED_NATIVE_CURRENCY: { [chainId: number]: Token | undefined } =
),
}
export function isCelo(chainId: number): chainId is SupportedChainId.CELO | SupportedChainId.CELO_ALFAJORES {
return chainId === SupportedChainId.CELO_ALFAJORES || chainId === SupportedChainId.CELO
}
function getCeloNativeCurrency(chainId: number) {
switch (chainId) {
case SupportedChainId.CELO_ALFAJORES:
return CELO_CELO_ALFAJORES
case SupportedChainId.CELO:
return CELO_CELO
default:
throw new Error('Not celo')
}
}
function isMatic(chainId: number): chainId is SupportedChainId.POLYGON | SupportedChainId.POLYGON_MUMBAI {
return chainId === SupportedChainId.POLYGON_MUMBAI || chainId === SupportedChainId.POLYGON
}
......@@ -354,14 +441,18 @@ export class ExtendedEther extends Ether {
}
}
const cachedNativeCurrency: { [chainId: number]: NativeCurrency } = {}
export function nativeOnChain(chainId: number): NativeCurrency {
return (
cachedNativeCurrency[chainId] ??
(cachedNativeCurrency[chainId] = isMatic(chainId)
? new MaticNativeCurrency(chainId)
: ExtendedEther.onChain(chainId))
)
const cachedNativeCurrency: { [chainId: number]: NativeCurrency | Token } = {}
export function nativeOnChain(chainId: number): NativeCurrency | Token {
if (cachedNativeCurrency[chainId]) return cachedNativeCurrency[chainId]
let nativeCurrency: NativeCurrency | Token
if (isMatic(chainId)) {
nativeCurrency = new MaticNativeCurrency(chainId)
} else if (isCelo(chainId)) {
nativeCurrency = getCeloNativeCurrency(chainId)
} else {
nativeCurrency = ExtendedEther.onChain(chainId)
}
return (cachedNativeCurrency[chainId] = nativeCurrency)
}
export const TOKEN_SHORTHANDS: { [shorthand: string]: { [chainId in SupportedChainId]?: string } } = {
......@@ -373,6 +464,8 @@ export const TOKEN_SHORTHANDS: { [shorthand: string]: { [chainId in SupportedCha
[SupportedChainId.OPTIMISTIC_KOVAN]: USDC_OPTIMISTIC_KOVAN.address,
[SupportedChainId.POLYGON]: USDC_POLYGON.address,
[SupportedChainId.POLYGON_MUMBAI]: USDC_POLYGON_MUMBAI.address,
[SupportedChainId.CELO]: PORTAL_USDC_CELO.address,
[SupportedChainId.CELO_ALFAJORES]: PORTAL_USDC_CELO.address,
[SupportedChainId.GOERLI]: USDC_GOERLI.address,
[SupportedChainId.RINKEBY]: USDC_RINKEBY.address,
[SupportedChainId.KOVAN]: USDC_KOVAN.address,
......
import { useWeb3React } from '@web3-react/core'
import { AUTO_ROUTER_SUPPORTED_CHAINS } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import { isSupportedChainId } from 'lib/hooks/routing/clientSideSmartOrderRouter'
export default function useAutoRouterSupported(): boolean {
const { chainId } = useWeb3React()
return Boolean(chainId && AUTO_ROUTER_SUPPORTED_CHAINS.includes(chainId))
return isSupportedChainId(chainId)
}
......@@ -9,7 +9,7 @@ import { useMemo } from 'react'
import { InterfaceTrade } from 'state/routing/types'
import useGasPrice from './useGasPrice'
import useUSDCPrice, { useUSDCValue } from './useUSDCPrice'
import useStablecoinPrice, { useUSDCValue } from './useStablecoinPrice'
const V3_SWAP_DEFAULT_SLIPPAGE = new Percent(50, 10_000) // .50%
const ONE_TENTHS_PERCENT = new Percent(10, 10_000) // .10%
......@@ -42,7 +42,7 @@ export default function useAutoSlippageTolerance(
const gasEstimate = guesstimateGas(trade)
const nativeCurrency = useNativeCurrency()
const nativeCurrencyPrice = useUSDCPrice((trade && nativeCurrency) ?? undefined)
const nativeCurrencyPrice = useStablecoinPrice((trade && nativeCurrency) ?? undefined)
return useMemo(() => {
if (!trade || onL2) return DEFAULT_AUTO_SLIPPAGE
......
......@@ -8,7 +8,7 @@ import { useMemo } from 'react'
import { InterfaceTrade, TradeState } from 'state/routing/types'
import { useAllV3Routes } from './useAllV3Routes'
import { useV3Quoter } from './useContract'
import { useQuoter } from './useContract'
const QUOTE_GAS_OVERRIDES: { [chainId: number]: number } = {
[SupportedChainId.ARBITRUM_ONE]: 25_000_000,
......@@ -34,15 +34,23 @@ export function useClientSideV3Trade<TTradeType extends TradeType>(
: [otherCurrency, amountSpecified?.currency]
const { routes, loading: routesLoading } = useAllV3Routes(currencyIn, currencyOut)
const quoter = useV3Quoter()
const { chainId } = useWeb3React()
// Chains deployed using the deploy-v3 script only deploy QuoterV2.
const useQuoterV2 = useMemo(
() => Boolean(chainId && [SupportedChainId.CELO, SupportedChainId.CELO_ALFAJORES].includes(chainId)),
[chainId]
)
const quoter = useQuoter(useQuoterV2)
const callData = useMemo(
() =>
amountSpecified
? routes.map((route) => SwapQuoter.quoteCallParameters(route, amountSpecified, tradeType).calldata)
? routes.map(
(route) => SwapQuoter.quoteCallParameters(route, amountSpecified, tradeType, { useQuoterV2 }).calldata
)
: [],
[amountSpecified, routes, tradeType]
[amountSpecified, routes, tradeType, useQuoterV2]
)
const quotesResults = useSingleContractWithCallData(quoter, callData, {
gasRequired: chainId ? QUOTE_GAS_OVERRIDES[chainId] ?? DEFAULT_GAS_QUOTE : undefined,
})
......
import { Contract } from '@ethersproject/contracts'
import QuoterV2Json from '@uniswap/swap-router-contracts/artifacts/contracts/lens/QuoterV2.sol/QuoterV2.json'
import IUniswapV2PairJson from '@uniswap/v2-core/build/IUniswapV2Pair.json'
import IUniswapV2Router02Json from '@uniswap/v2-periphery/build/IUniswapV2Router02.json'
import QuoterJson from '@uniswap/v3-periphery/artifacts/contracts/lens/Quoter.sol/Quoter.json'
......@@ -29,7 +30,7 @@ import {
} from 'constants/addresses'
import { WRAPPED_NATIVE_CURRENCY } from 'constants/tokens'
import { useMemo } from 'react'
import { NonfungiblePositionManager, Quoter, TickLens, UniswapInterfaceMulticall } from 'types/v3'
import { NonfungiblePositionManager, Quoter, QuoterV2, TickLens, UniswapInterfaceMulticall } from 'types/v3'
import { V3Migrator } from 'types/v3/V3Migrator'
import { getContract } from '../utils'
......@@ -37,6 +38,7 @@ import { getContract } from '../utils'
const { abi: IUniswapV2PairABI } = IUniswapV2PairJson
const { abi: IUniswapV2Router02ABI } = IUniswapV2Router02Json
const { abi: QuoterABI } = QuoterJson
const { abi: QuoterV2ABI } = QuoterV2Json
const { abi: TickLensABI } = TickLensJson
const { abi: MulticallABI } = UniswapInterfaceMulticallJson
const { abi: NFTPositionManagerABI } = NonfungiblePositionManagerJson
......@@ -130,8 +132,8 @@ export function useV3NFTPositionManagerContract(withSignerIfPossible?: boolean):
)
}
export function useV3Quoter() {
return useContract<Quoter>(QUOTER_ADDRESSES, QuoterABI)
export function useQuoter(useQuoterV2: boolean) {
return useContract<Quoter | QuoterV2>(QUOTER_ADDRESSES, useQuoterV2 ? QuoterV2ABI : QuoterABI)
}
export function useTickLens(): TickLens | null {
......
import { nanoid } from '@reduxjs/toolkit'
import { TokenList } from '@uniswap/token-lists'
import { MAINNET_PROVIDER } from 'constants/infura'
import { MAINNET_PROVIDER } from 'constants/networks'
import getTokenList from 'lib/hooks/useTokenList/fetchTokenList'
import resolveENSContentHash from 'lib/utils/resolveENSContentHash'
import { useCallback } from 'react'
......
import { skipToken } from '@reduxjs/toolkit/query/react'
import { Currency } from '@uniswap/sdk-core'
import { FeeAmount, nearestUsableTick, Pool, TICK_SPACINGS, tickToPrice } from '@uniswap/v3-sdk'
import { useWeb3React } from '@web3-react/core'
import { SupportedChainId } from 'constants/chains'
import { ZERO_ADDRESS } from 'constants/misc'
import JSBI from 'jsbi'
......@@ -10,6 +11,7 @@ import { useEffect, useMemo, useState } from 'react'
import { useAllV3TicksQuery } from 'state/data/enhanced'
import computeSurroundingTicks from 'utils/computeSurroundingTicks'
import { V3_CORE_FACTORY_ADDRESSES } from '../constants/addresses'
import { useTickLens } from './useContract'
import { PoolState, usePool } from './usePools'
......@@ -54,9 +56,17 @@ function useTicksFromTickLens(
// Find nearest valid tick for pool in case tick is not initialized.
const activeTick = pool?.tickCurrent && tickSpacing ? nearestUsableTick(pool?.tickCurrent, tickSpacing) : undefined
const { chainId } = useWeb3React()
const poolAddress =
currencyA && currencyB && feeAmount && poolState === PoolState.EXISTS
? Pool.getAddress(currencyA?.wrapped, currencyB?.wrapped, feeAmount)
? Pool.getAddress(
currencyA?.wrapped,
currencyB?.wrapped,
feeAmount,
undefined,
chainId ? V3_CORE_FACTORY_ADDRESSES[chainId] : undefined
)
: undefined
// it is also possible to grab all tick data but it is extremely slow
......@@ -140,8 +150,17 @@ function useTicksFromSubgraph(
currencyB: Currency | undefined,
feeAmount: FeeAmount | undefined
) {
const { chainId } = useWeb3React()
const poolAddress =
currencyA && currencyB && feeAmount ? Pool.getAddress(currencyA?.wrapped, currencyB?.wrapped, feeAmount) : undefined
currencyA && currencyB && feeAmount
? Pool.getAddress(
currencyA?.wrapped,
currencyB?.wrapped,
feeAmount,
undefined,
chainId ? V3_CORE_FACTORY_ADDRESSES[chainId] : undefined
)
: undefined
return useAllV3TicksQuery(poolAddress ? { poolAddress: poolAddress?.toLowerCase(), skip: 0 } : skipToken, {
pollingInterval: ms`30s`,
......
......@@ -4,7 +4,7 @@ import tryParseCurrencyAmount from 'lib/utils/tryParseCurrencyAmount'
import { useMemo, useRef } from 'react'
import { SupportedChainId } from '../constants/chains'
import { DAI_OPTIMISM, USDC_ARBITRUM, USDC_MAINNET, USDC_POLYGON } from '../constants/tokens'
import { CUSD_CELO, DAI_OPTIMISM, USDC_ARBITRUM, USDC_MAINNET, USDC_POLYGON } from '../constants/tokens'
import { useBestV2Trade } from './useBestV2Trade'
import { useClientSideV3Trade } from './useClientSideV3Trade'
......@@ -15,13 +15,14 @@ export const STABLECOIN_AMOUNT_OUT: { [chainId: number]: CurrencyAmount<Token> }
[SupportedChainId.ARBITRUM_ONE]: CurrencyAmount.fromRawAmount(USDC_ARBITRUM, 10_000e6),
[SupportedChainId.OPTIMISM]: CurrencyAmount.fromRawAmount(DAI_OPTIMISM, 10_000e18),
[SupportedChainId.POLYGON]: CurrencyAmount.fromRawAmount(USDC_POLYGON, 10_000e6),
[SupportedChainId.CELO]: CurrencyAmount.fromRawAmount(CUSD_CELO, 10_000e18),
}
/**
* Returns the price in USDC of the input currency
* @param currency currency to compute the USDC price of
*/
export default function useUSDCPrice(currency?: Currency): Price<Currency, Token> | undefined {
export default function useStablecoinPrice(currency?: Currency): Price<Currency, Token> | undefined {
const chainId = currency?.chainId
const amountOut = chainId ? STABLECOIN_AMOUNT_OUT[chainId] : undefined
......@@ -62,7 +63,7 @@ export default function useUSDCPrice(currency?: Currency): Price<Currency, Token
}
export function useUSDCValue(currencyAmount: CurrencyAmount<Currency> | undefined | null) {
const price = useUSDCPrice(currencyAmount?.currency)
const price = useStablecoinPrice(currencyAmount?.currency)
return useMemo(() => {
if (!price || !currencyAmount) return null
......
......@@ -2,24 +2,29 @@ import { BigintIsh, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core'
// This file is lazy-loaded, so the import of smart-order-router is intentional.
// eslint-disable-next-line no-restricted-imports
import { AlphaRouter, AlphaRouterConfig, AlphaRouterParams, ChainId } from '@uniswap/smart-order-router'
import { SupportedChainId } from 'constants/chains'
import JSBI from 'jsbi'
import { GetQuoteResult } from 'state/routing/types'
import { transformSwapRouteToGetQuoteResult } from 'utils/transformSwapRouteToGetQuoteResult'
export const AUTO_ROUTER_SUPPORTED_CHAINS: ChainId[] = Object.values(ChainId).filter((chainId): chainId is ChainId =>
Number.isInteger(chainId)
)
export function toSupportedChainId(chainId: ChainId): SupportedChainId | undefined {
const numericChainId: number = chainId
if (SupportedChainId[numericChainId]) return numericChainId
return undefined
}
export function isSupportedChainId(chainId: ChainId | undefined): boolean {
if (chainId === undefined) return false
return toSupportedChainId(chainId) !== undefined
}
async function getQuote(
{
type,
chainId,
tokenIn,
tokenOut,
amount: amountRaw,
}: {
type: 'exactIn' | 'exactOut'
chainId: ChainId
tokenIn: { address: string; chainId: number; decimals: number; symbol?: string }
tokenOut: { address: string; chainId: number; decimals: number; symbol?: string }
amount: BigintIsh
......@@ -81,7 +86,6 @@ export async function getClientSideQuote(
return getQuote(
{
type,
chainId: tokenInChainId,
tokenIn: {
address: tokenInAddress,
chainId: tokenInChainId,
......
......@@ -8,6 +8,7 @@ import { useMemo } from 'react'
import { getTxOptimizedSwapRouter, SwapRouterVersion } from 'utils/getTxOptimizedSwapRouter'
import { ApprovalState, useApproval, useApprovalStateForSpender } from '../useApproval'
export { ApprovalState } from '../useApproval'
/** Returns approval state for all known swap routers */
......@@ -71,8 +72,7 @@ export default function useSwapApproval(
)
const spender = useSwapRouterAddress(trade)
const approval = useApproval(amountToApprove, spender, useIsPendingApproval)
return approval
return useApproval(amountToApprove, spender, useIsPendingApproval)
}
export function useSwapApprovalOptimizedTrade(
......@@ -110,7 +110,7 @@ export function useSwapApprovalOptimizedTrade(
return V3Trade.createUncheckedTradeWithMultipleRoutes({
routes: trade.swaps.map(({ route, inputAmount, outputAmount }) => ({
route: new V3Route(
route.pools.filter((p) => p instanceof Pool) as Pool[],
route.pools.filter((p): p is Pool => p instanceof Pool),
inputAmount.currency,
outputAmount.currency
),
......
......@@ -5,7 +5,9 @@ import { useMemo } from 'react'
import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo'
import EthereumLogo from '../../assets/images/ethereum-logo.png'
import CeloLogo from '../../assets/svg/celo_logo.svg'
import MaticLogo from '../../assets/svg/matic-token-icon.svg'
import { isCelo, nativeOnChain } from '../../constants/tokens'
type Network = 'ethereum' | 'arbitrum' | 'optimism'
......@@ -24,9 +26,12 @@ function chainIdToNetworkName(networkId: SupportedChainId): Network {
function getNativeLogoURI(chainId: SupportedChainId = SupportedChainId.MAINNET): string {
switch (chainId) {
case SupportedChainId.POLYGON_MUMBAI:
case SupportedChainId.POLYGON:
case SupportedChainId.POLYGON_MUMBAI:
return MaticLogo
case SupportedChainId.CELO:
case SupportedChainId.CELO_ALFAJORES:
return CeloLogo
default:
return EthereumLogo
}
......@@ -38,6 +43,13 @@ function getTokenLogoURI(address: string, chainId: SupportedChainId = SupportedC
if (networksWithUrls.includes(chainId)) {
return `https://raw.githubusercontent.com/Uniswap/assets/master/blockchains/${networkName}/assets/${address}/logo.png`
}
// Celo logo logo is hosted elsewhere.
if (isCelo(chainId)) {
if (address === nativeOnChain(chainId).wrapped.address) {
return 'https://raw.githubusercontent.com/ubeswap/default-token-list/master/assets/asset_CELO.png'
}
}
}
export default function useCurrencyLogoURIs(currency?: Currency | null): string[] {
......
import { NativeCurrency } from '@uniswap/sdk-core'
import { NativeCurrency, Token } from '@uniswap/sdk-core'
import { useWeb3React } from '@web3-react/core'
import { SupportedChainId } from 'constants/chains'
import { nativeOnChain } from 'constants/tokens'
import { useMemo } from 'react'
export default function useNativeCurrency(): NativeCurrency {
export default function useNativeCurrency(): NativeCurrency | Token {
const { chainId } = useWeb3React()
return useMemo(
() =>
......
......@@ -43,8 +43,8 @@ import { useArgentWalletContract } from '../../hooks/useArgentWalletContract'
import { useV3NFTPositionManagerContract } from '../../hooks/useContract'
import { useDerivedPositionInfo } from '../../hooks/useDerivedPositionInfo'
import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported'
import { useUSDCValue } from '../../hooks/useStablecoinPrice'
import useTransactionDeadline from '../../hooks/useTransactionDeadline'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import { useV3PositionFromTokenId } from '../../hooks/useV3Positions'
import { useToggleWalletModal } from '../../state/application/hooks'
import { Bound, Field } from '../../state/mint/v3/actions'
......
......@@ -20,8 +20,8 @@ import { BIG_INT_SECONDS_IN_WEEK, BIG_INT_ZERO } from '../../constants/misc'
import { useCurrency } from '../../hooks/Tokens'
import { useColor } from '../../hooks/useColor'
import usePrevious from '../../hooks/usePrevious'
import useStablecoinPrice from '../../hooks/useStablecoinPrice'
import { useTotalSupply } from '../../hooks/useTotalSupply'
import useUSDCPrice from '../../hooks/useUSDCPrice'
import { useV2Pair } from '../../hooks/useV2Pairs'
import { useToggleWalletModal } from '../../state/application/hooks'
import { useTokenBalance } from '../../state/connection/hooks'
......@@ -138,7 +138,7 @@ export default function Manage({
const countUpAmountPrevious = usePrevious(countUpAmount) ?? '0'
// get the USD value of staked WETH
const USDPrice = useUSDCPrice(WETH)
const USDPrice = useStablecoinPrice(WETH)
const valueOfTotalStakedAmountInUSDC =
valueOfTotalStakedAmountInWETH && USDPrice?.quote(valueOfTotalStakedAmountInWETH)
......
......@@ -20,7 +20,7 @@ import { useToken } from 'hooks/Tokens'
import { useV3NFTPositionManagerContract } from 'hooks/useContract'
import useIsTickAtLimit from 'hooks/useIsTickAtLimit'
import { PoolState, usePool } from 'hooks/usePools'
import useUSDCPrice from 'hooks/useUSDCPrice'
import useStablecoinPrice from 'hooks/useStablecoinPrice'
import { useV3PositionFees } from 'hooks/useV3PositionFees'
import { useV3PositionFromTokenId } from 'hooks/useV3Positions'
import { useSingleCallResult } from 'lib/hooks/multicall'
......@@ -399,8 +399,8 @@ export function PositionPage({
const [showConfirm, setShowConfirm] = useState(false)
// usdc prices always in terms of tokens
const price0 = useUSDCPrice(token0 ?? undefined)
const price1 = useUSDCPrice(token1 ?? undefined)
const price0 = useStablecoinPrice(token0 ?? undefined)
const price1 = useStablecoinPrice(token1 ?? undefined)
const fiatValueOfFees: CurrencyAmount<Currency> | null = useMemo(() => {
if (!price0 || !price1 || !feeValue0 || !feeValue1) return null
......
......@@ -40,7 +40,7 @@ import useENSAddress from '../../hooks/useENSAddress'
import { useERC20PermitFromTrade, UseERC20PermitState } from '../../hooks/useERC20Permit'
import useIsArgentWallet from '../../hooks/useIsArgentWallet'
import { useIsSwapUnsupported } from '../../hooks/useIsSwapUnsupported'
import { useUSDCValue } from '../../hooks/useUSDCPrice'
import { useUSDCValue } from '../../hooks/useStablecoinPrice'
import useWrapCallback, { WrapErrorText, WrapType } from '../../hooks/useWrapCallback'
import { useToggleWalletModal } from '../../state/application/hooks'
import { Field } from '../../state/swap/actions'
......
......@@ -15,6 +15,8 @@ const CHAIN_SUBGRAPH_URL: Record<number, string> = {
[SupportedChainId.OPTIMISM]: 'https://api.thegraph.com/subgraphs/name/ianlapham/optimism-post-regenesis',
[SupportedChainId.POLYGON]: 'https://api.thegraph.com/subgraphs/name/ianlapham/uniswap-v3-polygon',
[SupportedChainId.CELO]: 'https://api.thegraph.com/subgraphs/name/jesse-sawa/uniswap-celo',
}
export const api = createApi({
......
import { getVersionUpgrade, minVersionBump, VersionUpgrade } from '@uniswap/token-lists'
import { useWeb3React } from '@web3-react/core'
import { SupportedChainId } from 'constants/chains'
import { ARBITRUM_LIST, OPTIMISM_LIST, UNSUPPORTED_LIST_URLS } from 'constants/lists'
import { ARBITRUM_LIST, CELO_LIST, OPTIMISM_LIST, UNSUPPORTED_LIST_URLS } from 'constants/lists'
import useInterval from 'lib/hooks/useInterval'
import { useCallback, useEffect } from 'react'
import { useAppDispatch } from 'state/hooks'
......@@ -36,6 +36,9 @@ export default function Updater(): null {
if (chainId && [SupportedChainId.ARBITRUM_ONE, SupportedChainId.ARBITRUM_RINKEBY].includes(chainId)) {
dispatch(enableList(ARBITRUM_LIST))
}
if (chainId && [SupportedChainId.CELO, SupportedChainId.CELO_ALFAJORES].includes(chainId)) {
dispatch(enableList(CELO_LIST))
}
}, [chainId, dispatch])
// fetch all lists every 10 minutes, but only after we initialize provider
useInterval(fetchAllListsCallback, provider ? 1000 * 60 * 10 : null)
......
......@@ -2,8 +2,8 @@ import { BaseProvider, JsonRpcProvider } from '@ethersproject/providers'
import { createApi, fetchBaseQuery, FetchBaseQueryError } from '@reduxjs/toolkit/query/react'
import { Protocol } from '@uniswap/router-sdk'
import { ChainId } from '@uniswap/smart-order-router'
import { INFURA_NETWORK_URLS } from 'constants/infura'
import { AUTO_ROUTER_SUPPORTED_CHAINS, getClientSideQuote } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import { RPC_URLS } from 'constants/networks'
import { getClientSideQuote, toSupportedChainId } from 'lib/hooks/routing/clientSideSmartOrderRouter'
import ms from 'ms.macro'
import qs from 'qs'
......@@ -14,8 +14,9 @@ function getRouterProvider(chainId: ChainId): BaseProvider {
const provider = routerProviders.get(chainId)
if (provider) return provider
if (AUTO_ROUTER_SUPPORTED_CHAINS.includes(chainId)) {
const provider = new JsonRpcProvider(INFURA_NETWORK_URLS[chainId])
const supportedChainId = toSupportedChainId(chainId)
if (supportedChainId) {
const provider = new JsonRpcProvider(RPC_URLS[supportedChainId])
routerProviders.set(chainId, provider)
return provider
}
......
......@@ -2,7 +2,7 @@ import { skipToken } from '@reduxjs/toolkit/query/react'
import { Currency, CurrencyAmount, TradeType } from '@uniswap/sdk-core'
import { IMetric, MetricLoggerUnit, setGlobalMetric } from '@uniswap/smart-order-router'
import { sendTiming } from 'components/analytics'
import { useStablecoinAmountFromFiatValue } from 'hooks/useUSDCPrice'
import { useStablecoinAmountFromFiatValue } from 'hooks/useStablecoinPrice'
import { useRoutingAPIArguments } from 'lib/hooks/routing/useRoutingAPIArguments'
import useIsValidBlock from 'lib/hooks/useIsValidBlock'
import ms from 'ms.macro'
......
......@@ -60,6 +60,15 @@ export default function RadialGradientByChainUpdater(): null {
backgroundRadialGradientElement.style.background = darkMode ? polygonDarkGradient : polygonLightGradient
backgroundRadialGradientElement.style.backgroundBlendMode = darkMode ? 'overlay,normal' : 'multiply,normal'
break
case SupportedChainId.CELO:
case SupportedChainId.CELO_ALFAJORES:
setBackground(backgroundResetStyles)
const celoLightGradient = 'radial-gradient(150% 100% at 50% 0%,#35D07F35 0, #FBCC5C35 100%)'
const celoDarkGradient =
'radial-gradient(150% 100% at 50% 0%, rgb(2 80 47) 2%, rgb(12 41 28) 53%, rgb(31, 33, 40) 100%)'
backgroundRadialGradientElement.style.background = darkMode ? celoDarkGradient : celoLightGradient
backgroundRadialGradientElement.style.backgroundBlendMode = darkMode ? 'overlay,normal' : 'multiply,normal'
break
default:
setBackground(initialStyles)
backgroundRadialGradientElement.style.background = ''
......
......@@ -19,6 +19,9 @@ describe('#getExplorerLink', () => {
it('polygon', () => {
expect(getExplorerLink(137, 'abc', ExplorerDataType.ADDRESS)).toEqual('https://polygonscan.com/address/abc')
})
it('celo', () => {
expect(getExplorerLink(42220, 'abc', ExplorerDataType.ADDRESS)).toEqual('https://celoscan.io/address/abc')
})
it('ropsten', () => {
expect(getExplorerLink(3, 'abc', ExplorerDataType.ADDRESS)).toEqual('https://ropsten.etherscan.io/address/abc')
})
......
import { SupportedChainId } from '../constants/chains'
const ETHERSCAN_PREFIXES: { [chainId: number]: string } = {
const BLOCK_EXPLORER_PREFIXES: { [chainId: number]: string } = {
[SupportedChainId.MAINNET]: 'https://etherscan.io',
[SupportedChainId.ROPSTEN]: 'https://ropsten.etherscan.io',
[SupportedChainId.RINKEBY]: 'https://rinkeby.etherscan.io',
......@@ -8,8 +8,10 @@ const ETHERSCAN_PREFIXES: { [chainId: number]: string } = {
[SupportedChainId.KOVAN]: 'https://kovan.etherscan.io',
[SupportedChainId.OPTIMISM]: 'https://optimistic.etherscan.io',
[SupportedChainId.OPTIMISTIC_KOVAN]: 'https://kovan-optimistic.etherscan.io',
[SupportedChainId.POLYGON_MUMBAI]: 'https://mumbai.polygonscan.com',
[SupportedChainId.POLYGON]: 'https://polygonscan.com',
[SupportedChainId.POLYGON_MUMBAI]: 'https://mumbai.polygonscan.com',
[SupportedChainId.CELO]: 'https://celoscan.io',
[SupportedChainId.CELO_ALFAJORES]: 'https://alfajores-blockscout.celo-testnet.org',
}
export enum ExplorerDataType {
......@@ -54,7 +56,7 @@ export function getExplorerLink(chainId: number, data: string, type: ExplorerDat
}
}
const prefix = ETHERSCAN_PREFIXES[chainId] ?? 'https://etherscan.io'
const prefix = BLOCK_EXPLORER_PREFIXES[chainId] ?? 'https://etherscan.io'
switch (type) {
case ExplorerDataType.TRANSACTION:
......
......@@ -9,7 +9,7 @@ import {
} from 'connection'
import { CHAIN_INFO } from 'constants/chainInfo'
import { ALL_SUPPORTED_CHAIN_IDS, SupportedChainId } from 'constants/chains'
import { INFURA_NETWORK_URLS } from 'constants/infura'
import { RPC_URLS } from 'constants/networks'
function getRpcUrls(chainId: SupportedChainId): [string] {
switch (chainId) {
......@@ -18,7 +18,7 @@ function getRpcUrls(chainId: SupportedChainId): [string] {
case SupportedChainId.ROPSTEN:
case SupportedChainId.KOVAN:
case SupportedChainId.GOERLI:
return [INFURA_NETWORK_URLS[chainId]]
return [RPC_URLS[chainId]]
case SupportedChainId.OPTIMISM:
return ['https://mainnet.optimism.io']
case SupportedChainId.OPTIMISTIC_KOVAN:
......@@ -31,6 +31,10 @@ function getRpcUrls(chainId: SupportedChainId): [string] {
return ['https://polygon-rpc.com/']
case SupportedChainId.POLYGON_MUMBAI:
return ['https://rpc-endpoints.superfluid.dev/mumbai']
case SupportedChainId.CELO:
return ['https://forno.celo.org']
case SupportedChainId.CELO_ALFAJORES:
return ['https://alfajores-forno.celo-testnet.org']
default:
}
// Our API-keyed URLs will fail security checks when used with external wallets.
......
......@@ -3142,6 +3142,11 @@
resolved "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.4.1-solc-0.7-2.tgz"
integrity sha512-tAG9LWg8+M2CMu7hIsqHPaTyG4uDzjr6mhvH96LvOpLZZj6tgzTluBt+LsCf1/QaYrlis6pITvpIaIhE+iZB+Q==
"@openzeppelin/contracts@3.4.2-solc-0.7":
version "3.4.2-solc-0.7"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2-solc-0.7.tgz#38f4dbab672631034076ccdf2f3201fab1726635"
integrity sha512-W6QmqgkADuFcTLzHL8vVoNBtkwjvQRpYIAom7KiUNoLKghyx3FgH0GBjt8NRvigV1ZmMOBllvE1By1C+bi8WpA==
"@pedrouid/environment@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@pedrouid/environment/-/environment-1.0.1.tgz#858f0f8a057340e0b250398b75ead77d6f4342ec"
......@@ -4540,16 +4545,16 @@
resolved "https://registry.yarnpkg.com/@uniswap/redux-multicall/-/redux-multicall-1.1.5.tgz#7c097047d489c1624038c0fbbd3d76dc705bf153"
integrity sha512-RSMhfuAX2rPimnevvAAiwoyV2bCGTIKhVHEBOLTMF+oVxYcKKe9hCwx/cffY12t/usXWHlEJ//V7JoxTKI1Lyg==
"@uniswap/router-sdk@^1.0.3", "@uniswap/router-sdk@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@uniswap/router-sdk/-/router-sdk-1.0.5.tgz#59b429327b0d202744db6de958e6b61d5adeec12"
integrity sha512-PA/0Ye9u3U5cm/LHrJuOgVSff6W4oFY3h+MUEzdp80SYIQdZZJ+BV06RL0h5KOSH+tuIX72n/qNusuRcf2Tc8Q==
"@uniswap/router-sdk@^1.0.5", "@uniswap/router-sdk@^1.0.6":
version "1.0.6"
resolved "https://registry.yarnpkg.com/@uniswap/router-sdk/-/router-sdk-1.0.6.tgz#cc8c9abe241fed12fc58788fd12020ac4495e5d3"
integrity sha512-xhtx8oaiETiC/oVbsZwZ/OXfHP8UGDFuW2oND3r43uCj/0f2vlElwcd9npL6gN5ZxrawbA3ZwR6BrPrPJ5QGjQ==
dependencies:
"@ethersproject/abi" "^5.5.0"
"@uniswap/sdk-core" "^3.0.1"
"@uniswap/swap-router-contracts" "1.1.0"
"@uniswap/v2-sdk" "^3.0.1"
"@uniswap/v3-sdk" "^3.7.1"
"@uniswap/v3-sdk" "^3.8.3"
"@uniswap/sdk-core@^3.0.0-alpha.3", "@uniswap/sdk-core@^3.0.1":
version "3.0.1"
......@@ -4617,6 +4622,18 @@
dotenv "^14.2.0"
hardhat-watcher "^2.1.1"
"@uniswap/swap-router-contracts@^1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@uniswap/swap-router-contracts/-/swap-router-contracts-1.2.1.tgz#223c8b6672b7754080d95ca917763d98feb5e696"
integrity sha512-aRNiZYIOpJ0uYxujPxvQsUEuNJWLC4bvnmU40TlNej1rGWHPyDL1PmnVzebu8UpW9EGeKlvDjsNGTyo53dih9Q==
dependencies:
"@openzeppelin/contracts" "3.4.2-solc-0.7"
"@uniswap/v2-core" "1.0.1"
"@uniswap/v3-core" "1.0.0"
"@uniswap/v3-periphery" "1.4.1"
dotenv "^14.2.0"
hardhat-watcher "^2.1.1"
"@uniswap/token-lists@^1.0.0-beta.25", "@uniswap/token-lists@^1.0.0-beta.30":
version "1.0.0-beta.30"
resolved "https://registry.yarnpkg.com/@uniswap/token-lists/-/token-lists-1.0.0-beta.30.tgz#2103ca23b8007c59ec71718d34cdc97861c409e5"
......@@ -4656,7 +4673,7 @@
resolved "https://registry.npmjs.org/@uniswap/v3-core/-/v3-core-1.0.0.tgz"
integrity sha512-kSC4djMGKMHj7sLMYVnn61k9nu+lHjMIxgg9CDQT+s2QYLoA56GbSK9Oxr+qJXzzygbkrmuY6cwgP6cW2JXPFA==
"@uniswap/v3-periphery@1.3.0", "@uniswap/v3-periphery@^1.0.1", "@uniswap/v3-periphery@^1.1.1":
"@uniswap/v3-periphery@1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.3.0.tgz#37f0a1ef6025221722e50e9f3f2009c2d5d6e4ec"
integrity sha512-HjHdI5RkjBl8zz3bqHShrbULFoZSrjbbrRHoO2vbzn+WRzTa6xY4PWphZv2Tlcb38YEKfKHp6NPl5hVedac8uw==
......@@ -4668,14 +4685,27 @@
base64-sol "1.0.1"
hardhat-watcher "^2.1.1"
"@uniswap/v3-sdk@^3.7.0", "@uniswap/v3-sdk@^3.7.1", "@uniswap/v3-sdk@^3.8.2":
version "3.8.2"
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.8.2.tgz#6e10eebe0da851a4f6a5036a1e70a896a5c239d4"
integrity sha512-JVrs1ZuWKP8JmYi5hxFliOnCFAEREwMpE7qB6rKPCo155/pIRyQ90lJfQZCJO7pP/webx5t5JFxCOytmDIp29Q==
"@uniswap/v3-periphery@1.4.1", "@uniswap/v3-periphery@^1.0.1", "@uniswap/v3-periphery@^1.1.1":
version "1.4.1"
resolved "https://registry.yarnpkg.com/@uniswap/v3-periphery/-/v3-periphery-1.4.1.tgz#b90f08b7386163c0abfd7258831caef6339c7862"
integrity sha512-Ab0ZCKOQrQMKIcpBTezTsEhWfQjItd0TtkCG8mPhoQu+wC67nPaf4hYUhM6wGHeFUmDiYY5MpEQuokB0ENvoTg==
dependencies:
"@openzeppelin/contracts" "3.4.2-solc-0.7"
"@uniswap/lib" "^4.0.1-alpha"
"@uniswap/v2-core" "1.0.1"
"@uniswap/v3-core" "1.0.0"
base64-sol "1.0.1"
hardhat-watcher "^2.1.1"
"@uniswap/v3-sdk@^3.7.0", "@uniswap/v3-sdk@^3.8.3", "@uniswap/v3-sdk@^3.9.0":
version "3.9.0"
resolved "https://registry.yarnpkg.com/@uniswap/v3-sdk/-/v3-sdk-3.9.0.tgz#de93fa19f89c29d460996aa4d0b4bb6531641105"
integrity sha512-LuoF3UcY1DxSAQKJ3E4/1Eq4HaNp+x+7q9mvbpiu+/PBj+O1DjLforAMrKxu+RsA0aarmZtz7yBnAPy+akgfgQ==
dependencies:
"@ethersproject/abi" "^5.0.12"
"@ethersproject/solidity" "^5.0.9"
"@uniswap/sdk-core" "^3.0.1"
"@uniswap/swap-router-contracts" "^1.2.1"
"@uniswap/v3-periphery" "^1.1.1"
"@uniswap/v3-staker" "1.0.0"
tiny-invariant "^1.1.0"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment