UNPKG

hardhat

Version:

Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

111 lines (97 loc) 3.44 kB
import type { RawInlineOverride } from "./types.js"; import type { TestFunctionConfigOverride } from "@nomicfoundation/edr"; import { assertHardhatInvariant } from "@nomicfoundation/hardhat-errors"; import { bytesIncludesUtf8String } from "@nomicfoundation/hardhat-utils/bytes"; import { getFullyQualifiedName } from "../../../../utils/contract-names.js"; import { HARDHAT_CONFIG_PREFIX, FORGE_CONFIG_PREFIX, KEY_TYPES, } from "./constants.js"; /** * Returns true if the build info bytes contain either of the inline config * prefixes. */ export function buildInfoContainsInlineConfig( buildInfoBytes: Uint8Array, ): boolean { return ( bytesIncludesUtf8String(buildInfoBytes, HARDHAT_CONFIG_PREFIX) || bytesIncludesUtf8String(buildInfoBytes, FORGE_CONFIG_PREFIX) ); } /** * Finds the function selector for a given function name in the methodIdentifiers * map. Matches the first entry whose signature starts with `functionName(`. * Returns the selector prefixed with "0x". */ export function resolveFunctionSelector( methodIdentifiers: Record<string, string>, functionName: string, ): string | undefined { const prefix = `${functionName}(`; for (const [signature, selector] of Object.entries(methodIdentifiers)) { if (signature.startsWith(prefix)) { return `0x${selector}`; } } return undefined; } /** * Converts a validated set of raw overrides into a TestFunctionConfigOverride * object. */ export function buildConfigOverride( overrides: RawInlineOverride[], ): TestFunctionConfigOverride { const config: Record<string, unknown> = {}; const fuzz: Record<string, unknown> = {}; const invariant: Record<string, unknown> = {}; for (const override of overrides) { const expectedType = KEY_TYPES[override.key]; let parsed: number | boolean | string; if (expectedType === "number") { parsed = Number(override.rawValue); } else if (expectedType === "boolean") { parsed = override.rawValue.toLowerCase() === "true"; } else if (expectedType === "string") { // Validation has already proven the surrounding double quotes. parsed = override.rawValue.slice(1, -1); } else { assertHardhatInvariant( false, `Unhandled inline config value type for key ${override.key}`, ); } const dotIndex = override.key.indexOf("."); if (dotIndex === -1) { // Top-level key, like "allowInternalExpectRevert" config[override.key] = parsed; } else { const section = override.key.slice(0, dotIndex); const field = override.key.slice(dotIndex + 1); const target = section === "fuzz" ? fuzz : invariant; target[field] = field === "timeout" ? { time: parsed } : parsed; } } if (Object.keys(fuzz).length > 0) { config.fuzz = fuzz; } if (Object.keys(invariant).length > 0) { config.invariant = invariant; } /* eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Cast is safe because we have validated all keys and value types in the previous step. */ return config as TestFunctionConfigOverride; } /** * Constructs a fully qualified function name, in the format * "source.sol:ContractName#functionName". */ export function getFunctionFqn( inputSourceName: string, contractName: string, functionName: string, ): string { return `${getFullyQualifiedName(inputSourceName, contractName)}#${functionName}`; }