hardhat
Version:
Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.
86 lines • 2.94 kB
JavaScript
import chalk from "chalk";
/**
* Converts an internal FQN (e.g. `"project/contracts/Foo.sol:Foo"` or
* `"npm/@oz/contracts@5.0.0/token/ERC20.sol:ERC20"`) to its user-friendly
* form by stripping the `project/` prefix or npm version segment.
*/
export function getUserFqn(inputFqn) {
if (inputFqn.startsWith("project/")) {
return inputFqn.slice("project/".length);
}
if (inputFqn.startsWith("npm/")) {
const withoutPrefix = inputFqn.slice("npm/".length);
// Match "<pkg>@<version>/<rest>", where <pkg> may be scoped (@scope/pkg)
const match = withoutPrefix.match(/^(@?[^@/]+(?:\/[^@/]+)*)@[^/]+\/(.*)$/);
if (match !== null) {
return `${match[1]}/${match[2]}`;
}
return withoutPrefix;
}
return inputFqn;
}
/**
* Extracts the function name from a Solidity function signature
* (e.g. `"transfer(address,uint256)"` → `"transfer"`).
*/
export function getFunctionName(signature) {
return signature.split("(")[0];
}
/**
* Builds a deterministic string key for grouping gas measurements by
* (contractFqn, proxyChain). Uses null-byte separators to avoid collisions.
*/
export function makeGroupKey(contractFqn, proxyChain) {
if (proxyChain.length === 0) {
return contractFqn;
}
return contractFqn + "\0" + proxyChain.join("\0");
}
/**
* Returns a human-readable proxy label like `"(via Proxy2 → Proxy)"`,
* or `undefined` for direct calls. Strips the last element (the
* implementation) and converts internal FQNs to user-friendly format.
*/
export function getProxyLabel(proxyChain) {
const proxies = proxyChain.slice(0, -1).map(getUserFqn);
if (proxies.length === 0) {
return undefined;
}
return `(via ${proxies.join(" → ")})`;
}
/**
* Returns a display key for a contract entry, appending the proxy label
* when the call went through a proxy chain. Used for table headers and
* JSON object keys.
*/
export function getDisplayKey(userFqn, proxyChain) {
const label = getProxyLabel(proxyChain);
if (label === undefined) {
return userFqn;
}
return `${userFqn} ${label}`;
}
export function avg(values) {
return values.reduce((a, c) => a + c, 0) / values.length;
}
export function median(values) {
const sorted = [...values].sort((a, b) => a - b);
const mid = Math.floor(sorted.length / 2);
return sorted.length % 2 === 1
? sorted[mid]
: (sorted[mid - 1] + sorted[mid]) / 2;
}
export function formatSectionHeader(sectionName, { changedLength, addedLength, removedLength, }) {
const parts = [];
if (changedLength > 0) {
parts.push(`${changedLength} changed`);
}
if (addedLength > 0) {
parts.push(`${addedLength} added`);
}
if (removedLength > 0) {
parts.push(`${removedLength} removed`);
}
return `${sectionName}: ${chalk.gray(parts.join(", "))}`;
}
//# sourceMappingURL=utils.js.map