From 22b9daddab25068e97452a1ad79d8301f4424b48 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sat, 27 Apr 2024 03:28:14 +0000 Subject: [PATCH 1/4] init - data fetcher options - memoizer for fetching pools details --- packages/sushi/src/router/data-fetcher.ts | 24 ++- .../liquidity-providers/CurveProvider.ts | 52 ++++- .../liquidity-providers/LiquidityProvider.ts | 2 + .../src/router/liquidity-providers/Trident.ts | 173 ++++++++++------ .../liquidity-providers/UniswapV2Base.ts | 47 +++-- .../liquidity-providers/UniswapV3Base.ts | 189 ++++++++++++------ .../src/router/static-pool-fetcher/Trident.ts | 59 +++++- 7 files changed, 386 insertions(+), 160 deletions(-) diff --git a/packages/sushi/src/router/data-fetcher.ts b/packages/sushi/src/router/data-fetcher.ts index e6069096f2..8c88ee3d7e 100644 --- a/packages/sushi/src/router/data-fetcher.ts +++ b/packages/sushi/src/router/data-fetcher.ts @@ -29,6 +29,12 @@ import { UniswapV2Provider } from './liquidity-providers/UniswapV2.js' import { UniswapV3Provider } from './liquidity-providers/UniswapV3.js' import type { PoolCode } from './pool-codes/index.js' +// options for data fetching, such as pinning block number and memoize +export type DataFetcherOptions = { + blockNumber?: bigint, + memoize?: boolean +} + // TODO: Should be a mode on the config for DataFetcher const isTest = process.env['APP_ENV'] === 'test' || @@ -169,6 +175,7 @@ export class DataFetcher { currency0: Type, currency1: Type, excludePools?: Set, + options?: DataFetcherOptions, ): Promise { // console.log('PROVIDER COUNT', this.providers.length) // ensure that we only fetch the native wrap pools if the token is the native currency and wrapped native currency @@ -177,11 +184,14 @@ export class DataFetcher { (p) => p.getType() === LiquidityProviders.NativeWrap, ) if (provider) { - await provider.fetchPoolsForToken( - currency0.wrapped, - currency1.wrapped, - excludePools, - ) + try { + await provider.fetchPoolsForToken( + currency0.wrapped, + currency1.wrapped, + excludePools, + options + ) + } catch { /**/ } } } else { const [token0, token1] = @@ -189,9 +199,9 @@ export class DataFetcher { currency0.wrapped.sortsBefore(currency1.wrapped) ? [currency0.wrapped, currency1.wrapped] : [currency1.wrapped, currency0.wrapped] - await Promise.all( + await Promise.allSettled( this.providers.map((p) => - p.fetchPoolsForToken(token0, token1, excludePools), + p.fetchPoolsForToken(token0, token1, excludePools, options), ), ) } diff --git a/packages/sushi/src/router/liquidity-providers/CurveProvider.ts b/packages/sushi/src/router/liquidity-providers/CurveProvider.ts index 837f850d44..176b98a0a3 100644 --- a/packages/sushi/src/router/liquidity-providers/CurveProvider.ts +++ b/packages/sushi/src/router/liquidity-providers/CurveProvider.ts @@ -22,6 +22,8 @@ import { getCurrencyCombinations } from '../get-currency-combinations.js' import { CurvePoolCode } from '../pool-codes/CurvePool.js' import { PoolCode } from '../pool-codes/PoolCode.js' import { LiquidityProvider, LiquidityProviders } from './LiquidityProvider.js' +import { DataFetcherOptions } from '../data-fetcher.js' +import { memoizer } from '../memoizer.js' const stETH = new Token({ chainId: 1, @@ -379,9 +381,13 @@ export class CurveProvider extends LiquidityProvider { t0: Token, t1: Token, excludePools?: Set, + options?: DataFetcherOptions, ): Promise> { const pools: Map = new Map() let currencyCombinations = getCurrencyCombinations(this.chainId, t0, t1) + + const multicallMemoize = await memoizer.fn(this.client.multicall); + for (let i = 0; currencyCombinations.length > 0; ++i) { const calls = (CURVE_FACTORY_ADDRESSES[this.chainId] ?? []).flatMap( (factory) => @@ -397,12 +403,25 @@ export class CurveProvider extends LiquidityProvider { ] as const, })), ) - const newFoundPools = await this.client.multicall({ + const newfoundPoolsData = { multicallAddress: this.client.chain?.contracts?.multicall3 ?.address as '0x${string}', allowFailure: true, + blockNumber: options?.blockNumber, contracts: calls, - }) + } + const newFoundPools: ({ + error?: undefined; + result: `0x${string}`; + status: "success"; + } | { + error: Error; + result?: undefined; + status: "failure"; + })[] = options?.memoize + ? await multicallMemoize(newfoundPoolsData) as any + : await this.client.multicall(newfoundPoolsData) + newFoundPools.forEach((pool, i) => { if ( pool.status === 'success' && @@ -429,12 +448,16 @@ export class CurveProvider extends LiquidityProvider { async getPoolRatio( pools: [string, [CurvePoolType, Type[]]][], + options?: DataFetcherOptions, ): Promise<(number[] | undefined)[]> { if (this.chainId === ChainId.ETHEREUM) { - const ratios = await this.client.multicall({ + const multicallMemoize = await memoizer.fn(this.client.multicall); + + const ratiosData = { multicallAddress: this.client.chain?.contracts?.multicall3 ?.address as '0x${string}', allowFailure: true, + blockNumber: options?.blockNumber, contracts: [ { address: '0xE95A203B1a91a908F9B9CE46459d101078c2c3cb', // ankr @@ -467,7 +490,11 @@ export class CurveProvider extends LiquidityProvider { functionName: 'exchangeRateCurrent', }, ], - }) + } as any + const ratios = options?.memoize + ? await multicallMemoize(ratiosData) as any + : await this.client.multicall(ratiosData) + return pools.map(([poolAddress]) => { // collection of freaks switch (poolAddress.toLowerCase()) { @@ -498,9 +525,10 @@ export class CurveProvider extends LiquidityProvider { async getCurvePoolCodes( pools: Map, + options?: DataFetcherOptions, ): Promise { const poolArray = Array.from(pools.entries()) - const poolsMulticall = < + const poolsMulticall = async < T extends ContractFunctionParameters< (typeof curvePoolABI)[keyof typeof curvePoolABI] >['functionName'], @@ -512,10 +540,12 @@ export class CurveProvider extends LiquidityProvider { T >['args'], ) => { - return this.client.multicall({ + const multicallMemoize = await memoizer.fn(this.client.multicall); + const data = { multicallAddress: this.client.chain?.contracts?.multicall3 ?.address as '0x${string}', allowFailure: true, + blockNumber: options?.blockNumber, contracts: poolArray.map(([address, [poolType]]) => ({ address: address as Address, // //chainId: this.chainId, @@ -523,7 +553,10 @@ export class CurveProvider extends LiquidityProvider { functionName: functionName, args, })) as any, - }) + } as any + return options?.memoize + ? multicallMemoize(data) as any + : this.client.multicall(data) } // const poolContract = getContract({ // address: poolAddress as '0x${string}', @@ -581,9 +614,10 @@ export class CurveProvider extends LiquidityProvider { t0: Token, t1: Token, excludePools?: Set, + options?: DataFetcherOptions, ): Promise { - const pools = await this.getPoolsForTokens(t0, t1, excludePools) - this.foundPools = await this.getCurvePoolCodes(pools) + const pools = await this.getPoolsForTokens(t0, t1, excludePools, options) + this.foundPools = await this.getCurvePoolCodes(pools, options) //console.log(JSON.stringify(this.foundPools, undefined, ' ')) } diff --git a/packages/sushi/src/router/liquidity-providers/LiquidityProvider.ts b/packages/sushi/src/router/liquidity-providers/LiquidityProvider.ts index 59e73d54d4..ae726a2f66 100644 --- a/packages/sushi/src/router/liquidity-providers/LiquidityProvider.ts +++ b/packages/sushi/src/router/liquidity-providers/LiquidityProvider.ts @@ -2,6 +2,7 @@ import { PublicClient } from 'viem' import { ChainId, chainShortName } from '../../chain/index.js' import type { Token } from '../../currency/index.js' import type { PoolCode } from '../pool-codes/index.js' +import { DataFetcherOptions } from '../data-fetcher.js' export enum LiquidityProviders { SushiSwapV2 = 'SushiSwapV2', @@ -79,6 +80,7 @@ export abstract class LiquidityProvider { t0: Token, t1: Token, excludePools?: Set, + options?: DataFetcherOptions ): Promise /** diff --git a/packages/sushi/src/router/liquidity-providers/Trident.ts b/packages/sushi/src/router/liquidity-providers/Trident.ts index bfaf64e0c2..8d4e1c1b22 100644 --- a/packages/sushi/src/router/liquidity-providers/Trident.ts +++ b/packages/sushi/src/router/liquidity-providers/Trident.ts @@ -39,6 +39,8 @@ import { TridentStaticPoolFetcher, } from '../static-pool-fetcher/Trident.js' import { LiquidityProvider, LiquidityProviders } from './LiquidityProvider.js' +import { DataFetcherOptions } from '../data-fetcher.js' +import { memoizer } from '../memoizer.js' export function convertToNumbers(arr: bigint[]): (number | undefined)[] { return arr.map((a) => { @@ -577,6 +579,7 @@ export class TridentProvider extends LiquidityProvider { t0: Token, t1: Token, excludePools?: Set, + options?: DataFetcherOptions, ): Promise { const topPoolAddresses = [ ...Array.from(this.topClassicPools.keys()), @@ -609,6 +612,7 @@ export class TridentProvider extends LiquidityProvider { this.chainId, t0, t1, + options ) if (excludePools) onDemandClassicPools = (onDemandClassicPools as PoolResponse2[]).filter( @@ -723,21 +727,34 @@ export class TridentProvider extends LiquidityProvider { } }) - const classicReservePromise = this.client - .multicall({ - multicallAddress: this.client.chain?.contracts?.multicall3 - ?.address as Address, - allowFailure: true, - contracts: classicPoolCodesToCreate.map( - (pc) => - ({ - address: pc.pool.address as Address, - chainId: this.chainId, - abi: getReservesAbi, - functionName: 'getReserves', - }) as const, - ), + const multicallMemoize = await memoizer.fn(this.client.multicall); + + const classicReservesPromiseData = { + multicallAddress: this.client.chain?.contracts?.multicall3 + ?.address as Address, + allowFailure: true, + blockNumber: options?.blockNumber, + contracts: classicPoolCodesToCreate.map( + (pc) => + ({ + address: pc.pool.address as Address, + chainId: this.chainId, + abi: getReservesAbi, + functionName: 'getReserves', + }) as const, + ), + } + const classicReservePromise = options?.memoize + ? (multicallMemoize(classicReservesPromiseData) as Promise) + .catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined }) + : this.client.multicall(classicReservesPromiseData) .catch((e) => { console.warn( `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ @@ -747,21 +764,32 @@ export class TridentProvider extends LiquidityProvider { return undefined }) - const stableReservePromise = this.client - .multicall({ - multicallAddress: this.client.chain?.contracts?.multicall3 - ?.address as Address, - allowFailure: true, - contracts: stablePoolCodesToCreate.map( - (pc) => - ({ - address: pc.pool.address as Address, - chainId: this.chainId, - abi: getStableReservesAbi, - functionName: 'getReserves', - }) as const, - ), + const stableReservePromiseData = { + multicallAddress: this.client.chain?.contracts?.multicall3 + ?.address as Address, + allowFailure: true, + blockNumber: options?.blockNumber, + contracts: stablePoolCodesToCreate.map( + (pc) => + ({ + address: pc.pool.address as Address, + chainId: this.chainId, + abi: getStableReservesAbi, + functionName: 'getReserves', + }) as const, + ), + } + const stableReservePromise = options?.memoize + ? (multicallMemoize(stableReservePromiseData) as Promise) + .catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined }) + : this.client.multicall(stableReservePromiseData) .catch((e) => { console.warn( `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ @@ -771,24 +799,35 @@ export class TridentProvider extends LiquidityProvider { return undefined }) - const totalsPromise = this.client - .multicall({ - multicallAddress: this.client.chain?.contracts?.multicall3 - ?.address as Address, - allowFailure: true, - contracts: bridgesToCreate.map( - (b) => - ({ - args: [b.pool.token0.address as Address], - address: this.bentoBox[ - this.chainId as BentoBoxChainId - ] as Address, - chainId: this.chainId, - abi: totalsAbi, - functionName: 'totals', - }) as const, - ), + const totalsPromiseData = { + multicallAddress: this.client.chain?.contracts?.multicall3 + ?.address as Address, + allowFailure: true, + blockNumber: options?.blockNumber, + contracts: bridgesToCreate.map( + (b) => + ({ + args: [b.pool.token0.address as Address], + address: this.bentoBox[ + this.chainId as BentoBoxChainId + ] as Address, + chainId: this.chainId, + abi: totalsAbi, + functionName: 'totals', + }) as const, + ), + } + const totalsPromise = options?.memoize + ? (multicallMemoize(totalsPromiseData) as Promise) + .catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined }) + : this.client.multicall(totalsPromiseData) .catch((e) => { console.warn( `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ @@ -798,22 +837,33 @@ export class TridentProvider extends LiquidityProvider { return undefined }) - const balancesPromise = this.client - .multicall({ - multicallAddress: this.client.chain?.contracts?.multicall3 - ?.address as Address, - allowFailure: true, - contracts: bridgesToCreate.map( - (b) => - ({ - args: [this.bentoBox[this.chainId as BentoBoxChainId] as Address], - address: b.pool.token0.address as Address, - chainId: this.chainId, - abi: balanceOfAbi, - functionName: 'balanceOf', - }) as const, - ), + const balancesPromiseData = { + multicallAddress: this.client.chain?.contracts?.multicall3 + ?.address as Address, + allowFailure: true, + blockNumber: options?.blockNumber, + contracts: bridgesToCreate.map( + (b) => + ({ + args: [this.bentoBox[this.chainId as BentoBoxChainId] as Address], + address: b.pool.token0.address as Address, + chainId: this.chainId, + abi: balanceOfAbi, + functionName: 'balanceOf', + }) as const, + ), + } + const balancesPromise = options?.memoize + ? (multicallMemoize(balancesPromiseData) as Promise) + .catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined }) + : this.client.multicall(balancesPromiseData) .catch((e) => { console.warn( `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ @@ -1139,8 +1189,9 @@ export class TridentProvider extends LiquidityProvider { t0: Token, t1: Token, excludePools?: Set, + options?: DataFetcherOptions, ): Promise { - await this.getOnDemandPools(t0, t1, excludePools) + await this.getOnDemandPools(t0, t1, excludePools, options) } getCurrentPoolList(t0: Token, t1: Token): PoolCode[] { diff --git a/packages/sushi/src/router/liquidity-providers/UniswapV2Base.ts b/packages/sushi/src/router/liquidity-providers/UniswapV2Base.ts index d9d31ec9b7..09c7bc06ad 100644 --- a/packages/sushi/src/router/liquidity-providers/UniswapV2Base.ts +++ b/packages/sushi/src/router/liquidity-providers/UniswapV2Base.ts @@ -18,6 +18,8 @@ import { } from '../lib/api.js' import { ConstantProductPoolCode, type PoolCode } from '../pool-codes/index.js' import { LiquidityProvider } from './LiquidityProvider.js' +import { memoizer } from '../memoizer.js' +import { DataFetcherOptions } from '../data-fetcher.js' interface PoolInfo { poolCode: PoolCode @@ -160,6 +162,7 @@ export abstract class UniswapV2BaseProvider extends LiquidityProvider { t0: Token, t1: Token, excludePools?: Set, + options?: DataFetcherOptions, ): Promise { const topPoolAddresses = Array.from(this.topPools.keys()) let pools = @@ -219,21 +222,34 @@ export abstract class UniswapV2BaseProvider extends LiquidityProvider { } }) - const reserves = await this.client - .multicall({ - multicallAddress: this.client.chain?.contracts?.multicall3 - ?.address as Address, - allowFailure: true, - contracts: poolCodesToCreate.map( - (poolCode) => - ({ - address: poolCode.pool.address as Address, - chainId: this.chainId, - abi: getReservesAbi, - functionName: 'getReserves', - }) as const, - ), + const multicallMemoize = await memoizer.fn(this.client.multicall); + + const multicallData = { + multicallAddress: this.client.chain?.contracts?.multicall3 + ?.address as Address, + allowFailure: true, + blockNumber: options?.blockNumber, + contracts: poolCodesToCreate.map( + (poolCode) => + ({ + address: poolCode.pool.address as Address, + chainId: this.chainId, + abi: getReservesAbi, + functionName: 'getReserves', + }) as const, + ), + } + const reserves = options?.memoize + ? await (multicallMemoize(multicallData) as Promise) + .catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: on-demand pools multicall failed, message: ${ + e.message + }`, + ) + return undefined }) + : await this.client.multicall(multicallData) .catch((e) => { console.warn( `${this.getLogPrefix()} - UPDATE: on-demand pools multicall failed, message: ${ @@ -536,8 +552,9 @@ export abstract class UniswapV2BaseProvider extends LiquidityProvider { t0: Token, t1: Token, excludePools?: Set, + options?: DataFetcherOptions, ): Promise { - await this.getOnDemandPools(t0, t1, excludePools) + await this.getOnDemandPools(t0, t1, excludePools, options) } /** diff --git a/packages/sushi/src/router/liquidity-providers/UniswapV3Base.ts b/packages/sushi/src/router/liquidity-providers/UniswapV3Base.ts index c3ab1201b7..36584a19a3 100644 --- a/packages/sushi/src/router/liquidity-providers/UniswapV3Base.ts +++ b/packages/sushi/src/router/liquidity-providers/UniswapV3Base.ts @@ -8,6 +8,8 @@ import { RToken, UniV3Pool } from '../../tines/index.js' import { getCurrencyCombinations } from '../get-currency-combinations.js' import { type PoolCode, UniV3PoolCode } from '../pool-codes/index.js' import { LiquidityProvider } from './LiquidityProvider.js' +import { DataFetcherOptions } from '../data-fetcher.js' +import { memoizer } from '../memoizer.js' interface StaticPool { address: Address @@ -78,62 +80,76 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { t0: Token, t1: Token, excludePools?: Set | PoolFilter, + options?: DataFetcherOptions, ): Promise { let staticPools = this.getStaticPools(t0, t1) if (excludePools) staticPools = staticPools.filter((p) => !excludePools.has(p.address)) - const slot0 = await this.client - .multicall({ - multicallAddress: this.client.chain?.contracts?.multicall3 - ?.address as Address, - allowFailure: true, - contracts: staticPools.map( - (pool) => - ({ - address: pool.address as Address, - chainId: this.chainId, - abi: [ - { - inputs: [], - name: 'slot0', - outputs: [ - { - internalType: 'uint160', - name: 'sqrtPriceX96', - type: 'uint160', - }, - { internalType: 'int24', name: 'tick', type: 'int24' }, - { - internalType: 'uint16', - name: 'observationIndex', - type: 'uint16', - }, - { - internalType: 'uint16', - name: 'observationCardinality', - type: 'uint16', - }, - { - internalType: 'uint16', - name: 'observationCardinalityNext', - type: 'uint16', - }, - { - internalType: 'uint8', - name: 'feeProtocol', - type: 'uint8', - }, - { internalType: 'bool', name: 'unlocked', type: 'bool' }, - ], - stateMutability: 'view', - type: 'function', - }, - ], - functionName: 'slot0', - }) as const, - ), + const multicallMemoize = await memoizer.fn(this.client.multicall); + + const slot0Data = { + multicallAddress: this.client.chain?.contracts?.multicall3 + ?.address as Address, + allowFailure: true, + blockNumber: options?.blockNumber, + contracts: staticPools.map( + (pool) => + ({ + address: pool.address as Address, + chainId: this.chainId, + abi: [ + { + inputs: [], + name: 'slot0', + outputs: [ + { + internalType: 'uint160', + name: 'sqrtPriceX96', + type: 'uint160', + }, + { internalType: 'int24', name: 'tick', type: 'int24' }, + { + internalType: 'uint16', + name: 'observationIndex', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'observationCardinality', + type: 'uint16', + }, + { + internalType: 'uint16', + name: 'observationCardinalityNext', + type: 'uint16', + }, + { + internalType: 'uint8', + name: 'feeProtocol', + type: 'uint8', + }, + { internalType: 'bool', name: 'unlocked', type: 'bool' }, + ], + stateMutability: 'view', + type: 'function', + }, + ], + functionName: 'slot0', + }) as const, + ), + } + const slot0 = options?.memoize + ? await (multicallMemoize(slot0Data) as Promise) + .catch((e) => { + console.warn( + `${this.getLogPrefix()} - INIT: multicall failed, message: ${ + e.message + }`, + ) + return undefined }) + : await this.client.multicall(slot0Data) .catch((e) => { console.warn( `${this.getLogPrefix()} - INIT: multicall failed, message: ${ @@ -162,10 +178,11 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { if (existingPools.length === 0) return - const liquidityContracts = this.client.multicall({ + const liquidityContractsData = { multicallAddress: this.client.chain?.contracts?.multicall3 ?.address as Address, allowFailure: true, + blockNumber: options?.blockNumber, contracts: existingPools.map( (pool) => ({ @@ -185,12 +202,24 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { functionName: 'liquidity', }) as const, ), - }) - - const token0Contracts = this.client.multicall({ + } + const liquidityContracts: Promise<({ + error?: undefined; + result: bigint; + status: "success"; + } | { + error: Error; + result?: undefined; + status: "failure"; + })[]> = options?.memoize + ? multicallMemoize(liquidityContractsData) as Promise + : this.client.multicall(liquidityContractsData) + + const token0ContractsData = { multicallAddress: this.client.chain?.contracts?.multicall3 ?.address as Address, allowFailure: true, + blockNumber: options?.blockNumber, contracts: existingPools.map( (pool) => ({ @@ -201,12 +230,24 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { functionName: 'balanceOf', }) as const, ), - }) - - const token1Contracts = this.client.multicall({ + } + const token0Contracts: Promise<({ + error: Error; + result?: undefined; + status: "failure"; + } | { + error?: undefined; + result: bigint; + status: "success"; + })[]> = options?.memoize + ? multicallMemoize(token0ContractsData) as Promise + : this.client.multicall(token0ContractsData) + + const token1ContractsData = { multicallAddress: this.client.chain?.contracts?.multicall3 ?.address as Address, allowFailure: true, + blockNumber: options?.blockNumber, contracts: existingPools.map( (pool) => ({ @@ -217,7 +258,18 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { functionName: 'balanceOf', }) as const, ), - }) + } + const token1Contracts: Promise<({ + error?: undefined; + result: bigint; + status: "success"; + } | { + error: Error; + result?: undefined; + status: "failure"; + })[]> = options?.memoize + ? multicallMemoize(token1ContractsData) as Promise + : this.client.multicall(token1ContractsData) const minIndexes = existingPools.map((pool) => bitmapIndex( @@ -242,6 +294,7 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { ).flatMap((j) => ({ chainId: this.chainId, address: this.tickLens[ + // @ts-ignore this.chainId as keyof typeof this.tickLens ] as Address, args: [pool.address, j] as const, @@ -251,12 +304,28 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { })) }) - const ticksContracts = this.client.multicall({ + const ticksContractsData = { multicallAddress: this.client.chain?.contracts?.multicall3 ?.address as Address, allowFailure: true, contracts: wordList, - }) + blockNumber: options?.blockNumber, + } + const ticksContracts: Promise<({ + error?: undefined; + result: readonly { + tick: number; + liquidityNet: bigint; + liquidityGross: bigint; + }[]; + status: "success"; + } | { + error: Error; + result?: undefined; + status: "failure"; + })[]> = options?.memoize + ? multicallMemoize(ticksContractsData) as Promise + : this.client.multicall(ticksContractsData) const [liquidityResults, token0Balances, token1Balances, tickResults] = await Promise.all([ diff --git a/packages/sushi/src/router/static-pool-fetcher/Trident.ts b/packages/sushi/src/router/static-pool-fetcher/Trident.ts index ecd3038b7e..05851f6ae2 100644 --- a/packages/sushi/src/router/static-pool-fetcher/Trident.ts +++ b/packages/sushi/src/router/static-pool-fetcher/Trident.ts @@ -12,6 +12,8 @@ import { } from '../../config/index.js' import { Currency, Token } from '../../currency/index.js' import { getCurrencyCombinations } from '../get-currency-combinations.js' +import { DataFetcherOptions } from '../data-fetcher.js' +import { memoizer } from '../memoizer.js' export interface TridentStaticPool { address: Address @@ -27,10 +29,11 @@ export class TridentStaticPoolFetcher { chainId: ChainId, t1: Token, t2: Token, + options?: DataFetcherOptions, ): Promise<[TridentStaticPool[], TridentStaticPool[]]> { const pools = await Promise.all([ - this.getPools(client, chainId, t1, t2, 'CONSTANT_PRODUCT_POOL'), - this.getPools(client, chainId, t1, t2, 'STABLE_POOL'), + this.getPools(client, chainId, t1, t2, 'CONSTANT_PRODUCT_POOL', options), + this.getPools(client, chainId, t1, t2, 'STABLE_POOL', options), ]) return pools @@ -42,6 +45,7 @@ export class TridentStaticPoolFetcher { t1: Token, t2: Token, type: 'STABLE_POOL' | 'CONSTANT_PRODUCT_POOL', + options?: DataFetcherOptions, ) { const currencies = getCurrencyCombinations(chainId, t1, t2) @@ -59,9 +63,12 @@ export class TridentStaticPoolFetcher { chainId as TridentChainId ] as Address) - const callStatePoolsCount = await client.multicall({ + const multicallMemoize = await memoizer.fn(client.multicall); + + const callStatePoolsCountData = { multicallAddress: client.chain?.contracts?.multicall3?.address as Address, allowFailure: true, + blockNumber: options?.blockNumber, contracts: _pairsUniqueAddr.map( (el) => ({ @@ -72,7 +79,18 @@ export class TridentStaticPoolFetcher { args: el as [Address, Address], }) as const, ), - }) + } + const callStatePoolsCount: ({ + error?: undefined; + result: bigint; + status: "success"; + } | { + error: Error; + result?: undefined; + status: "failure"; + })[] = options?.memoize + ? await (multicallMemoize(callStatePoolsCountData) as Promise) + : await client.multicall(callStatePoolsCountData) const callStatePoolsCountProcessed = callStatePoolsCount ?.map( @@ -104,9 +122,10 @@ export class TridentStaticPoolFetcher { .filter(([, length]) => length) .map(([i]) => [_pairsUnique[i]![0], _pairsUnique[i]![1]]) - const callStatePools = await client.multicall({ + const callStatePoolsData = { multicallAddress: client.chain?.contracts?.multicall3?.address as Address, allowFailure: true, + blockNumber: options?.blockNumber, contracts: callStatePoolsCountProcessed.map( (args) => ({ @@ -117,7 +136,18 @@ export class TridentStaticPoolFetcher { args, }) as const, ), - }) + } + const callStatePools: ({ + error?: undefined; + result: readonly `0x${string}`[]; + status: "success"; + } | { + error: Error; + result?: undefined; + status: "failure"; + })[] = options?.memoize + ? await (multicallMemoize(callStatePoolsData) as Promise) + : await client.multicall(callStatePoolsData) const pools: TridentStaticPool[] = [] callStatePools.forEach((s, i) => { @@ -134,9 +164,10 @@ export class TridentStaticPoolFetcher { const poolsAddresses = pools.map((p) => p.address) - const fees = await client.multicall({ + const feesData = { multicallAddress: client.chain?.contracts?.multicall3?.address as Address, allowFailure: true, + blockNumber: options?.blockNumber, contracts: poolsAddresses.map( (address) => ({ @@ -146,7 +177,19 @@ export class TridentStaticPoolFetcher { functionName: 'swapFee', }) as const, ), - }) + } + const fees: ({ + error?: undefined; + result: bigint; + status: "success"; + } | { + error: Error; + result?: undefined; + status: "failure"; + })[] = options?.memoize + ? await (multicallMemoize(feesData) as Promise) + : await client.multicall(feesData) + const results: TridentStaticPool[] = [] pools.forEach((p, i) => { From 331aa98a4f2c0c6bbacb94b6af6a6ae9f7a7d3bd Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sat, 27 Apr 2024 03:32:50 +0000 Subject: [PATCH 2/4] lint --- packages/sushi/src/router/data-fetcher.ts | 8 +- .../liquidity-providers/CurveProvider.ts | 39 ++-- .../liquidity-providers/LiquidityProvider.ts | 4 +- .../src/router/liquidity-providers/Trident.ts | 148 ++++++++------- .../liquidity-providers/UniswapV2Base.ts | 42 +++-- .../liquidity-providers/UniswapV3Base.ts | 148 ++++++++------- .../src/router/static-pool-fetcher/Trident.ts | 69 +++---- packages/sushi/test/tines/snapshots/report | 169 ++---------------- 8 files changed, 251 insertions(+), 376 deletions(-) diff --git a/packages/sushi/src/router/data-fetcher.ts b/packages/sushi/src/router/data-fetcher.ts index 8c88ee3d7e..74c88a6249 100644 --- a/packages/sushi/src/router/data-fetcher.ts +++ b/packages/sushi/src/router/data-fetcher.ts @@ -31,7 +31,7 @@ import type { PoolCode } from './pool-codes/index.js' // options for data fetching, such as pinning block number and memoize export type DataFetcherOptions = { - blockNumber?: bigint, + blockNumber?: bigint memoize?: boolean } @@ -189,9 +189,11 @@ export class DataFetcher { currency0.wrapped, currency1.wrapped, excludePools, - options + options, ) - } catch { /**/ } + } catch { + /**/ + } } } else { const [token0, token1] = diff --git a/packages/sushi/src/router/liquidity-providers/CurveProvider.ts b/packages/sushi/src/router/liquidity-providers/CurveProvider.ts index 176b98a0a3..4c80ac4bec 100644 --- a/packages/sushi/src/router/liquidity-providers/CurveProvider.ts +++ b/packages/sushi/src/router/liquidity-providers/CurveProvider.ts @@ -18,12 +18,12 @@ import { } from '../../currency/index.js' import { Native, Token, Type } from '../../currency/index.js' import { RToken, createCurvePoolsForMultipool } from '../../tines/index.js' +import { DataFetcherOptions } from '../data-fetcher.js' import { getCurrencyCombinations } from '../get-currency-combinations.js' +import { memoizer } from '../memoizer.js' import { CurvePoolCode } from '../pool-codes/CurvePool.js' import { PoolCode } from '../pool-codes/PoolCode.js' import { LiquidityProvider, LiquidityProviders } from './LiquidityProvider.js' -import { DataFetcherOptions } from '../data-fetcher.js' -import { memoizer } from '../memoizer.js' const stETH = new Token({ chainId: 1, @@ -386,8 +386,8 @@ export class CurveProvider extends LiquidityProvider { const pools: Map = new Map() let currencyCombinations = getCurrencyCombinations(this.chainId, t0, t1) - const multicallMemoize = await memoizer.fn(this.client.multicall); - + const multicallMemoize = await memoizer.fn(this.client.multicall) + for (let i = 0; currencyCombinations.length > 0; ++i) { const calls = (CURVE_FACTORY_ADDRESSES[this.chainId] ?? []).flatMap( (factory) => @@ -410,16 +410,19 @@ export class CurveProvider extends LiquidityProvider { blockNumber: options?.blockNumber, contracts: calls, } - const newFoundPools: ({ - error?: undefined; - result: `0x${string}`; - status: "success"; - } | { - error: Error; - result?: undefined; - status: "failure"; - })[] = options?.memoize - ? await multicallMemoize(newfoundPoolsData) as any + const newFoundPools: ( + | { + error?: undefined + result: `0x${string}` + status: 'success' + } + | { + error: Error + result?: undefined + status: 'failure' + } + )[] = options?.memoize + ? ((await multicallMemoize(newfoundPoolsData)) as any) : await this.client.multicall(newfoundPoolsData) newFoundPools.forEach((pool, i) => { @@ -451,7 +454,7 @@ export class CurveProvider extends LiquidityProvider { options?: DataFetcherOptions, ): Promise<(number[] | undefined)[]> { if (this.chainId === ChainId.ETHEREUM) { - const multicallMemoize = await memoizer.fn(this.client.multicall); + const multicallMemoize = await memoizer.fn(this.client.multicall) const ratiosData = { multicallAddress: this.client.chain?.contracts?.multicall3 @@ -492,7 +495,7 @@ export class CurveProvider extends LiquidityProvider { ], } as any const ratios = options?.memoize - ? await multicallMemoize(ratiosData) as any + ? ((await multicallMemoize(ratiosData)) as any) : await this.client.multicall(ratiosData) return pools.map(([poolAddress]) => { @@ -540,7 +543,7 @@ export class CurveProvider extends LiquidityProvider { T >['args'], ) => { - const multicallMemoize = await memoizer.fn(this.client.multicall); + const multicallMemoize = await memoizer.fn(this.client.multicall) const data = { multicallAddress: this.client.chain?.contracts?.multicall3 ?.address as '0x${string}', @@ -555,7 +558,7 @@ export class CurveProvider extends LiquidityProvider { })) as any, } as any return options?.memoize - ? multicallMemoize(data) as any + ? (multicallMemoize(data) as any) : this.client.multicall(data) } // const poolContract = getContract({ diff --git a/packages/sushi/src/router/liquidity-providers/LiquidityProvider.ts b/packages/sushi/src/router/liquidity-providers/LiquidityProvider.ts index ae726a2f66..289465fb94 100644 --- a/packages/sushi/src/router/liquidity-providers/LiquidityProvider.ts +++ b/packages/sushi/src/router/liquidity-providers/LiquidityProvider.ts @@ -1,8 +1,8 @@ import { PublicClient } from 'viem' import { ChainId, chainShortName } from '../../chain/index.js' import type { Token } from '../../currency/index.js' -import type { PoolCode } from '../pool-codes/index.js' import { DataFetcherOptions } from '../data-fetcher.js' +import type { PoolCode } from '../pool-codes/index.js' export enum LiquidityProviders { SushiSwapV2 = 'SushiSwapV2', @@ -80,7 +80,7 @@ export abstract class LiquidityProvider { t0: Token, t1: Token, excludePools?: Set, - options?: DataFetcherOptions + options?: DataFetcherOptions, ): Promise /** diff --git a/packages/sushi/src/router/liquidity-providers/Trident.ts b/packages/sushi/src/router/liquidity-providers/Trident.ts index 8d4e1c1b22..c8620ff678 100644 --- a/packages/sushi/src/router/liquidity-providers/Trident.ts +++ b/packages/sushi/src/router/liquidity-providers/Trident.ts @@ -23,12 +23,14 @@ import { convertTokenToBento, toShareBI, } from '../../tines/index.js' +import { DataFetcherOptions } from '../data-fetcher.js' import { PoolResponse2, filterOnDemandPools, filterTopPools, mapToken, } from '../lib/api.js' +import { memoizer } from '../memoizer.js' import { BentoBridgePoolCode, BentoPoolCode, @@ -39,8 +41,6 @@ import { TridentStaticPoolFetcher, } from '../static-pool-fetcher/Trident.js' import { LiquidityProvider, LiquidityProviders } from './LiquidityProvider.js' -import { DataFetcherOptions } from '../data-fetcher.js' -import { memoizer } from '../memoizer.js' export function convertToNumbers(arr: bigint[]): (number | undefined)[] { return arr.map((a) => { @@ -612,7 +612,7 @@ export class TridentProvider extends LiquidityProvider { this.chainId, t0, t1, - options + options, ) if (excludePools) onDemandClassicPools = (onDemandClassicPools as PoolResponse2[]).filter( @@ -727,7 +727,7 @@ export class TridentProvider extends LiquidityProvider { } }) - const multicallMemoize = await memoizer.fn(this.client.multicall); + const multicallMemoize = await memoizer.fn(this.client.multicall) const classicReservesPromiseData = { multicallAddress: this.client.chain?.contracts?.multicall3 @@ -745,24 +745,24 @@ export class TridentProvider extends LiquidityProvider { ), } const classicReservePromise = options?.memoize - ? (multicallMemoize(classicReservesPromiseData) as Promise) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) - : this.client.multicall(classicReservesPromiseData) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ - e.message - }`, + ? (multicallMemoize(classicReservesPromiseData) as Promise).catch( + (e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }, ) - return undefined - }) + : this.client.multicall(classicReservesPromiseData).catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) const stableReservePromiseData = { multicallAddress: this.client.chain?.contracts?.multicall3 @@ -780,24 +780,24 @@ export class TridentProvider extends LiquidityProvider { ), } const stableReservePromise = options?.memoize - ? (multicallMemoize(stableReservePromiseData) as Promise) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ - e.message - }`, + ? (multicallMemoize(stableReservePromiseData) as Promise).catch( + (e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }, ) - return undefined - }) - : this.client.multicall(stableReservePromiseData) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) + : this.client.multicall(stableReservePromiseData).catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) const totalsPromiseData = { multicallAddress: this.client.chain?.contracts?.multicall3 @@ -808,9 +808,7 @@ export class TridentProvider extends LiquidityProvider { (b) => ({ args: [b.pool.token0.address as Address], - address: this.bentoBox[ - this.chainId as BentoBoxChainId - ] as Address, + address: this.bentoBox[this.chainId as BentoBoxChainId] as Address, chainId: this.chainId, abi: totalsAbi, functionName: 'totals', @@ -818,24 +816,22 @@ export class TridentProvider extends LiquidityProvider { ), } const totalsPromise = options?.memoize - ? (multicallMemoize(totalsPromiseData) as Promise) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) - : this.client.multicall(totalsPromiseData) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) + ? (multicallMemoize(totalsPromiseData) as Promise).catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) + : this.client.multicall(totalsPromiseData).catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) const balancesPromiseData = { multicallAddress: this.client.chain?.contracts?.multicall3 @@ -854,24 +850,22 @@ export class TridentProvider extends LiquidityProvider { ), } const balancesPromise = options?.memoize - ? (multicallMemoize(balancesPromiseData) as Promise) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) - : this.client.multicall(balancesPromiseData) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) + ? (multicallMemoize(balancesPromiseData) as Promise).catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) + : this.client.multicall(balancesPromiseData).catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) const [classicReserves, stableReserves, totals, balances] = await Promise.all([ diff --git a/packages/sushi/src/router/liquidity-providers/UniswapV2Base.ts b/packages/sushi/src/router/liquidity-providers/UniswapV2Base.ts index 09c7bc06ad..e46987fb8d 100644 --- a/packages/sushi/src/router/liquidity-providers/UniswapV2Base.ts +++ b/packages/sushi/src/router/liquidity-providers/UniswapV2Base.ts @@ -9,6 +9,7 @@ import { } from '../../config/index.js' import { Token } from '../../currency/index.js' import { ConstantProductRPool, RToken } from '../../tines/index.js' +import { DataFetcherOptions } from '../data-fetcher.js' import { getCurrencyCombinations } from '../get-currency-combinations.js' import { PoolResponse2, @@ -16,10 +17,9 @@ import { filterTopPools, mapToken, } from '../lib/api.js' +import { memoizer } from '../memoizer.js' import { ConstantProductPoolCode, type PoolCode } from '../pool-codes/index.js' import { LiquidityProvider } from './LiquidityProvider.js' -import { memoizer } from '../memoizer.js' -import { DataFetcherOptions } from '../data-fetcher.js' interface PoolInfo { poolCode: PoolCode @@ -222,7 +222,7 @@ export abstract class UniswapV2BaseProvider extends LiquidityProvider { } }) - const multicallMemoize = await memoizer.fn(this.client.multicall); + const multicallMemoize = await memoizer.fn(this.client.multicall) const multicallData = { multicallAddress: this.client.chain?.contracts?.multicall3 @@ -239,25 +239,23 @@ export abstract class UniswapV2BaseProvider extends LiquidityProvider { }) as const, ), } - const reserves = options?.memoize - ? await (multicallMemoize(multicallData) as Promise) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: on-demand pools multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) - : await this.client.multicall(multicallData) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - UPDATE: on-demand pools multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) + const reserves = options?.memoize + ? await (multicallMemoize(multicallData) as Promise).catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: on-demand pools multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) + : await this.client.multicall(multicallData).catch((e) => { + console.warn( + `${this.getLogPrefix()} - UPDATE: on-demand pools multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) poolCodesToCreate.forEach((poolCode, i) => { const pool = poolCode.pool diff --git a/packages/sushi/src/router/liquidity-providers/UniswapV3Base.ts b/packages/sushi/src/router/liquidity-providers/UniswapV3Base.ts index 36584a19a3..334f8328ab 100644 --- a/packages/sushi/src/router/liquidity-providers/UniswapV3Base.ts +++ b/packages/sushi/src/router/liquidity-providers/UniswapV3Base.ts @@ -5,11 +5,11 @@ import { SushiSwapV3FeeAmount, TICK_SPACINGS } from '../../config/index.js' import { Currency, Token, Type } from '../../currency/index.js' import { computeSushiSwapV3PoolAddress } from '../../pool/index.js' import { RToken, UniV3Pool } from '../../tines/index.js' +import { DataFetcherOptions } from '../data-fetcher.js' import { getCurrencyCombinations } from '../get-currency-combinations.js' +import { memoizer } from '../memoizer.js' import { type PoolCode, UniV3PoolCode } from '../pool-codes/index.js' import { LiquidityProvider } from './LiquidityProvider.js' -import { DataFetcherOptions } from '../data-fetcher.js' -import { memoizer } from '../memoizer.js' interface StaticPool { address: Address @@ -86,7 +86,7 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { if (excludePools) staticPools = staticPools.filter((p) => !excludePools.has(p.address)) - const multicallMemoize = await memoizer.fn(this.client.multicall); + const multicallMemoize = await memoizer.fn(this.client.multicall) const slot0Data = { multicallAddress: this.client.chain?.contracts?.multicall3 @@ -140,24 +140,22 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { ), } const slot0 = options?.memoize - ? await (multicallMemoize(slot0Data) as Promise) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - INIT: multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) - : await this.client.multicall(slot0Data) - .catch((e) => { - console.warn( - `${this.getLogPrefix()} - INIT: multicall failed, message: ${ - e.message - }`, - ) - return undefined - }) + ? await (multicallMemoize(slot0Data) as Promise).catch((e) => { + console.warn( + `${this.getLogPrefix()} - INIT: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) + : await this.client.multicall(slot0Data).catch((e) => { + console.warn( + `${this.getLogPrefix()} - INIT: multicall failed, message: ${ + e.message + }`, + ) + return undefined + }) const existingPools: V3Pool[] = [] @@ -203,16 +201,21 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { }) as const, ), } - const liquidityContracts: Promise<({ - error?: undefined; - result: bigint; - status: "success"; - } | { - error: Error; - result?: undefined; - status: "failure"; - })[]> = options?.memoize - ? multicallMemoize(liquidityContractsData) as Promise + const liquidityContracts: Promise< + ( + | { + error?: undefined + result: bigint + status: 'success' + } + | { + error: Error + result?: undefined + status: 'failure' + } + )[] + > = options?.memoize + ? (multicallMemoize(liquidityContractsData) as Promise) : this.client.multicall(liquidityContractsData) const token0ContractsData = { @@ -231,16 +234,21 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { }) as const, ), } - const token0Contracts: Promise<({ - error: Error; - result?: undefined; - status: "failure"; - } | { - error?: undefined; - result: bigint; - status: "success"; - })[]> = options?.memoize - ? multicallMemoize(token0ContractsData) as Promise + const token0Contracts: Promise< + ( + | { + error: Error + result?: undefined + status: 'failure' + } + | { + error?: undefined + result: bigint + status: 'success' + } + )[] + > = options?.memoize + ? (multicallMemoize(token0ContractsData) as Promise) : this.client.multicall(token0ContractsData) const token1ContractsData = { @@ -259,16 +267,21 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { }) as const, ), } - const token1Contracts: Promise<({ - error?: undefined; - result: bigint; - status: "success"; - } | { - error: Error; - result?: undefined; - status: "failure"; - })[]> = options?.memoize - ? multicallMemoize(token1ContractsData) as Promise + const token1Contracts: Promise< + ( + | { + error?: undefined + result: bigint + status: 'success' + } + | { + error: Error + result?: undefined + status: 'failure' + } + )[] + > = options?.memoize + ? (multicallMemoize(token1ContractsData) as Promise) : this.client.multicall(token1ContractsData) const minIndexes = existingPools.map((pool) => @@ -311,20 +324,25 @@ export abstract class UniswapV3BaseProvider extends LiquidityProvider { contracts: wordList, blockNumber: options?.blockNumber, } - const ticksContracts: Promise<({ - error?: undefined; - result: readonly { - tick: number; - liquidityNet: bigint; - liquidityGross: bigint; - }[]; - status: "success"; - } | { - error: Error; - result?: undefined; - status: "failure"; - })[]> = options?.memoize - ? multicallMemoize(ticksContractsData) as Promise + const ticksContracts: Promise< + ( + | { + error?: undefined + result: readonly { + tick: number + liquidityNet: bigint + liquidityGross: bigint + }[] + status: 'success' + } + | { + error: Error + result?: undefined + status: 'failure' + } + )[] + > = options?.memoize + ? (multicallMemoize(ticksContractsData) as Promise) : this.client.multicall(ticksContractsData) const [liquidityResults, token0Balances, token1Balances, tickResults] = diff --git a/packages/sushi/src/router/static-pool-fetcher/Trident.ts b/packages/sushi/src/router/static-pool-fetcher/Trident.ts index 05851f6ae2..80dd95d61a 100644 --- a/packages/sushi/src/router/static-pool-fetcher/Trident.ts +++ b/packages/sushi/src/router/static-pool-fetcher/Trident.ts @@ -11,8 +11,8 @@ import { TridentChainId, } from '../../config/index.js' import { Currency, Token } from '../../currency/index.js' -import { getCurrencyCombinations } from '../get-currency-combinations.js' import { DataFetcherOptions } from '../data-fetcher.js' +import { getCurrencyCombinations } from '../get-currency-combinations.js' import { memoizer } from '../memoizer.js' export interface TridentStaticPool { @@ -63,8 +63,8 @@ export class TridentStaticPoolFetcher { chainId as TridentChainId ] as Address) - const multicallMemoize = await memoizer.fn(client.multicall); - + const multicallMemoize = await memoizer.fn(client.multicall) + const callStatePoolsCountData = { multicallAddress: client.chain?.contracts?.multicall3?.address as Address, allowFailure: true, @@ -80,15 +80,18 @@ export class TridentStaticPoolFetcher { }) as const, ), } - const callStatePoolsCount: ({ - error?: undefined; - result: bigint; - status: "success"; - } | { - error: Error; - result?: undefined; - status: "failure"; - })[] = options?.memoize + const callStatePoolsCount: ( + | { + error?: undefined + result: bigint + status: 'success' + } + | { + error: Error + result?: undefined + status: 'failure' + } + )[] = options?.memoize ? await (multicallMemoize(callStatePoolsCountData) as Promise) : await client.multicall(callStatePoolsCountData) @@ -137,15 +140,18 @@ export class TridentStaticPoolFetcher { }) as const, ), } - const callStatePools: ({ - error?: undefined; - result: readonly `0x${string}`[]; - status: "success"; - } | { - error: Error; - result?: undefined; - status: "failure"; - })[] = options?.memoize + const callStatePools: ( + | { + error?: undefined + result: readonly `0x${string}`[] + status: 'success' + } + | { + error: Error + result?: undefined + status: 'failure' + } + )[] = options?.memoize ? await (multicallMemoize(callStatePoolsData) as Promise) : await client.multicall(callStatePoolsData) @@ -178,15 +184,18 @@ export class TridentStaticPoolFetcher { }) as const, ), } - const fees: ({ - error?: undefined; - result: bigint; - status: "success"; - } | { - error: Error; - result?: undefined; - status: "failure"; - })[] = options?.memoize + const fees: ( + | { + error?: undefined + result: bigint + status: 'success' + } + | { + error: Error + result?: undefined + status: 'failure' + } + )[] = options?.memoize ? await (multicallMemoize(feesData) as Promise) : await client.multicall(feesData) diff --git a/packages/sushi/test/tines/snapshots/report b/packages/sushi/test/tines/snapshots/report index 306557668b..f8d28db60a 100644 --- a/packages/sushi/test/tines/snapshots/report +++ b/packages/sushi/test/tines/snapshots/report @@ -1,191 +1,42 @@ 1:"bridge-1": 5528.94 -> 5528.94 (0%) avg:0% 2:"bridge-2": 7663 -> 7663 (0%) avg:0% +151:"top20-150": 0 -> 0 (0%) avg:0% +152:"top20-151": 481 -> 481 (0%) avg:0% 3:"bridge-3": 11953.94 -> 11953.94 (0%) avg:0% 4:"bridge-4": 5496.94 -> 5496.94 (0%) avg:0% 5:"bridge-5-1": 4260.964 -> 4260.964 (0%) avg:0% -2:"top20-1": 1.1195509365387262e+37 -> 1.1195509365387262e+37 (0%) avg:0% 6:"bridge-5-2": 5473.94 -> 5473.94 (0%) avg:0% 7:"bridge-5-3": 5501.94 -> 5501.94 (0%) avg:0% 8:"bridge-5-5": 5528.94 -> 5528.94 (0%) avg:0% 9:"bridge-5-10": 5528.94 -> 5528.94 (0%) avg:0% 10:"bridge-5-30": 5528.94 -> 5528.94 (0%) avg:0% 11:"bridge-5-100": 5528.94 -> 5528.94 (0%) avg:0% -3:"top20-2": 96249232830474440000 -> 96249232830474440000 (0%) avg:0% -4:"top20-3": 467011582838851800000 -> 467011582838851800000 (0%) avg:0% -5:"top20-4": 14263706377454.916 -> 14263706377454.916 (0%) avg:0% 12:"bridge-5-300": 5528.94 -> 5528.94 (0%) avg:0% -6:"top20-5": 111208992328025 -> 111208992328025 (0%) avg:0% -7:"top20-6": 184056193599 -> 184056193599 (0%) avg:0% +153:"top20-152": 0 -> 0 (0%) avg:0% +154:"top20-153": 1.3468577317796694e+32 -> 1.3468577317796694e+32 (0%) avg:0% 13:"bridge-5-1000": 5528.94 -> 5528.94 (0%) avg:0% -8:"top20-7": 1.949010266471403e+21 -> 1.949010266471403e+21 (0%) avg:0% +155:"top20-154": 7978807883992.964 -> 7978807883992.964 (0%) avg:0% 14:"bridge-6": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% +156:"top20-155": 75460.9999999988 -> 75460.9999999988 (0%) avg:0% 15:"bridge-7-1": 567.9947198349995 -> 567.9947198349995 (0%) avg:0% 16:"bridge-7-2": 567.9947198349995 -> 567.9947198349995 (0%) avg:0% 17:"bridge-7-3": 569.9929597799993 -> 569.9929597799993 (0%) avg:0% -9:"top20-8": 5147698251 -> 5147698251 (0%) avg:0% +157:"top20-156": 1433531033857000200 -> 1433531033857000200 (0%) avg:0% 18:"bridge-7-5": 577.9911997249991 -> 577.9911997249991 (0%) avg:0% 19:"bridge-7-10": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% 20:"bridge-7-30": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% -10:"top20-9": 2.3146866045567974e+29 -> 2.3146866045567974e+29 (0%) avg:0% -11:"top20-10": 2.000939725061475e+25 -> 2.000939725061475e+25 (0%) avg:0% -21:"bridge-7-100": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% -12:"top20-11": 0 -> 0 (0%) avg:0% -22:"bridge-7-300": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% -13:"top20-12": 5.998729978399937e+23 -> 5.998729978399937e+23 (0%) avg:0% -14:"top20-13": 14.999999999999975 -> 14.999999999999975 (0%) avg:0% -15:"top20-14": 242561332730 -> 242561332730 (0%) avg:0% -16:"top20-15": 20057219983855420 -> 20057219983855420 (0%) avg:0% -17:"top20-16": 1371193183.507006 -> 1371193183.507006 (0%) avg:0% -18:"top20-17": 618784869519468900000 -> 618784869519468900000 (0%) avg:0% -19:"top20-18": 13965130914 -> 13965130914 (0%) avg:0% -23:"bridge-7-1000": 578.9911997249991 -> 578.9911997249991 (0%) avg:0% -20:"top20-19": 1719221840266011.2 -> 1719221840266011.2 (0%) avg:0% -21:"top20-20": 1.1539072915253164e+27 -> 1.1539072915253164e+27 (0%) avg:0% -22:"top20-21": 1.4857010533172297e+22 -> 1.4857010533172297e+22 (0%) avg:0% -23:"top20-22": 13216695381.96823 -> 13216695381.96823 (0%) avg:0% -24:"top20-23": 71.99999999995467 -> 71.99999999995467 (0%) avg:0% -25:"top20-24": 4.257526126994545e+23 -> 4.257526126994545e+23 (0%) avg:0% -26:"top20-25": 9.20707200216008e+22 -> 9.20707200216008e+22 (0%) avg:0% -27:"top20-26": 119377775 -> 119377775 (0%) avg:0% -28:"top20-27": 4.5396775085904846e+33 -> 4.5396775085904846e+33 (0%) avg:0% -29:"top20-28": 224764614280864 -> 224764614280864 (0%) avg:0% -30:"top20-29": 137910092016871140 -> 137910092016871140 (0%) avg:0% -31:"top20-30": 38414127759.999916 -> 38414127759.999916 (0%) avg:0% -32:"top20-31": 3.9150404497784796e+29 -> 3.9150404497784796e+29 (0%) avg:0% -33:"top20-32": 44939721212060795000 -> 44939721212060795000 (0%) avg:0% -34:"top20-33": 1.4260244914513205e+22 -> 1.4260244914513205e+22 (0%) avg:0% -35:"top20-34": 1.5495747386928312e+21 -> 1.5495747386928312e+21 (0%) avg:0% -36:"top20-35": 943239170088233300000 -> 943239170088233300000 (0%) avg:0% -37:"top20-36": 6121749117436.458 -> 6121749117436.458 (0%) avg:0% -38:"top20-37": 696747 -> 696747 (0%) avg:0% -39:"top20-38": 0 -> 0 (0%) avg:0% -40:"top20-39": 2.3426635283232224e+24 -> 2.3426635283232224e+24 (0%) avg:0% -41:"top20-40": 48254932363.26666 -> 48254932363.26666 (0%) avg:0% -42:"top20-41": 37860138974211.35 -> 37860138974211.35 (0%) avg:0% -43:"top20-42": 6.848076980412381e+22 -> 6.848076980412381e+22 (0%) avg:0% -44:"top20-43": 4320914881 -> 4320914881 (0%) avg:0% -45:"top20-44": 30713427089 -> 30713427089 (0%) avg:0% -46:"top20-45": 198661729955810 -> 198661729955810 (0%) avg:0% -47:"top20-46": 4003462547412852.5 -> 4003462547412852.5 (0%) avg:0% -48:"top20-47": 121585 -> 121585 (0%) avg:0% -49:"top20-48": 0 -> 0 (0%) avg:0% -50:"top20-49": 5.999999999999976 -> 5.999999999999976 (0%) avg:0% -51:"top20-50": 968129348392.8033 -> 968129348392.8033 (0%) avg:0% -52:"top20-51": 17468164450890598000 -> 17468164450890598000 (0%) avg:0% -53:"top20-52": 3370 -> 3370 (0%) avg:0% -54:"top20-53": 2.8669052288613494e+26 -> 2.8669052288613494e+26 (0%) avg:0% -55:"top20-54": 212397690771150670000 -> 212397690771150670000 (0%) avg:0% -56:"top20-55": 114722123950.99864 -> 114722123950.99864 (0%) avg:0% -57:"top20-56": 6237611807.9999895 -> 6237611807.9999895 (0%) avg:0% -58:"top20-57": 173 -> 173 (0%) avg:0% -59:"top20-58": 8.653786678134718e+34 -> 8.653786678134718e+34 (0%) avg:0% -60:"top20-59": 584843.9943957697 -> 584843.9943957697 (0%) avg:0% -61:"top20-60": 83746.99999922093 -> 83746.99999922093 (0%) avg:0% -62:"top20-61": 1.2108029911483686e+28 -> 1.2108029911483686e+28 (0%) avg:0% -63:"top20-62": 1.1321762736810075e+23 -> 1.1321762736810075e+23 (0%) avg:0% -64:"top20-63": 18624850720 -> 18624850720 (0%) avg:0% -65:"top20-64": 6558802213825504000 -> 6558802213825504000 (0%) avg:0% -66:"top20-65": 3006323408104.839 -> 3006323408104.839 (0%) avg:0% -67:"top20-66": 7.25699759360167e+33 -> 7.25699759360167e+33 (0%) avg:0% -68:"top20-67": 26997497976784.977 -> 26997497976784.977 (0%) avg:0% -69:"top20-68": 2.271898658800524e+29 -> 2.271898658800524e+29 (0%) avg:0% -70:"top20-69": 3320690.9992622463 -> 3320690.9992622463 (0%) avg:0% -71:"top20-70": 12137990973481046000 -> 12137990973481046000 (0%) avg:0% -72:"top20-71": 4.2988353121158716e+26 -> 4.2988353121158716e+26 (0%) avg:0% -73:"top20-72": 6.3575495792381146e+28 -> 6.3575495792381146e+28 (0%) avg:0% -74:"top20-73": 1.2313497939167126e+26 -> 1.2313497939167126e+26 (0%) avg:0% -75:"top20-74": 27707599790097 -> 27707599790097 (0%) avg:0% -76:"top20-75": 7124308 -> 7124308 (0%) avg:0% -77:"top20-76": 0 -> 0 (0%) avg:0% -78:"top20-77": 117608543724585440000 -> 117608543724585440000 (0%) avg:0% -79:"top20-78": 274576852204457 -> 274576852204457 (0%) avg:0% -80:"top20-79": 4.1679251723404575e+23 -> 4.1679251723404575e+23 (0%) avg:0% -81:"top20-80": 1.169123327125618e+23 -> 1.169123327125618e+23 (0%) avg:0% -82:"top20-81": 1.256638691159724e+26 -> 1.256638691159724e+26 (0%) avg:0% -83:"top20-82": 0 -> 0 (0%) avg:0% -84:"top20-83": 2.0149283251435153e+32 -> 2.0149283251435153e+32 (0%) avg:0% -85:"top20-84": 6.510078466693012e+35 -> 6.510078466693012e+35 (0%) avg:0% -86:"top20-85": 0 -> 0 (0%) avg:0% -87:"top20-86": 541712645104171 -> 541712645104171 (0%) avg:0% -88:"top20-87": 2935458414464351700 -> 2935458414464351700 (0%) avg:0% -89:"top20-88": 1672225 -> 1672225 (0%) avg:0% -90:"top20-89": 0 -> 0 (0%) avg:0% -91:"top20-90": 0 -> 0 (0%) avg:0% -92:"top20-91": 98143784 -> 98143784 (0%) avg:0% -93:"top20-92": 8692029076033.435 -> 8692029076033.435 (0%) avg:0% -94:"top20-93": 51562257056054440 -> 51562257056054440 (0%) avg:0% -95:"top20-94": 25641964396823.965 -> 25641964396823.965 (0%) avg:0% -96:"top20-95": 526418678128563400 -> 526418678128563400 (0%) avg:0% -97:"top20-96": 42011945995000000 -> 42011945995000000 (0%) avg:0% -98:"top20-97": 0 -> 0 (0%) avg:0% -99:"top20-98": 578210769514157600 -> 578210769514157600 (0%) avg:0% -100:"top20-99": 23757288573225 -> 23757288573225 (0%) avg:0% -101:"top20-100": 3519054200.963973 -> 3519054200.963973 (0%) avg:0% -102:"top20-101": 1.2366902841804613e+26 -> 1.2366902841804613e+26 (0%) avg:0% -103:"top20-102": 3.0616038596056797e+32 -> 3.0616038596056797e+32 (0%) avg:0% -104:"top20-103": 398198791124206 -> 398198791124206 (0%) avg:0% -105:"top20-104": 3434281999000000 -> 3434281999000000 (0%) avg:0% -106:"top20-105": 436386366610963040000 -> 436386366610963040000 (0%) avg:0% -107:"top20-106": 7814 -> 7814 (0%) avg:0% -108:"top20-107": 4.387432445585929e+34 -> 4.387432445585929e+34 (0%) avg:0% -109:"top20-108": 0 -> 0 (0%) avg:0% -110:"top20-109": 0 -> 0 (0%) avg:0% -111:"top20-110": 180771390372608.16 -> 180771390372608.16 (0%) avg:0% -112:"top20-111": 1.53356324718735e+23 -> 1.53356324718735e+23 (0%) avg:0% -113:"top20-112": 0 -> 0 (0%) avg:0% -114:"top20-113": 441807728976948040000 -> 441807728976948040000 (0%) avg:0% -115:"top20-114": 5.872905678780656e+30 -> 5.872905678780656e+30 (0%) avg:0% -116:"top20-115": 1.9999999999999998 -> 1.9999999999999998 (0%) avg:0% -117:"top20-116": 0 -> 0 (0%) avg:0% -118:"top20-117": 103625.91934739704 -> 103625.91934739704 (0%) avg:0% -119:"top20-118": 3994 -> 3994 (0%) avg:0% -120:"top20-119": 5481554822 -> 5481554822 (0%) avg:0% -121:"top20-120": 2148662632935361000 -> 2148662632935361000 (0%) avg:0% -122:"top20-121": 780768139203693200000 -> 780768139203693200000 (0%) avg:0% -123:"top20-122": 0 -> 0 (0%) avg:0% -124:"top20-123": 74390557839848180 -> 74390557839848180 (0%) avg:0% -125:"top20-124": 5.2767009412144705e+23 -> 5.2767009412144705e+23 (0%) avg:0% -126:"top20-125": 12999322599.999998 -> 12999322599.999998 (0%) avg:0% -127:"top20-126": 1.166563599584172e+25 -> 1.166563599584172e+25 (0%) avg:0% -128:"top20-127": 0 -> 0 (0%) avg:0% -129:"top20-128": 2.381239814048817e+29 -> 2.381239814048817e+29 (0%) avg:0% -130:"top20-129": 1.773617547666896e+21 -> 1.773617547666896e+21 (0%) avg:0% -131:"top20-130": 1043374941775 -> 1043374941775 (0%) avg:0% -132:"top20-131": 3 -> 3 (0%) avg:0% -133:"top20-132": 3523544256 -> 3523544256 (0%) avg:0% -134:"top20-133": 30660569440069612 -> 30660569440069612 (0%) avg:0% -135:"top20-134": 0 -> 0 (0%) avg:0% -136:"top20-135": 46215289309 -> 46215289309 (0%) avg:0% -137:"top20-136": 157666012290841060 -> 157666012290841060 (0%) avg:0% -138:"top20-137": 0 -> 0 (0%) avg:0% -139:"top20-138": 94486154517 -> 94486154517 (0%) avg:0% -140:"top20-139": 5381047.578903644 -> 5381047.578903644 (0%) avg:0% -141:"top20-140": 2904868891031402 -> 2904868891031402 (0%) avg:0% -142:"top20-141": 349815735970433660000 -> 349815735970433660000 (0%) avg:0% -143:"top20-142": 1.61321284630438e+29 -> 1.61321284630438e+29 (0%) avg:0% -144:"top20-143": 0 -> 0 (0%) avg:0% -145:"top20-144": 1.8715935050611244e+27 -> 1.8715935050611244e+27 (0%) avg:0% -146:"top20-145": 2329.999987331977 -> 2329.999987331977 (0%) avg:0% -147:"top20-146": 1.5754421469670991e+28 -> 1.5754421469670991e+28 (0%) avg:0% -148:"top20-147": 2.6838048385825768e+32 -> 2.6838048385825768e+32 (0%) avg:0% -149:"top20-148": 2.7141809250137436e+32 -> 2.7141809250137436e+32 (0%) avg:0% -150:"top20-149": 17399664148369718 -> 17399664148369718 (0%) avg:0% -151:"top20-150": 0 -> 0 (0%) avg:0% -152:"top20-151": 481 -> 481 (0%) avg:0% -153:"top20-152": 0 -> 0 (0%) avg:0% -154:"top20-153": 1.3468577317796694e+32 -> 1.3468577317796694e+32 (0%) avg:0% -155:"top20-154": 7978807883992.964 -> 7978807883992.964 (0%) avg:0% -156:"top20-155": 75460.9999999988 -> 75460.9999999988 (0%) avg:0% -157:"top20-156": 1433531033857000200 -> 1433531033857000200 (0%) avg:0% 158:"top20-157": 5729885219 -> 5729885219 (0%) avg:0% +21:"bridge-7-100": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% 159:"top20-158": 3.5295876698920206e+21 -> 3.5295876698920206e+21 (0%) avg:0% 160:"top20-159": 2752089826200724500 -> 2752089826200724500 (0%) avg:0% 161:"top20-160": 1.3721043284746797e+27 -> 1.3721043284746797e+27 (0%) avg:0% 162:"top20-161": 2628873 -> 2628873 (0%) avg:0% +22:"bridge-7-300": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% 163:"top20-162": 0 -> 0 (0%) avg:0% 164:"top20-163": 7.139942836800165e+35 -> 7.139942836800165e+35 (0%) avg:0% 165:"top20-164": 588671138.9993676 -> 588671138.9993676 (0%) avg:0% 166:"top20-165": 141491517.99997458 -> 141491517.99997458 (0%) avg:0% +23:"bridge-7-1000": 578.9911997249991 -> 578.9911997249991 (0%) avg:0% 167:"top20-166": 9.906334905865037e+36 -> 9.906334905865037e+36 (0%) avg:0% 168:"top20-167": 6.127970056928261e+23 -> 6.127970056928261e+23 (0%) avg:0% 169:"top20-168": 0 -> 0 (0%) avg:0% From 7b38c83858c268dc8ac87f9acf7c2a221f9af4c3 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sat, 27 Apr 2024 04:10:29 +0000 Subject: [PATCH 3/4] Update data-fetcher.ts --- packages/sushi/src/router/data-fetcher.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/sushi/src/router/data-fetcher.ts b/packages/sushi/src/router/data-fetcher.ts index 74c88a6249..7f5e56294b 100644 --- a/packages/sushi/src/router/data-fetcher.ts +++ b/packages/sushi/src/router/data-fetcher.ts @@ -31,7 +31,13 @@ import type { PoolCode } from './pool-codes/index.js' // options for data fetching, such as pinning block number and memoize export type DataFetcherOptions = { + /** + * The pinned block number when getting onchain data + * this option is usefull for reproducing the route, + * price, etc of a certain block + */ blockNumber?: bigint + /** Determines if memoizer should be used or not */ memoize?: boolean } From 1f3530d7bc53ec6997992bded151d101bb20f819 Mon Sep 17 00:00:00 2001 From: rouzwelt Date: Sun, 5 May 2024 20:30:14 +0000 Subject: [PATCH 4/4] Update report --- packages/sushi/test/tines/snapshots/report | 169 +++++++++++++++++++-- 1 file changed, 159 insertions(+), 10 deletions(-) diff --git a/packages/sushi/test/tines/snapshots/report b/packages/sushi/test/tines/snapshots/report index f8d28db60a..306557668b 100644 --- a/packages/sushi/test/tines/snapshots/report +++ b/packages/sushi/test/tines/snapshots/report @@ -1,42 +1,191 @@ 1:"bridge-1": 5528.94 -> 5528.94 (0%) avg:0% 2:"bridge-2": 7663 -> 7663 (0%) avg:0% -151:"top20-150": 0 -> 0 (0%) avg:0% -152:"top20-151": 481 -> 481 (0%) avg:0% 3:"bridge-3": 11953.94 -> 11953.94 (0%) avg:0% 4:"bridge-4": 5496.94 -> 5496.94 (0%) avg:0% 5:"bridge-5-1": 4260.964 -> 4260.964 (0%) avg:0% +2:"top20-1": 1.1195509365387262e+37 -> 1.1195509365387262e+37 (0%) avg:0% 6:"bridge-5-2": 5473.94 -> 5473.94 (0%) avg:0% 7:"bridge-5-3": 5501.94 -> 5501.94 (0%) avg:0% 8:"bridge-5-5": 5528.94 -> 5528.94 (0%) avg:0% 9:"bridge-5-10": 5528.94 -> 5528.94 (0%) avg:0% 10:"bridge-5-30": 5528.94 -> 5528.94 (0%) avg:0% 11:"bridge-5-100": 5528.94 -> 5528.94 (0%) avg:0% +3:"top20-2": 96249232830474440000 -> 96249232830474440000 (0%) avg:0% +4:"top20-3": 467011582838851800000 -> 467011582838851800000 (0%) avg:0% +5:"top20-4": 14263706377454.916 -> 14263706377454.916 (0%) avg:0% 12:"bridge-5-300": 5528.94 -> 5528.94 (0%) avg:0% -153:"top20-152": 0 -> 0 (0%) avg:0% -154:"top20-153": 1.3468577317796694e+32 -> 1.3468577317796694e+32 (0%) avg:0% +6:"top20-5": 111208992328025 -> 111208992328025 (0%) avg:0% +7:"top20-6": 184056193599 -> 184056193599 (0%) avg:0% 13:"bridge-5-1000": 5528.94 -> 5528.94 (0%) avg:0% -155:"top20-154": 7978807883992.964 -> 7978807883992.964 (0%) avg:0% +8:"top20-7": 1.949010266471403e+21 -> 1.949010266471403e+21 (0%) avg:0% 14:"bridge-6": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% -156:"top20-155": 75460.9999999988 -> 75460.9999999988 (0%) avg:0% 15:"bridge-7-1": 567.9947198349995 -> 567.9947198349995 (0%) avg:0% 16:"bridge-7-2": 567.9947198349995 -> 567.9947198349995 (0%) avg:0% 17:"bridge-7-3": 569.9929597799993 -> 569.9929597799993 (0%) avg:0% -157:"top20-156": 1433531033857000200 -> 1433531033857000200 (0%) avg:0% +9:"top20-8": 5147698251 -> 5147698251 (0%) avg:0% 18:"bridge-7-5": 577.9911997249991 -> 577.9911997249991 (0%) avg:0% 19:"bridge-7-10": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% 20:"bridge-7-30": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% -158:"top20-157": 5729885219 -> 5729885219 (0%) avg:0% +10:"top20-9": 2.3146866045567974e+29 -> 2.3146866045567974e+29 (0%) avg:0% +11:"top20-10": 2.000939725061475e+25 -> 2.000939725061475e+25 (0%) avg:0% 21:"bridge-7-100": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% +12:"top20-11": 0 -> 0 (0%) avg:0% +22:"bridge-7-300": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% +13:"top20-12": 5.998729978399937e+23 -> 5.998729978399937e+23 (0%) avg:0% +14:"top20-13": 14.999999999999975 -> 14.999999999999975 (0%) avg:0% +15:"top20-14": 242561332730 -> 242561332730 (0%) avg:0% +16:"top20-15": 20057219983855420 -> 20057219983855420 (0%) avg:0% +17:"top20-16": 1371193183.507006 -> 1371193183.507006 (0%) avg:0% +18:"top20-17": 618784869519468900000 -> 618784869519468900000 (0%) avg:0% +19:"top20-18": 13965130914 -> 13965130914 (0%) avg:0% +23:"bridge-7-1000": 578.9911997249991 -> 578.9911997249991 (0%) avg:0% +20:"top20-19": 1719221840266011.2 -> 1719221840266011.2 (0%) avg:0% +21:"top20-20": 1.1539072915253164e+27 -> 1.1539072915253164e+27 (0%) avg:0% +22:"top20-21": 1.4857010533172297e+22 -> 1.4857010533172297e+22 (0%) avg:0% +23:"top20-22": 13216695381.96823 -> 13216695381.96823 (0%) avg:0% +24:"top20-23": 71.99999999995467 -> 71.99999999995467 (0%) avg:0% +25:"top20-24": 4.257526126994545e+23 -> 4.257526126994545e+23 (0%) avg:0% +26:"top20-25": 9.20707200216008e+22 -> 9.20707200216008e+22 (0%) avg:0% +27:"top20-26": 119377775 -> 119377775 (0%) avg:0% +28:"top20-27": 4.5396775085904846e+33 -> 4.5396775085904846e+33 (0%) avg:0% +29:"top20-28": 224764614280864 -> 224764614280864 (0%) avg:0% +30:"top20-29": 137910092016871140 -> 137910092016871140 (0%) avg:0% +31:"top20-30": 38414127759.999916 -> 38414127759.999916 (0%) avg:0% +32:"top20-31": 3.9150404497784796e+29 -> 3.9150404497784796e+29 (0%) avg:0% +33:"top20-32": 44939721212060795000 -> 44939721212060795000 (0%) avg:0% +34:"top20-33": 1.4260244914513205e+22 -> 1.4260244914513205e+22 (0%) avg:0% +35:"top20-34": 1.5495747386928312e+21 -> 1.5495747386928312e+21 (0%) avg:0% +36:"top20-35": 943239170088233300000 -> 943239170088233300000 (0%) avg:0% +37:"top20-36": 6121749117436.458 -> 6121749117436.458 (0%) avg:0% +38:"top20-37": 696747 -> 696747 (0%) avg:0% +39:"top20-38": 0 -> 0 (0%) avg:0% +40:"top20-39": 2.3426635283232224e+24 -> 2.3426635283232224e+24 (0%) avg:0% +41:"top20-40": 48254932363.26666 -> 48254932363.26666 (0%) avg:0% +42:"top20-41": 37860138974211.35 -> 37860138974211.35 (0%) avg:0% +43:"top20-42": 6.848076980412381e+22 -> 6.848076980412381e+22 (0%) avg:0% +44:"top20-43": 4320914881 -> 4320914881 (0%) avg:0% +45:"top20-44": 30713427089 -> 30713427089 (0%) avg:0% +46:"top20-45": 198661729955810 -> 198661729955810 (0%) avg:0% +47:"top20-46": 4003462547412852.5 -> 4003462547412852.5 (0%) avg:0% +48:"top20-47": 121585 -> 121585 (0%) avg:0% +49:"top20-48": 0 -> 0 (0%) avg:0% +50:"top20-49": 5.999999999999976 -> 5.999999999999976 (0%) avg:0% +51:"top20-50": 968129348392.8033 -> 968129348392.8033 (0%) avg:0% +52:"top20-51": 17468164450890598000 -> 17468164450890598000 (0%) avg:0% +53:"top20-52": 3370 -> 3370 (0%) avg:0% +54:"top20-53": 2.8669052288613494e+26 -> 2.8669052288613494e+26 (0%) avg:0% +55:"top20-54": 212397690771150670000 -> 212397690771150670000 (0%) avg:0% +56:"top20-55": 114722123950.99864 -> 114722123950.99864 (0%) avg:0% +57:"top20-56": 6237611807.9999895 -> 6237611807.9999895 (0%) avg:0% +58:"top20-57": 173 -> 173 (0%) avg:0% +59:"top20-58": 8.653786678134718e+34 -> 8.653786678134718e+34 (0%) avg:0% +60:"top20-59": 584843.9943957697 -> 584843.9943957697 (0%) avg:0% +61:"top20-60": 83746.99999922093 -> 83746.99999922093 (0%) avg:0% +62:"top20-61": 1.2108029911483686e+28 -> 1.2108029911483686e+28 (0%) avg:0% +63:"top20-62": 1.1321762736810075e+23 -> 1.1321762736810075e+23 (0%) avg:0% +64:"top20-63": 18624850720 -> 18624850720 (0%) avg:0% +65:"top20-64": 6558802213825504000 -> 6558802213825504000 (0%) avg:0% +66:"top20-65": 3006323408104.839 -> 3006323408104.839 (0%) avg:0% +67:"top20-66": 7.25699759360167e+33 -> 7.25699759360167e+33 (0%) avg:0% +68:"top20-67": 26997497976784.977 -> 26997497976784.977 (0%) avg:0% +69:"top20-68": 2.271898658800524e+29 -> 2.271898658800524e+29 (0%) avg:0% +70:"top20-69": 3320690.9992622463 -> 3320690.9992622463 (0%) avg:0% +71:"top20-70": 12137990973481046000 -> 12137990973481046000 (0%) avg:0% +72:"top20-71": 4.2988353121158716e+26 -> 4.2988353121158716e+26 (0%) avg:0% +73:"top20-72": 6.3575495792381146e+28 -> 6.3575495792381146e+28 (0%) avg:0% +74:"top20-73": 1.2313497939167126e+26 -> 1.2313497939167126e+26 (0%) avg:0% +75:"top20-74": 27707599790097 -> 27707599790097 (0%) avg:0% +76:"top20-75": 7124308 -> 7124308 (0%) avg:0% +77:"top20-76": 0 -> 0 (0%) avg:0% +78:"top20-77": 117608543724585440000 -> 117608543724585440000 (0%) avg:0% +79:"top20-78": 274576852204457 -> 274576852204457 (0%) avg:0% +80:"top20-79": 4.1679251723404575e+23 -> 4.1679251723404575e+23 (0%) avg:0% +81:"top20-80": 1.169123327125618e+23 -> 1.169123327125618e+23 (0%) avg:0% +82:"top20-81": 1.256638691159724e+26 -> 1.256638691159724e+26 (0%) avg:0% +83:"top20-82": 0 -> 0 (0%) avg:0% +84:"top20-83": 2.0149283251435153e+32 -> 2.0149283251435153e+32 (0%) avg:0% +85:"top20-84": 6.510078466693012e+35 -> 6.510078466693012e+35 (0%) avg:0% +86:"top20-85": 0 -> 0 (0%) avg:0% +87:"top20-86": 541712645104171 -> 541712645104171 (0%) avg:0% +88:"top20-87": 2935458414464351700 -> 2935458414464351700 (0%) avg:0% +89:"top20-88": 1672225 -> 1672225 (0%) avg:0% +90:"top20-89": 0 -> 0 (0%) avg:0% +91:"top20-90": 0 -> 0 (0%) avg:0% +92:"top20-91": 98143784 -> 98143784 (0%) avg:0% +93:"top20-92": 8692029076033.435 -> 8692029076033.435 (0%) avg:0% +94:"top20-93": 51562257056054440 -> 51562257056054440 (0%) avg:0% +95:"top20-94": 25641964396823.965 -> 25641964396823.965 (0%) avg:0% +96:"top20-95": 526418678128563400 -> 526418678128563400 (0%) avg:0% +97:"top20-96": 42011945995000000 -> 42011945995000000 (0%) avg:0% +98:"top20-97": 0 -> 0 (0%) avg:0% +99:"top20-98": 578210769514157600 -> 578210769514157600 (0%) avg:0% +100:"top20-99": 23757288573225 -> 23757288573225 (0%) avg:0% +101:"top20-100": 3519054200.963973 -> 3519054200.963973 (0%) avg:0% +102:"top20-101": 1.2366902841804613e+26 -> 1.2366902841804613e+26 (0%) avg:0% +103:"top20-102": 3.0616038596056797e+32 -> 3.0616038596056797e+32 (0%) avg:0% +104:"top20-103": 398198791124206 -> 398198791124206 (0%) avg:0% +105:"top20-104": 3434281999000000 -> 3434281999000000 (0%) avg:0% +106:"top20-105": 436386366610963040000 -> 436386366610963040000 (0%) avg:0% +107:"top20-106": 7814 -> 7814 (0%) avg:0% +108:"top20-107": 4.387432445585929e+34 -> 4.387432445585929e+34 (0%) avg:0% +109:"top20-108": 0 -> 0 (0%) avg:0% +110:"top20-109": 0 -> 0 (0%) avg:0% +111:"top20-110": 180771390372608.16 -> 180771390372608.16 (0%) avg:0% +112:"top20-111": 1.53356324718735e+23 -> 1.53356324718735e+23 (0%) avg:0% +113:"top20-112": 0 -> 0 (0%) avg:0% +114:"top20-113": 441807728976948040000 -> 441807728976948040000 (0%) avg:0% +115:"top20-114": 5.872905678780656e+30 -> 5.872905678780656e+30 (0%) avg:0% +116:"top20-115": 1.9999999999999998 -> 1.9999999999999998 (0%) avg:0% +117:"top20-116": 0 -> 0 (0%) avg:0% +118:"top20-117": 103625.91934739704 -> 103625.91934739704 (0%) avg:0% +119:"top20-118": 3994 -> 3994 (0%) avg:0% +120:"top20-119": 5481554822 -> 5481554822 (0%) avg:0% +121:"top20-120": 2148662632935361000 -> 2148662632935361000 (0%) avg:0% +122:"top20-121": 780768139203693200000 -> 780768139203693200000 (0%) avg:0% +123:"top20-122": 0 -> 0 (0%) avg:0% +124:"top20-123": 74390557839848180 -> 74390557839848180 (0%) avg:0% +125:"top20-124": 5.2767009412144705e+23 -> 5.2767009412144705e+23 (0%) avg:0% +126:"top20-125": 12999322599.999998 -> 12999322599.999998 (0%) avg:0% +127:"top20-126": 1.166563599584172e+25 -> 1.166563599584172e+25 (0%) avg:0% +128:"top20-127": 0 -> 0 (0%) avg:0% +129:"top20-128": 2.381239814048817e+29 -> 2.381239814048817e+29 (0%) avg:0% +130:"top20-129": 1.773617547666896e+21 -> 1.773617547666896e+21 (0%) avg:0% +131:"top20-130": 1043374941775 -> 1043374941775 (0%) avg:0% +132:"top20-131": 3 -> 3 (0%) avg:0% +133:"top20-132": 3523544256 -> 3523544256 (0%) avg:0% +134:"top20-133": 30660569440069612 -> 30660569440069612 (0%) avg:0% +135:"top20-134": 0 -> 0 (0%) avg:0% +136:"top20-135": 46215289309 -> 46215289309 (0%) avg:0% +137:"top20-136": 157666012290841060 -> 157666012290841060 (0%) avg:0% +138:"top20-137": 0 -> 0 (0%) avg:0% +139:"top20-138": 94486154517 -> 94486154517 (0%) avg:0% +140:"top20-139": 5381047.578903644 -> 5381047.578903644 (0%) avg:0% +141:"top20-140": 2904868891031402 -> 2904868891031402 (0%) avg:0% +142:"top20-141": 349815735970433660000 -> 349815735970433660000 (0%) avg:0% +143:"top20-142": 1.61321284630438e+29 -> 1.61321284630438e+29 (0%) avg:0% +144:"top20-143": 0 -> 0 (0%) avg:0% +145:"top20-144": 1.8715935050611244e+27 -> 1.8715935050611244e+27 (0%) avg:0% +146:"top20-145": 2329.999987331977 -> 2329.999987331977 (0%) avg:0% +147:"top20-146": 1.5754421469670991e+28 -> 1.5754421469670991e+28 (0%) avg:0% +148:"top20-147": 2.6838048385825768e+32 -> 2.6838048385825768e+32 (0%) avg:0% +149:"top20-148": 2.7141809250137436e+32 -> 2.7141809250137436e+32 (0%) avg:0% +150:"top20-149": 17399664148369718 -> 17399664148369718 (0%) avg:0% +151:"top20-150": 0 -> 0 (0%) avg:0% +152:"top20-151": 481 -> 481 (0%) avg:0% +153:"top20-152": 0 -> 0 (0%) avg:0% +154:"top20-153": 1.3468577317796694e+32 -> 1.3468577317796694e+32 (0%) avg:0% +155:"top20-154": 7978807883992.964 -> 7978807883992.964 (0%) avg:0% +156:"top20-155": 75460.9999999988 -> 75460.9999999988 (0%) avg:0% +157:"top20-156": 1433531033857000200 -> 1433531033857000200 (0%) avg:0% +158:"top20-157": 5729885219 -> 5729885219 (0%) avg:0% 159:"top20-158": 3.5295876698920206e+21 -> 3.5295876698920206e+21 (0%) avg:0% 160:"top20-159": 2752089826200724500 -> 2752089826200724500 (0%) avg:0% 161:"top20-160": 1.3721043284746797e+27 -> 1.3721043284746797e+27 (0%) avg:0% 162:"top20-161": 2628873 -> 2628873 (0%) avg:0% -22:"bridge-7-300": 579.9911997249991 -> 579.9911997249991 (0%) avg:0% 163:"top20-162": 0 -> 0 (0%) avg:0% 164:"top20-163": 7.139942836800165e+35 -> 7.139942836800165e+35 (0%) avg:0% 165:"top20-164": 588671138.9993676 -> 588671138.9993676 (0%) avg:0% 166:"top20-165": 141491517.99997458 -> 141491517.99997458 (0%) avg:0% -23:"bridge-7-1000": 578.9911997249991 -> 578.9911997249991 (0%) avg:0% 167:"top20-166": 9.906334905865037e+36 -> 9.906334905865037e+36 (0%) avg:0% 168:"top20-167": 6.127970056928261e+23 -> 6.127970056928261e+23 (0%) avg:0% 169:"top20-168": 0 -> 0 (0%) avg:0%