diff --git a/.changeset/fifty-months-cover.md b/.changeset/fifty-months-cover.md new file mode 100644 index 0000000..6a09d64 --- /dev/null +++ b/.changeset/fifty-months-cover.md @@ -0,0 +1,5 @@ +--- +'@3loop/transaction-decoder': patch +--- + +Improved perfomance of loading proxies by adding batching and cahching of request diff --git a/apps/web/src/app/data.ts b/apps/web/src/app/data.ts index 9f5b8a6..3089e6b 100644 --- a/apps/web/src/app/data.ts +++ b/apps/web/src/app/data.ts @@ -130,7 +130,6 @@ export const supportedChains: { chainID: number rpcUrl: string traceAPI?: 'parity' | 'geth' | 'none' - batchMaxCount?: number }[] = [ { name: 'Ethereum Mainnet', @@ -146,8 +145,7 @@ export const supportedChains: { name: 'Base mainnet', chainID: 8453, rpcUrl: process.env.BASE_RPC_URL as string, - traceAPI: 'parity', - batchMaxCount: 1, + traceAPI: 'geth', }, { name: 'Polygon Mainnet', diff --git a/apps/web/src/lib/decode.ts b/apps/web/src/lib/decode.ts index e52ae9d..fe8c9d6 100644 --- a/apps/web/src/lib/decode.ts +++ b/apps/web/src/lib/decode.ts @@ -1,5 +1,5 @@ import { getProvider, RPCProviderLive } from './rpc-provider' -import { Config, Effect, Layer, ManagedRuntime } from 'effect' +import { Config, Effect, Layer, ManagedRuntime, Request } from 'effect' import { DecodedTransaction, DecodeResult, @@ -56,8 +56,10 @@ const MetaStoreLive = Layer.unwrapEffect( }) }), ) +const CacheLayer = Layer.setRequestCache(Request.makeCache({ capacity: 100, timeToLive: '60 minutes' })) const DataLayer = Layer.mergeAll(RPCProviderLive, DatabaseLive) const LoadersLayer = Layer.mergeAll(AbiStoreLive, MetaStoreLive) + const MainLayer = Layer.provideMerge(LoadersLayer, DataLayer) as Layer.Layer< | AbiStore | ContractMetaStore @@ -68,7 +70,7 @@ const MainLayer = Layer.provideMerge(LoadersLayer, DataLayer) as Layer.Layer< never > -const runtime = ManagedRuntime.make(MainLayer) +const runtime = ManagedRuntime.make(Layer.provide(MainLayer, CacheLayer)) export async function decodeTransaction({ chainID, @@ -80,10 +82,19 @@ export async function decodeTransaction({ // NOTE: For unknonw reason the context of main layer is still missing the SqlClient in the type const runnable = decodeTransactionByHash(hash as Hex, chainID) - return runtime.runPromise(runnable).catch((error: unknown) => { + const startTime = performance.now() + + try { + const result = await runtime.runPromise(runnable) + const endTime = performance.now() + console.log(`Decode transaction took ${endTime - startTime}ms`) + return result + } catch (error: unknown) { + const endTime = performance.now() console.error('Decode error', JSON.stringify(error, null, 2)) + console.log(`Failed decode transaction took ${endTime - startTime}ms`) return undefined - }) + } } export async function decodeCalldata({ diff --git a/apps/web/src/lib/rpc-provider.ts b/apps/web/src/lib/rpc-provider.ts index b72c60a..3a3bbc6 100644 --- a/apps/web/src/lib/rpc-provider.ts +++ b/apps/web/src/lib/rpc-provider.ts @@ -16,7 +16,39 @@ export function getProvider(chainID: number): PublicClientObject | null { if (url != null) { return { client: createPublicClient({ - transport: http(url), + transport: http(url, { + // Requests logging + // onFetchRequest(request) { + // const reader = request.body?.getReader() + // if (!reader) { + // return + // } + // let body = '' + // reader + // .read() + // .then(function processText({ done, value }) { + // if (done) { + // return + // } + // // value for fetch streams is a Uint8Array + // body += value + // reader.read().then(processText) + // }) + // .then(() => { + // const json = JSON.parse( + // body + // .split(',') + // .map((code) => String.fromCharCode(parseInt(code, 10))) + // .join(''), + // ) + // try { + // console.log(JSON.stringify(json, null, 2)) + // } catch (e) { + // console.log(json['id'], json['method'], body.length) + // } + // }) + // }, + }), }), config: { traceAPI: providerConfigs[chainID]?.traceAPI, diff --git a/packages/transaction-decoder/src/abi-loader.ts b/packages/transaction-decoder/src/abi-loader.ts index fd17c6a..8832a1f 100644 --- a/packages/transaction-decoder/src/abi-loader.ts +++ b/packages/transaction-decoder/src/abi-loader.ts @@ -12,7 +12,8 @@ import { SchemaAST, } from 'effect' import { ContractABI, ContractAbiResolverStrategy, GetContractABIStrategy } from './abi-strategy/request-model.js' -import { Abi } from 'viem' +import { Abi, getAddress } from 'viem' +import { getProxyImplementation } from './decoding/proxies.js' export interface AbiParams { chainID: number @@ -39,6 +40,7 @@ export interface ContractAbiEmpty { export type ContractAbiResult = ContractAbiSuccess | ContractAbiNotFound | ContractAbiEmpty type ChainOrDefault = number | 'default' + export interface AbiStore { readonly strategies: Record readonly set: (key: Key, value: Value) => Effect.Effect diff --git a/packages/transaction-decoder/src/contract-meta-loader.ts b/packages/transaction-decoder/src/contract-meta-loader.ts index 5c118ac..f463dfc 100644 --- a/packages/transaction-decoder/src/contract-meta-loader.ts +++ b/packages/transaction-decoder/src/contract-meta-loader.ts @@ -2,6 +2,7 @@ import { Context, Effect, RequestResolver, Request, Array, Either, pipe, Schema, import { ContractData } from './types.js' import { ContractMetaResolverStrategy, GetContractMetaStrategy } from './meta-strategy/request-model.js' import { Address } from 'viem' +import { ZERO_ADDRESS } from './decoding/constants.js' export interface ContractMetaParams { address: string @@ -155,24 +156,28 @@ const ContractMetaLoaderRequestResolver = RequestResolver.makeBatched((requests: ) // Fetch ContractMeta from the strategies - const strategyResults = yield* Effect.forEach(remaining, ({ chainID, address }) => { - const allAvailableStrategies = Array.prependAll(strategies.default, strategies[chainID] ?? []) - - // TODO: Distinct the errors and missing data, so we can retry on errors - return Effect.validateFirst(allAvailableStrategies, (strategy) => - pipe( - Effect.request( - new GetContractMetaStrategy({ - address, - chainId: chainID, - strategyId: strategy.id, - }), - strategy.resolver, + const strategyResults = yield* Effect.forEach( + remaining, + ({ chainID, address }) => { + const allAvailableStrategies = Array.prependAll(strategies.default, strategies[chainID] ?? []) + + // TODO: Distinct the errors and missing data, so we can retry on errors + return Effect.validateFirst(allAvailableStrategies, (strategy) => + pipe( + Effect.request( + new GetContractMetaStrategy({ + address, + chainId: chainID, + strategyId: strategy.id, + }), + strategy.resolver, + ), + Effect.withRequestCaching(true), ), - Effect.withRequestCaching(true), - ), - ).pipe(Effect.orElseSucceed(() => null)) - }) + ).pipe(Effect.orElseSucceed(() => null)) + }, + { concurrency: 'unbounded', batching: true }, + ) // Store results and resolve pending requests yield* Effect.forEach( @@ -197,6 +202,8 @@ export const getAndCacheContractMeta = ({ readonly chainID: number readonly address: Address }) => { + if (address === ZERO_ADDRESS) return Effect.succeed(null) + return Effect.withSpan( Effect.request(new ContractMetaLoader({ chainID, address }), ContractMetaLoaderRequestResolver), 'GetAndCacheContractMeta', diff --git a/packages/transaction-decoder/src/decoding/calldata-decode.ts b/packages/transaction-decoder/src/decoding/calldata-decode.ts index 98700ed..3ca79b4 100644 --- a/packages/transaction-decoder/src/decoding/calldata-decode.ts +++ b/packages/transaction-decoder/src/decoding/calldata-decode.ts @@ -1,11 +1,11 @@ import { Effect } from 'effect' -import { isAddress, Hex, getAddress, encodeFunctionData, Address } from 'viem' -import { getProxyStorageSlot } from './proxies.js' +import { Hex, Address, encodeFunctionData, isAddress, getAddress } from 'viem' import { AbiParams, AbiStore, ContractAbiResult, getAndCacheAbi, MissingABIError } from '../abi-loader.js' import * as AbiDecoder from './abi-decode.js' import { TreeNode } from '../types.js' import { PublicClient, RPCFetchError, UnknownNetwork } from '../public-client.js' import { SAFE_MULTISEND_ABI, SAFE_MULTISEND_SIGNATURE } from './constants.js' +import { getProxyImplementation } from './proxies.js' const callDataKeys = ['callData', 'data', '_data'] const addressKeys = ['to', 'target', '_target'] @@ -147,11 +147,12 @@ export const decodeMethod = ({ }) => Effect.gen(function* () { const signature = data.slice(0, 10) + let implementationAddress: Address | undefined if (isAddress(contractAddress)) { //if contract is a proxy, get the implementation address - const implementation = yield* getProxyStorageSlot({ address: getAddress(contractAddress), chainID }) + const implementation = yield* getProxyImplementation({ address: getAddress(contractAddress), chainID }) if (implementation) { implementationAddress = implementation.address diff --git a/packages/transaction-decoder/src/decoding/constants.ts b/packages/transaction-decoder/src/decoding/constants.ts index 33d7aec..4aa5604 100644 --- a/packages/transaction-decoder/src/decoding/constants.ts +++ b/packages/transaction-decoder/src/decoding/constants.ts @@ -38,3 +38,4 @@ export const SAFE_MULTISEND_ABI: Abi = [ outputs: [], }, ] +export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' diff --git a/packages/transaction-decoder/src/decoding/log-decode.ts b/packages/transaction-decoder/src/decoding/log-decode.ts index c81a674..03c893c 100644 --- a/packages/transaction-decoder/src/decoding/log-decode.ts +++ b/packages/transaction-decoder/src/decoding/log-decode.ts @@ -1,7 +1,7 @@ -import { type GetTransactionReturnType, type Log, decodeEventLog, getAbiItem, getAddress } from 'viem' +import { Address, type GetTransactionReturnType, type Log, decodeEventLog, getAbiItem, getAddress } from 'viem' import { Effect } from 'effect' import type { DecodedLogEvent, Interaction, RawDecodedLog } from '../types.js' -import { getProxyStorageSlot } from './proxies.js' +import { getProxyImplementation } from './proxies.js' import { getAndCacheAbi } from '../abi-loader.js' import { getAndCacheContractMeta } from '../contract-meta-loader.js' import * as AbiDecoder from './abi-decode.js' @@ -22,14 +22,8 @@ const decodedLog = (transaction: GetTransactionReturnType, logItem: Log) => const chainID = Number(transaction.chainId) const address = getAddress(logItem.address) - let abiAddress = address - - const implementation = yield* getProxyStorageSlot({ address: getAddress(abiAddress), chainID }) - - if (implementation) { - yield* Effect.logDebug(`Proxy implementation found for ${abiAddress} at ${implementation}`) - abiAddress = implementation.address - } + const implementation = yield* getProxyImplementation({ address, chainID }) + const abiAddress = implementation?.address ?? address const [abiItem, contractData] = yield* Effect.all( [ diff --git a/packages/transaction-decoder/src/decoding/proxies.ts b/packages/transaction-decoder/src/decoding/proxies.ts index ceacf86..39b2b83 100644 --- a/packages/transaction-decoder/src/decoding/proxies.ts +++ b/packages/transaction-decoder/src/decoding/proxies.ts @@ -1,13 +1,20 @@ -import { Effect, Request, RequestResolver, Schedule } from 'effect' -import { PublicClient, RPCCallError, RPCFetchError, UnknownNetwork } from '../public-client.js' +import { Effect, PrimaryKey, Request, RequestResolver, Schedule, Schema, SchemaAST } from 'effect' + +import { PublicClient, RPCCallError, RPCFetchError } from '../public-client.js' import { Address, Hex } from 'viem' import { ProxyType } from '../types.js' +import { ZERO_ADDRESS } from './constants.js' interface StorageSlot { type: ProxyType slot: Hex } +interface ProxyResult { + type: ProxyType + address: Address +} + const storageSlots: StorageSlot[] = [ { type: 'eip1967', slot: '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' }, //EIP1967 { type: 'zeppelin', slot: '0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3' }, //zeppelin @@ -16,14 +23,30 @@ const storageSlots: StorageSlot[] = [ const zeroSlot = '0x0000000000000000000000000000000000000000000000000000000000000000' -export interface GetStorageSlot - extends Request.Request<{ type: ProxyType; address: Address } | undefined, UnknownNetwork> { - readonly _tag: 'GetStorageSlot' +export interface GetProxy extends Request.Request { + readonly _tag: 'GetProxy' readonly address: Address readonly chainID: number } -const getStorageSlot = (request: GetStorageSlot, slot: StorageSlot) => +export const GetProxy = Request.tagged('GetProxy') +class SchemaAddress extends Schema.make
(SchemaAST.stringKeyword) {} +class SchemaProxy extends Schema.make(SchemaAST.objectKeyword) {} + +class ProxyLoader extends Schema.TaggedRequest()('ProxyLoader', { + failure: Schema.instanceOf(RPCFetchError), + success: Schema.NullOr(SchemaProxy), + payload: { + address: SchemaAddress, + chainID: Schema.Number, + }, +}) { + [PrimaryKey.symbol]() { + return `proxy::${this.chainID}:${this.address}` + } +} + +const getStorageSlot = (request: ProxyLoader, slot: StorageSlot) => Effect.gen(function* () { const service = yield* PublicClient const { client: publicClient } = yield* service.getPublicClient(request.chainID) @@ -37,7 +60,7 @@ const getStorageSlot = (request: GetStorageSlot, slot: StorageSlot) => }) }) -const ethCall = (request: GetStorageSlot, slot: StorageSlot) => +const ethCall = (request: ProxyLoader, slot: StorageSlot) => Effect.gen(function* () { const service = yield* PublicClient const { client: publicClient } = yield* service.getPublicClient(request.chainID) @@ -49,52 +72,54 @@ const ethCall = (request: GetStorageSlot, slot: StorageSlot) => data: slot.slot, }) )?.data, - catch: () => new RPCCallError('Get storage'), + catch: () => new RPCCallError('Eth call'), }) }) -export const GetStorageSlot = Request.tagged('GetStorageSlot') +export const GetProxyResolver = RequestResolver.fromEffect( + (request: ProxyLoader): Effect.Effect => + Effect.gen(function* () { + // NOTE: Should we make this recursive when we have a Proxy of a Proxy? -export const GetStorageSlotResolver = RequestResolver.fromEffect((request: GetStorageSlot) => - Effect.gen(function* () { - // NOTE: Should we make this recursive when we have a Proxy of a Proxy? - const effects = storageSlots.map((slot) => - Effect.gen(function* () { - const res: { type: ProxyType; address: Hex } | undefined = { type: slot.type, address: '0x' } - - let addressString: Address | undefined - switch (slot.type) { - case 'eip1967': - case 'zeppelin': { - addressString = yield* getStorageSlot(request, slot) - break - } - case 'safe': { - addressString = yield* ethCall(request, slot).pipe(Effect.orElseSucceed(() => undefined)) - break - } - } + const effects = storageSlots.map((slot) => + Effect.gen(function* () { + const res: ProxyResult | undefined = { type: slot.type, address: '0x' } - if (addressString == null || addressString === zeroSlot) return undefined + let address: Hex | undefined + switch (slot.type) { + case 'eip1967': + case 'zeppelin': { + address = yield* getStorageSlot(request, slot) + break + } + case 'safe': { + address = yield* ethCall(request, slot).pipe(Effect.orElseSucceed(() => undefined)) + break + } + } - res.address = ('0x' + addressString.slice(addressString.length - 40)) as Address + if (!address || address === zeroSlot) return undefined - return res - }), - ) + res.address = ('0x' + address.slice(address.length - 40)) as Address + return res + }), + ) - const policy = Schedule.addDelay( - Schedule.recurs(2), // Retry for a maximum of 2 times - () => '100 millis', // Add a delay of 100 milliseconds between retries - ) - const res = yield* Effect.all(effects, { - concurrency: 'inherit', - batching: 'inherit', - }).pipe(Effect.retryOrElse(policy, () => Effect.succeed(undefined))) + const policy = Schedule.addDelay( + Schedule.recurs(2), // Retry for a maximum of 2 times + () => '100 millis', // Add a delay of 100 milliseconds between retries + ) + const res = yield* Effect.all(effects, { + concurrency: 'inherit', + batching: 'inherit', + }).pipe(Effect.retryOrElse(policy, () => Effect.succeed(undefined))) - return res?.find((x) => x != null) - }), + return res?.find((x) => x != null) + }), ).pipe(RequestResolver.contextFromEffect) -export const getProxyStorageSlot = ({ address, chainID }: { address: Address; chainID: number }) => - Effect.request(GetStorageSlot({ address, chainID }), GetStorageSlotResolver).pipe(Effect.withRequestCaching(true)) +export const getProxyImplementation = ({ address, chainID }: { address: Address; chainID: number }) => { + if (address === ZERO_ADDRESS) return Effect.succeed(null) + + return Effect.request(new ProxyLoader({ address, chainID }), GetProxyResolver).pipe(Effect.withRequestCaching(true)) +} diff --git a/packages/transaction-decoder/src/decoding/trace-decode.ts b/packages/transaction-decoder/src/decoding/trace-decode.ts index 0d7f7d9..906cab4 100644 --- a/packages/transaction-decoder/src/decoding/trace-decode.ts +++ b/packages/transaction-decoder/src/decoding/trace-decode.ts @@ -47,7 +47,7 @@ const decodeTraceLog = (call: TraceLog, transaction: GetTransactionReturnType) = return yield* new DecodeError(`Could not decode trace log ${stringify(call)}`) }) -const decodeTraceLogOutput = (call: TraceLog) => +const decodeTraceLogOutput = (call: TraceLog, chainID: number) => Effect.gen(function* () { if (call.result && 'output' in call.result && call.result.output !== '0x') { const data = call.result.output as Hex @@ -61,7 +61,7 @@ const decodeTraceLogOutput = (call: TraceLog) => const abi_ = yield* getAndCacheAbi({ address: '', signature, - chainID: 0, + chainID, }) abi = [...abi, ...abi_] @@ -184,7 +184,13 @@ export function augmentTraceLogs( return [...interactionsWithoutNativeTransfers, ...nativeTransfers] } -export const decodeErrorTrace = ({ trace }: { trace: TraceLog[] }) => +export const decodeErrorTrace = ({ + trace, + transaction, +}: { + trace: TraceLog[] + transaction: GetTransactionReturnType +}) => Effect.gen(function* () { const errorCalls = trace?.filter((call) => call.error != null) if (errorCalls.length === 0) { @@ -212,7 +218,7 @@ export const decodeErrorTrace = ({ trace }: { trace: TraceLog[] }) => message: null, } } - const decodedOutput = yield* decodeTraceLogOutput(call) + const decodedOutput = yield* decodeTraceLogOutput(call, Number(transaction.chainId)) const value = decodedOutput?.params?.[0]?.value?.toString() let message: string | null = null diff --git a/packages/transaction-decoder/src/meta-strategy/proxy-rpc-strategy.ts b/packages/transaction-decoder/src/meta-strategy/proxy-rpc-strategy.ts index cdddf94..4f5a193 100644 --- a/packages/transaction-decoder/src/meta-strategy/proxy-rpc-strategy.ts +++ b/packages/transaction-decoder/src/meta-strategy/proxy-rpc-strategy.ts @@ -1,14 +1,14 @@ import { ContractData, ContractType } from '../types.js' import * as RequestModel from './request-model.js' import { Effect, RequestResolver } from 'effect' -import { getProxyStorageSlot } from '../decoding/proxies.js' +import { getProxyImplementation } from '../decoding/proxies.js' import { PublicClient } from '../public-client.js' export const ProxyRPCStrategyResolver = (publicClientLive: PublicClient) => ({ id: 'proxy-rpc-strategy', resolver: RequestResolver.fromEffect(({ chainId, address }: RequestModel.GetContractMetaStrategy) => Effect.gen(function* () { - const proxyResult = yield* getProxyStorageSlot({ address, chainID: chainId }) + const proxyResult = yield* getProxyImplementation({ address, chainID: chainId }) const { address: implementationAddress, type: proxyType } = proxyResult ?? {} const fail = new RequestModel.ResolveStrategyMetaError('ProxyRPCStrategy', address, chainId) diff --git a/packages/transaction-decoder/src/meta-strategy/request-model.ts b/packages/transaction-decoder/src/meta-strategy/request-model.ts index 0e8478f..e2c2795 100644 --- a/packages/transaction-decoder/src/meta-strategy/request-model.ts +++ b/packages/transaction-decoder/src/meta-strategy/request-model.ts @@ -1,4 +1,4 @@ -import { UnknownNetwork } from '../public-client.js' +import { RPCFetchError, UnknownNetwork } from '../public-client.js' import { ContractData } from '../types.js' import { PrimaryKey, RequestResolver, Schema, SchemaAST } from 'effect' import { Address } from 'viem' @@ -28,7 +28,11 @@ class SchemaContractData extends Schema.make(SchemaAST.objectKeywo export class GetContractMetaStrategy extends Schema.TaggedRequest()( 'GetContractMetaStrategy', { - failure: Schema.Union(Schema.instanceOf(ResolveStrategyMetaError), Schema.instanceOf(UnknownNetwork)), + failure: Schema.Union( + Schema.instanceOf(ResolveStrategyMetaError), + Schema.instanceOf(UnknownNetwork), + Schema.instanceOf(RPCFetchError), + ), success: SchemaContractData, payload: { chainId: Schema.Number, diff --git a/packages/transaction-decoder/src/transaction-decoder.ts b/packages/transaction-decoder/src/transaction-decoder.ts index b597717..1bcb528 100644 --- a/packages/transaction-decoder/src/transaction-decoder.ts +++ b/packages/transaction-decoder/src/transaction-decoder.ts @@ -99,7 +99,7 @@ export const decodeTransaction = ({ ), decodedTrace: decodeTrace({ trace, transaction }), decodedLogs: decodeLogs({ receipt, transaction }), - decodedErrorTrace: decodeErrorTrace({ trace }), + decodedErrorTrace: decodeErrorTrace({ trace, transaction }), }, { batching: true, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0x02a4dda78f1452772d87aa080d65ed7c34785b9d0f4c20aa6c91c51a63ee1fa4.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0x02a4dda78f1452772d87aa080d65ed7c34785b9d0f4c20aa6c91c51a63ee1fa4.snapshot index a36668f..3a8d83c 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0x02a4dda78f1452772d87aa080d65ed7c34785b9d0f4c20aa6c91c51a63ee1fa4.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0x02a4dda78f1452772d87aa080d65ed7c34785b9d0f4c20aa6c91c51a63ee1fa4.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 1, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x0000000000A39bb272e79075ade125fd351887Ac": { "address": "0x0000000000A39bb272e79075ade125fd351887Ac", "chainID": 1, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0x1cf9beb600427c0fef7b4b5794f0f3eccef6a75cec1f1680b9295187effa3788.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0x1cf9beb600427c0fef7b4b5794f0f3eccef6a75cec1f1680b9295187effa3788.snapshot index 5247de3..fe78829 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0x1cf9beb600427c0fef7b4b5794f0f3eccef6a75cec1f1680b9295187effa3788.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0x1cf9beb600427c0fef7b4b5794f0f3eccef6a75cec1f1680b9295187effa3788.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 5, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x58c3c2547084CC1C94130D6fd750A3877c7Ca5D2": { "address": "0x58c3c2547084CC1C94130D6fd750A3877c7Ca5D2", "chainID": 5, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0x65324c58b7c555d7fccfacfaa124f39c64405f6692069ea003ce100f08192bcd.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0x65324c58b7c555d7fccfacfaa124f39c64405f6692069ea003ce100f08192bcd.snapshot index 698b8d5..29ac9b6 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0x65324c58b7c555d7fccfacfaa124f39c64405f6692069ea003ce100f08192bcd.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0x65324c58b7c555d7fccfacfaa124f39c64405f6692069ea003ce100f08192bcd.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 5, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x891D3e3f3C7eB90506D6705E643C53a05D390A3E": { "address": "0x891D3e3f3C7eB90506D6705E643C53a05D390A3E", "chainID": 5, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0x65954673ecca8c3c8939088f2eaa38ddad3cc2a96ab47c6b6a167548cf2da175.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0x65954673ecca8c3c8939088f2eaa38ddad3cc2a96ab47c6b6a167548cf2da175.snapshot index b7d77aa..68efc7b 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0x65954673ecca8c3c8939088f2eaa38ddad3cc2a96ab47c6b6a167548cf2da175.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0x65954673ecca8c3c8939088f2eaa38ddad3cc2a96ab47c6b6a167548cf2da175.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 5, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x2bF4761d2f9002c0a24fBAC3A65B794f0561BB7F": { "address": "0x2bF4761d2f9002c0a24fBAC3A65B794f0561BB7F", "chainID": 5, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0x695ed05f74461801e15d68768b784473de034156a81f12f3485bc157e4ac60c9.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0x695ed05f74461801e15d68768b784473de034156a81f12f3485bc157e4ac60c9.snapshot index 8418ef3..6884cae 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0x695ed05f74461801e15d68768b784473de034156a81f12f3485bc157e4ac60c9.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0x695ed05f74461801e15d68768b784473de034156a81f12f3485bc157e4ac60c9.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 5, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x4BED3aE022FD201AB7185a9BC80cB8Bf9819bb80": { "address": "0x4BED3aE022FD201AB7185a9BC80cB8Bf9819bb80", "chainID": 5, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0x867ee0665a0e37bb52e5c2211b122ee952c358ee1d509c45b1157c2b3be8313c.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0x867ee0665a0e37bb52e5c2211b122ee952c358ee1d509c45b1157c2b3be8313c.snapshot index 9c7cd52..969b146 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0x867ee0665a0e37bb52e5c2211b122ee952c358ee1d509c45b1157c2b3be8313c.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0x867ee0665a0e37bb52e5c2211b122ee952c358ee1d509c45b1157c2b3be8313c.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 5, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x63c640dE6f9963A90AFdFa64fD44Ee97e2169a18": { "address": "0x63c640dE6f9963A90AFdFa64fD44Ee97e2169a18", "chainID": 5, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0xabe682c315f7eb233c02618498b08dddf466513705d6402413016311844d3189.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0xabe682c315f7eb233c02618498b08dddf466513705d6402413016311844d3189.snapshot index 842a4cd..ef2cdb9 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0xabe682c315f7eb233c02618498b08dddf466513705d6402413016311844d3189.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0xabe682c315f7eb233c02618498b08dddf466513705d6402413016311844d3189.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 1, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x2aB047c293fC5b431d2e17A5A0a33467D7Ce3440": { "address": "0x2aB047c293fC5b431d2e17A5A0a33467D7Ce3440", "chainID": 1, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0xbb07f5dbff6c4b7bdd26d0f9e2f7c6d41fd8f6eb5a5697832c45a738518cd284.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0xbb07f5dbff6c4b7bdd26d0f9e2f7c6d41fd8f6eb5a5697832c45a738518cd284.snapshot index 95a1d56..428cb47 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0xbb07f5dbff6c4b7bdd26d0f9e2f7c6d41fd8f6eb5a5697832c45a738518cd284.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0xbb07f5dbff6c4b7bdd26d0f9e2f7c6d41fd8f6eb5a5697832c45a738518cd284.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 1, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x5b87C8323352C57Dac33884154aACE8b3D593A07": { "address": "0x5b87C8323352C57Dac33884154aACE8b3D593A07", "chainID": 1, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0xde9f6210899218e17a3e71661ead5e16da228e168b0572b1ddc30a967968f8f6.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0xde9f6210899218e17a3e71661ead5e16da228e168b0572b1ddc30a967968f8f6.snapshot index 6a846b8..72bb77b 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0xde9f6210899218e17a3e71661ead5e16da228e168b0572b1ddc30a967968f8f6.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0xde9f6210899218e17a3e71661ead5e16da228e168b0572b1ddc30a967968f8f6.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 1, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x018008bfb33d285247A21d44E50697654f754e63": { "address": "0x018008bfb33d285247A21d44E50697654f754e63", "chainID": 1, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0xe6acfd7099db3c9bf94e7dab0052a9363cc9b6a33d91449ccc523bdd5d99861c.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0xe6acfd7099db3c9bf94e7dab0052a9363cc9b6a33d91449ccc523bdd5d99861c.snapshot index 7fd9ec8..36ae972 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0xe6acfd7099db3c9bf94e7dab0052a9363cc9b6a33d91449ccc523bdd5d99861c.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0xe6acfd7099db3c9bf94e7dab0052a9363cc9b6a33d91449ccc523bdd5d99861c.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 1, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x5b87C8323352C57Dac33884154aACE8b3D593A07": { "address": "0x5b87C8323352C57Dac33884154aACE8b3D593A07", "chainID": 1, diff --git a/packages/transaction-decoder/test/snapshots/decoder/0xf852866a9d10ab4713b00f3a012b7e60a48055a6f2cd99ae7efce205c390f710.snapshot b/packages/transaction-decoder/test/snapshots/decoder/0xf852866a9d10ab4713b00f3a012b7e60a48055a6f2cd99ae7efce205c390f710.snapshot index 700b755..af0c242 100644 --- a/packages/transaction-decoder/test/snapshots/decoder/0xf852866a9d10ab4713b00f3a012b7e60a48055a6f2cd99ae7efce205c390f710.snapshot +++ b/packages/transaction-decoder/test/snapshots/decoder/0xf852866a9d10ab4713b00f3a012b7e60a48055a6f2cd99ae7efce205c390f710.snapshot @@ -1,14 +1,5 @@ { "addressesMeta": { - "0x0000000000000000000000000000000000000000": { - "address": "0x0000000000000000000000000000000000000000", - "chainID": 1, - "contractAddress": "0x0000000000000000000000000000000000000000", - "contractName": "Mock ERC20 Contract", - "decimals": 18, - "tokenSymbol": "ERC20", - "type": "ERC20", - }, "0x0000000000A39bb272e79075ade125fd351887Ac": { "address": "0x0000000000A39bb272e79075ade125fd351887Ac", "chainID": 1,