feat: Add support for mixed routes in the interface (#4181)

* Expand typing to match new QuoteResponse from routing api

* lint autofix

* Expand InterfaceTrade class to match router-sdk and allow mixedroutes

* Add new routing-api poolInRoute logic for client side trade

* eslint fix ==

* Add custom mxiedProtocolBadge and add into badgeDiagram

* Bump router-sdk to published version, and install latest local SOR

* git checkout main yarn.lock && yarn && npx yarn-deduplicate

* Bump SOR to 2.9.2

* bump SOR to 2.9.2

* Update yarn.lock

* revert slice.ts

* Add guesstimate logic for mixedRoutes

* Oops wrong pool import lol

* Add beta url + expand protocols array

* Add forceMixedRoutes for testing

* Fix cyrpress build issue: no-loop-func

* Change to prod url and remove testing param

* remove protocol flag

* Revisions: getRouteProtocol helper, fix gas acc for mixed route

* revert protocols array abck

* Remove :Protocol
This commit is contained in:
Eric Zhong 2022-08-11 16:40:55 -04:00 committed by GitHub
parent a6e35ed70f
commit 47e6c0891e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 105 additions and 145 deletions

@ -131,9 +131,9 @@
"@uniswap/liquidity-staker": "^1.0.2",
"@uniswap/merkle-distributor": "1.0.1",
"@uniswap/redux-multicall": "^1.1.5",
"@uniswap/router-sdk": "^1.0.6",
"@uniswap/router-sdk": "^1.3.0",
"@uniswap/sdk-core": "^3.0.1",
"@uniswap/smart-order-router": "^2.8.2",
"@uniswap/smart-order-router": "^2.9.2",
"@uniswap/token-lists": "^1.0.0-beta.30",
"@uniswap/v2-core": "1.0.0",
"@uniswap/v2-periphery": "^1.1.0-beta.0",

@ -1,4 +1,5 @@
import { Trans } from '@lingui/macro'
import { Protocol } from '@uniswap/router-sdk'
import { Currency } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
import Badge from 'components/Badge'
@ -73,6 +74,10 @@ const ProtocolBadge = styled(Badge)`
z-index: ${Z_INDEX.sticky + 1};
`
const MixedProtocolBadge = styled(ProtocolBadge)`
width: 60px;
`
const BadgeText = styled(ThemedText.DeprecatedSmall)`
word-break: normal;
`
@ -109,9 +114,15 @@ function Route({ entry: { percent, path, protocol } }: { entry: RoutingDiagramEn
<DotColor />
</DottedLine>
<OpaqueBadge>
<ProtocolBadge>
<BadgeText fontSize={12}>{protocol.toUpperCase()}</BadgeText>
</ProtocolBadge>
{protocol === Protocol.MIXED ? (
<MixedProtocolBadge>
<BadgeText fontSize={12}>{'V3 + V2'}</BadgeText>
</MixedProtocolBadge>
) : (
<ProtocolBadge>
<BadgeText fontSize={12}>{protocol.toUpperCase()}</BadgeText>
</ProtocolBadge>
)}
<BadgeText fontSize={14} style={{ minWidth: 'auto' }}>
{percent.toSignificant(2)}%
</BadgeText>

@ -1,5 +1,7 @@
import { Protocol, Trade } from '@uniswap/router-sdk'
import { MixedRoute, partitionMixedRouteByProtocol, Protocol, Trade } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Percent, TradeType } from '@uniswap/sdk-core'
import { Pair } from '@uniswap/v2-sdk'
import { Pool } from '@uniswap/v3-sdk'
import { useWeb3React } from '@web3-react/core'
import { SUPPORTED_GAS_ESTIMATE_CHAIN_IDS, SupportedChainId } from 'constants/chains'
import { L2_CHAIN_IDS } from 'constants/chains'
@ -43,8 +45,20 @@ function guesstimateGas(trade: Trade<Currency, Currency, TradeType> | undefined)
// V3 gas costs scale on initialized ticks being crossed, but we don't have that data here.
// We bake in some tick crossings into the base 100k cost.
gas += V3_SWAP_BASE_GAS_ESTIMATE + route.pools.length * V3_SWAP_HOP_GAS_ESTIMATE
} else if (route.protocol === Protocol.MIXED) {
const sections = partitionMixedRouteByProtocol(route as MixedRoute<Currency, Currency>)
gas += sections.reduce((gas, section) => {
if (section.every((pool) => pool instanceof Pool)) {
return gas + V3_SWAP_BASE_GAS_ESTIMATE + section.length * V3_SWAP_HOP_GAS_ESTIMATE
} else if (section.every((pool) => pool instanceof Pair)) {
return gas + V2_SWAP_BASE_GAS_ESTIMATE + (section.length - 1) * V2_SWAP_HOP_GAS_ESTIMATE
} else {
console.warn('Invalid section')
return gas
}
}, 0)
} else {
// TODO: Update with better estimates once we have interleaved routes.
// fallback general gas estimation
gas += V3_SWAP_BASE_GAS_ESTIMATE + route.pools.length * V3_SWAP_HOP_GAS_ESTIMATE
}
}

@ -1,4 +1,4 @@
import { Trade } from '@uniswap/router-sdk'
import { MixedRouteSDK, Trade } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core'
import { Route as V2Route } from '@uniswap/v2-sdk'
import { Route as V3Route } from '@uniswap/v3-sdk'
@ -64,7 +64,7 @@ export interface GetQuoteResult {
quoteDecimals: string
quoteGasAdjusted: string
quoteGasAdjustedDecimals: string
route: Array<V3PoolInRoute[] | V2PoolInRoute[]>
route: Array<(V3PoolInRoute | V2PoolInRoute)[]>
routeString: string
}
@ -94,6 +94,11 @@ export class InterfaceTrade<
outputAmount: CurrencyAmount<TOutput>
}[]
tradeType: TTradeType
mixedRoutes?: {
mixedRoute: MixedRouteSDK<TInput, TOutput>
inputAmount: CurrencyAmount<TInput>
outputAmount: CurrencyAmount<TOutput>
}[]
}) {
super(routes)
this.blockNumber = blockNumber

@ -1,3 +1,4 @@
import { MixedRouteSDK, Protocol } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount, Token, TradeType } from '@uniswap/sdk-core'
import { Pair, Route as V2Route } from '@uniswap/v2-sdk'
import { FeeAmount, Pool, Route as V3Route } from '@uniswap/v3-sdk'
@ -40,9 +41,21 @@ export function computeRoutes(
throw new Error('Expected both amountIn and amountOut to be present')
}
const routeProtocol = getRouteProtocol(route)
return {
routev3: isV3Route(route) ? new V3Route(route.map(parsePool), parsedCurrencyIn, parsedCurrencyOut) : null,
routev2: !isV3Route(route) ? new V2Route(route.map(parsePair), parsedCurrencyIn, parsedCurrencyOut) : null,
routev3:
routeProtocol === Protocol.V3
? new V3Route(route.map(genericPoolPairParser) as Pool[], parsedCurrencyIn, parsedCurrencyOut)
: null,
routev2:
routeProtocol === Protocol.V2
? new V2Route(route.map(genericPoolPairParser) as Pair[], parsedCurrencyIn, parsedCurrencyOut)
: null,
mixedRoute:
routeProtocol === Protocol.MIXED
? new MixedRouteSDK(route.map(genericPoolPairParser), parsedCurrencyIn, parsedCurrencyOut)
: null,
inputAmount: CurrencyAmount.fromRawAmount(parsedCurrencyIn, rawAmountIn),
outputAmount: CurrencyAmount.fromRawAmount(parsedCurrencyOut, rawAmountOut),
}
@ -71,6 +84,13 @@ export function transformRoutesToTrade<TTradeType extends TradeType>(
route
?.filter((r): r is typeof route[0] & { routev3: NonNullable<typeof route[0]['routev3']> } => r.routev3 !== null)
.map(({ routev3, inputAmount, outputAmount }) => ({ routev3, inputAmount, outputAmount })) ?? [],
mixedRoutes:
route
?.filter(
(r): r is typeof route[0] & { mixedRoute: NonNullable<typeof route[0]['mixedRoute']> } =>
r.mixedRoute !== null
)
.map(({ mixedRoute, inputAmount, outputAmount }) => ({ mixedRoute, inputAmount, outputAmount })) ?? [],
tradeType,
gasUseEstimateUSD,
blockNumber,
@ -97,6 +117,12 @@ const parsePair = ({ reserve0, reserve1 }: V2PoolInRoute): Pair =>
CurrencyAmount.fromRawAmount(parseToken(reserve1.token), reserve1.quotient)
)
function isV3Route(route: V3PoolInRoute[] | V2PoolInRoute[]): route is V3PoolInRoute[] {
return route[0].type === 'v3-pool'
const genericPoolPairParser = (pool: V3PoolInRoute | V2PoolInRoute): Pool | Pair => {
return pool.type === 'v3-pool' ? parsePool(pool) : parsePair(pool)
}
function getRouteProtocol(route: (V3PoolInRoute | V2PoolInRoute)[]): Protocol {
if (route.every((pool) => pool.type === 'v2-pool')) return Protocol.V2
if (route.every((pool) => pool.type === 'v3-pool')) return Protocol.V3
return Protocol.MIXED
}

@ -1,6 +1,7 @@
import { Protocol } from '@uniswap/router-sdk'
import { Currency, CurrencyAmount } from '@uniswap/sdk-core'
import { routeAmountsToString, SwapRoute } from '@uniswap/smart-order-router'
import { Pool } from '@uniswap/v3-sdk'
import { GetQuoteResult, V2PoolInRoute, V3PoolInRoute } from 'state/routing/types'
// from routing-api (https://github.com/Uniswap/routing-api/blob/main/lib/handlers/quote/quote.ts#L243-L311)
@ -19,29 +20,29 @@ export function transformSwapRouteToGetQuoteResult(
blockNumber,
}: SwapRoute
): GetQuoteResult {
const routeResponse: Array<V3PoolInRoute[] | V2PoolInRoute[]> = []
const routeResponse: Array<(V3PoolInRoute | V2PoolInRoute)[]> = []
for (const subRoute of route) {
const { amount, quote, tokenPath } = subRoute
if (subRoute.protocol === Protocol.V3) {
const pools = subRoute.route.pools
const curRoute: V3PoolInRoute[] = []
for (let i = 0; i < pools.length; i++) {
const nextPool = pools[i]
const tokenIn = tokenPath[i]
const tokenOut = tokenPath[i + 1]
const pools = subRoute.protocol === Protocol.V2 ? subRoute.route.pairs : subRoute.route.pools
const curRoute: (V3PoolInRoute | V2PoolInRoute)[] = []
for (let i = 0; i < pools.length; i++) {
const nextPool = pools[i]
const tokenIn = tokenPath[i]
const tokenOut = tokenPath[i + 1]
let edgeAmountIn = undefined
if (i === 0) {
edgeAmountIn = type === 'exactIn' ? amount.quotient.toString() : quote.quotient.toString()
}
let edgeAmountIn = undefined
if (i === 0) {
edgeAmountIn = type === 'exactIn' ? amount.quotient.toString() : quote.quotient.toString()
}
let edgeAmountOut = undefined
if (i === pools.length - 1) {
edgeAmountOut = type === 'exactIn' ? quote.quotient.toString() : amount.quotient.toString()
}
let edgeAmountOut = undefined
if (i === pools.length - 1) {
edgeAmountOut = type === 'exactIn' ? quote.quotient.toString() : amount.quotient.toString()
}
if (nextPool instanceof Pool) {
curRoute.push({
type: 'v3-pool',
tokenIn: {
@ -63,27 +64,7 @@ export function transformSwapRouteToGetQuoteResult(
amountIn: edgeAmountIn,
amountOut: edgeAmountOut,
})
}
routeResponse.push(curRoute)
} else if (subRoute.protocol === Protocol.V2) {
const pools = subRoute.route.pairs
const curRoute: V2PoolInRoute[] = []
for (let i = 0; i < pools.length; i++) {
const nextPool = pools[i]
const tokenIn = tokenPath[i]
const tokenOut = tokenPath[i + 1]
let edgeAmountIn = undefined
if (i === 0) {
edgeAmountIn = type === 'exactIn' ? amount.quotient.toString() : quote.quotient.toString()
}
let edgeAmountOut = undefined
if (i === pools.length - 1) {
edgeAmountOut = type === 'exactIn' ? quote.quotient.toString() : amount.quotient.toString()
}
} else {
const reserve0 = nextPool.reserve0
const reserve1 = nextPool.reserve1
@ -123,9 +104,9 @@ export function transformSwapRouteToGetQuoteResult(
amountOut: edgeAmountOut,
})
}
routeResponse.push(curRoute)
}
routeResponse.push(curRoute)
}
const result: GetQuoteResult = {

109
yarn.lock

@ -3159,11 +3159,6 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@nomiclabs/hardhat-ethers@^2.0.6":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-ethers/-/hardhat-ethers-2.1.0.tgz#9b7dc94d669ad9dc286b94f6f2f1513118c7027b"
integrity sha512-vlW90etB3675QWG7tMrHaDoTa7ymMB7irM4DAQ98g8zJoe9YqEggeDnbO6v5b+BLth/ty4vN6Ko/kaqRN1krHw==
"@npmcli/move-file@^1.0.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674"
@ -3807,18 +3802,6 @@
resolved "https://registry.yarnpkg.com/@types/array.prototype.flatmap/-/array.prototype.flatmap-1.2.2.tgz#9041c2dc907d583ffb80b8882a782b42436d57c1"
integrity sha512-dto5M/8GxPzjaScvQeft2IG0EkoZZfPg2+1noM2BWiU1VR2zsGHf76LonTOnLQKDuJlKDLzKaru4b+5Sci0Yhg==
"@types/async-retry@^1.4.2":
version "1.4.3"
resolved "https://registry.yarnpkg.com/@types/async-retry/-/async-retry-1.4.3.tgz#8b78f6ce88d97e568961732cdd9e5325cdc8c246"
integrity sha512-B3C9QmmNULVPL2uSJQ088eGWTNPIeUk35hca6CV8rRDJ8GXuQJP5CCVWA1ZUCrb9xYP7Js/RkLqnNNwKhe+Zsw==
dependencies:
"@types/retry" "*"
"@types/await-timeout@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@types/await-timeout/-/await-timeout-0.3.1.tgz#3a0baafc3a96c7a14447a4dcfdcc76b21ce97c3b"
integrity sha512-H5PzROT4KuP7XQDua13Iw8did//OCKAZ/3TL15DjvMzDonrk4HvhH1+tLko96f2guU6XaD3AoqRa49ZOwbwNig==
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.7":
version "7.1.15"
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.15.tgz#2ccfb1ad55a02c83f8e0ad327cbc332f55eb1024"
@ -3866,20 +3849,6 @@
dependencies:
"@types/node" "*"
"@types/bunyan-blackhole@^0.2.2":
version "0.2.2"
resolved "https://registry.yarnpkg.com/@types/bunyan-blackhole/-/bunyan-blackhole-0.2.2.tgz#469e58c5d129027a9e08bcf9a36232a69b6ad011"
integrity sha512-nbuxFn2FVw1AAT1h6shgluwz1cgpLKaMBYbEZcMU69Jb1UvSsXcwRiIg+FP4+/JjEUp/uPYLC+twWpfCAaVN1g==
dependencies:
"@types/bunyan" "*"
"@types/bunyan@*", "@types/bunyan@^1.8.6":
version "1.8.7"
resolved "https://registry.yarnpkg.com/@types/bunyan/-/bunyan-1.8.7.tgz#63cc65b5ecff6217d1509409a575e7b991f80831"
integrity sha512-jaNt6xX5poSmXuDAkQrSqx2zkR66OrdRDuVnU8ldvn3k/Ci/7Sf5nooKspQWimDnw337Bzt/yirqSThTjvrHkg==
dependencies:
"@types/node" "*"
"@types/d3-array@^2":
version "2.12.3"
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-2.12.3.tgz#8d16d51fb04ad5a5a8ebe14eb8263a579f1efdd1"
@ -4264,7 +4233,7 @@
"@types/lingui__core" "*"
"@types/react" "*"
"@types/lodash@^4.14.168", "@types/lodash@^4.14.172":
"@types/lodash@^4.14.172":
version "4.14.182"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2"
integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q==
@ -4422,11 +4391,6 @@
dependencies:
"@types/node" "*"
"@types/retry@*":
version "0.12.1"
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065"
integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==
"@types/scheduler@*":
version "0.16.2"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
@ -4459,11 +4423,6 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c"
integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==
"@types/stats-lite@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@types/stats-lite/-/stats-lite-2.2.0.tgz#bc8190bf9dfa1e16b89eaa2b433c99dff0804de9"
integrity sha512-YV6SS4QC+pbzqjMIV8qVSTDOOazgKBLTVaN+7PfuxELjz/eyzc20KwDVGPrbHt2OcYMA7K2ezLB45Cp6DpNOSQ==
"@types/styled-components@*", "@types/styled-components@^5.1.25":
version "5.1.25"
resolved "https://registry.yarnpkg.com/@types/styled-components/-/styled-components-5.1.25.tgz#0177c4ab5fa7c6ed0565d36f597393dae3f380ad"
@ -4742,10 +4701,10 @@
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.6", "@uniswap/router-sdk@^1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@uniswap/router-sdk/-/router-sdk-1.2.0.tgz#3dee393c422f531483d18f8bde29239fdaa8e153"
integrity sha512-LSA+Q8gNvYTudwaC1Sgnl7pZasLSheodpjZD6MYkcblusDdvw7fajv6AdJqOjHulsaQwr3WM3F+8JgThakeUPA==
"@uniswap/router-sdk@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@uniswap/router-sdk/-/router-sdk-1.3.0.tgz#8c17e957f65099a18dda536cd05fc34e779628aa"
integrity sha512-T6kXQFXrAkIHfCCmhyW+0xgUyuFVepL9rlwG9+MjnfVtmGIBssbMzyFKGk5HGQYlk6WQrm630W1j87kdfXpZ/Q==
dependencies:
"@ethersproject/abi" "^5.5.0"
"@uniswap/sdk-core" "^3.0.1"
@ -4765,21 +4724,14 @@
tiny-invariant "^1.1.0"
toformat "^2.0.0"
"@uniswap/smart-order-router@^2.8.2":
version "2.8.2"
resolved "https://registry.yarnpkg.com/@uniswap/smart-order-router/-/smart-order-router-2.8.2.tgz#cb521e1e02351ab18b35ca50f7a6c6f3eec2dc55"
integrity sha512-wV34O6QkRJPz52VClzCKmJ1wUY/WrIAC/L6oifySeJjqNh92xQ+HfNjZav+NPAjkz6GUD4UN4qCghi5wrR62ZA==
"@uniswap/smart-order-router@^2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@uniswap/smart-order-router/-/smart-order-router-2.9.2.tgz#3c9296b5b3821e191b6759a870330e4b10a9e9df"
integrity sha512-t+ruGvZTOvOJcVjxNPSU4o3GuPU/RYHr8KSKZlAHkZfusjbWrOLrO/aHzy/ncoRMNQz1UMBWQ2n3LDzqBxbTkA==
dependencies:
"@nomiclabs/hardhat-ethers" "^2.0.6"
"@types/async-retry" "^1.4.2"
"@types/await-timeout" "^0.3.1"
"@types/bunyan" "^1.8.6"
"@types/bunyan-blackhole" "^0.2.2"
"@types/lodash" "^4.14.168"
"@types/stats-lite" "^2.2.0"
"@uniswap/default-token-list" "^2.0.0"
"@uniswap/router-sdk" "^1.2.0"
"@uniswap/swap-router-contracts" "1.2.0"
"@uniswap/router-sdk" "^1.3.0"
"@uniswap/swap-router-contracts" "^1.3.0"
"@uniswap/token-lists" "^1.0.0-beta.25"
"@uniswap/v2-sdk" "^3.0.1"
"@uniswap/v3-sdk" "^3.7.0"
@ -4788,11 +4740,9 @@
axios "^0.21.1"
bunyan "^1.8.15"
bunyan-blackhole "^1.1.1"
bunyan-debug-stream "^2.0.0"
ethers "^5.6.1"
graphql "^15.5.0"
graphql-request "^3.4.0"
hardhat "^2.9.6"
lodash "^4.17.21"
mnemonist "^0.38.3"
node-cache "^5.1.2"
@ -4809,22 +4759,10 @@
"@uniswap/v3-periphery" "1.3.0"
hardhat-watcher "^2.1.1"
"@uniswap/swap-router-contracts@1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@uniswap/swap-router-contracts/-/swap-router-contracts-1.2.0.tgz#9fd3be07c40c697cf71804ab450ca7d6c028401d"
integrity sha512-wau6xVIrXY/7EQc3uB+A1HlRfxnewS4MAYOgcJBHGHG4OVy+X0WAl8mILC52Xx+y6vx6uQHOwH+sT3SaWi5EGw==
dependencies:
"@openzeppelin/contracts" "3.4.1-solc-0.7-2"
"@uniswap/v2-core" "1.0.1"
"@uniswap/v3-core" "1.0.0"
"@uniswap/v3-periphery" "1.3.0"
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==
"@uniswap/swap-router-contracts@^1.2.1", "@uniswap/swap-router-contracts@^1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@uniswap/swap-router-contracts/-/swap-router-contracts-1.3.0.tgz#8d555ca6d74b888d6e02a26ebb806ce315605f1f"
integrity sha512-iKvCuRkHXEe0EMjOf8HFUISTIhlxI57kKFllf3C3PUIE0HmwxrayyoflwAz5u/TRsFGYqJ9IjX2UgzLCsrNa5A==
dependencies:
"@openzeppelin/contracts" "3.4.2-solc-0.7"
"@uniswap/v2-core" "1.0.1"
@ -6956,14 +6894,6 @@ bunyan-blackhole@^1.1.1:
dependencies:
stream-blackhole "^1.0.3"
bunyan-debug-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-2.0.0.tgz#b9593e38753f594e3f9db3eb2fdebdc2af147a9f"
integrity sha512-Ovl43CJ7nUwalLzdXc6E1nGIy6ift9Z/QpYXUtsjpDAg35ZFKXifKNZyfpMGuN3N7ijLLqbnxPsMMHsXDdXa9A==
dependencies:
colors "^1.0.3"
exception-formatter "^1.0.4"
bunyan@^1.8.15:
version "1.8.15"
resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46"
@ -7621,7 +7551,7 @@ colorette@^1.2.1, colorette@^1.2.2:
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40"
integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==
colors@1.0.3, colors@^1.0.3:
colors@1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz"
integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=
@ -10016,13 +9946,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
md5.js "^1.3.4"
safe-buffer "^5.1.1"
exception-formatter@^1.0.4:
version "1.0.7"
resolved "https://registry.yarnpkg.com/exception-formatter/-/exception-formatter-1.0.7.tgz#3291616b86fceabefa97aee6a4708032c6e3b96d"
integrity sha512-zV45vEsjytJrwfGq6X9qd1Ll56cW4NC2mhCO6lqwMk4ZpA1fZ6C3UiaQM/X7if+7wZFmCgss3ahp9B/uVFuLRw==
dependencies:
colors "^1.0.3"
exec-sh@^0.3.2:
version "0.3.6"
resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc"