diff --git a/.changeset/spotty-teeth-show.md b/.changeset/spotty-teeth-show.md new file mode 100644 index 00000000000..7f7f955389f --- /dev/null +++ b/.changeset/spotty-teeth-show.md @@ -0,0 +1,5 @@ +--- +'openzeppelin-solidity': minor +--- + +Migrate test suite and helpers to Hardhat 3 diff --git a/.codecov.yml b/.codecov.yml index 4cec4ef7d5f..bca18179aa4 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -14,3 +14,4 @@ ignore: - "test" - "contracts/mocks" - "contracts/vendor" + - "contracts-exposed" diff --git a/.github/actions/gas-compare/action.yml b/.github/actions/gas-compare/action.yml index 94931d16f20..95eab646436 100644 --- a/.github/actions/gas-compare/action.yml +++ b/.github/actions/gas-compare/action.yml @@ -29,11 +29,10 @@ runs: GITHUB_TOKEN: ${{ inputs.token }} shell: bash continue-on-error: true - id: reference - name: Compare reports - if: steps.reference.outcome == 'success' && github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && hashFiles(inputs.ref_report) != '' run: | - node scripts/checks/compareGasReports.js ${{ inputs.report }} ${{ inputs.ref_report }} >> $GITHUB_STEP_SUMMARY + node scripts/checks/compare-gas-reports.js ${{ inputs.report }} ${{ inputs.ref_report }} >> $GITHUB_STEP_SUMMARY env: STYLE: markdown shell: bash diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 3f5b7db5699..58eeb791e83 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -8,7 +8,7 @@ inputs: foundry: description: Whether to set up Foundry required: false - default: 'on' # 'off' | 'on' | + default: 'off' # 'off' | 'on' | java: description: Whether to set up Java required: false diff --git a/.github/actions/storage-layout/action.yml b/.github/actions/storage-layout/action.yml index 69a649428bc..ea7e201993f 100644 --- a/.github/actions/storage-layout/action.yml +++ b/.github/actions/storage-layout/action.yml @@ -37,9 +37,8 @@ runs: GITHUB_TOKEN: ${{ inputs.token }} shell: bash continue-on-error: true - id: reference - name: Compare layouts - if: steps.reference.outcome == 'success' && github.event_name == 'pull_request' + if: github.event_name == 'pull_request' && hashFiles(inputs.ref_layout) != '' run: | node scripts/checks/compare-layout.js --head ${{ inputs.layout }} --ref ${{ inputs.ref_layout }} shell: bash diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index b7dd5afb50a..3a9dcae405d 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -35,10 +35,14 @@ jobs: GAS: true steps: - uses: actions/checkout@v6 + with: + submodules: recursive - name: Set up environment uses: ./.github/actions/setup + with: + foundry: 'on' # needed by npm run test:pragma - name: Run tests and generate gas report - run: npm run test + run: npm run test -- --gas-stats-json gasReport.json - name: Check linearisation of the inheritance graph run: npm run test:inheritance - name: Check pragma validity @@ -49,6 +53,7 @@ jobs: uses: ./.github/actions/gas-compare with: token: ${{ github.token }} + report: gasReport.json tests-upgradeable: runs-on: ubuntu-latest @@ -57,9 +62,12 @@ jobs: steps: - uses: actions/checkout@v6 with: + submodules: recursive fetch-depth: 0 # Include history so patch conflicts are resolved automatically - name: Set up environment uses: ./.github/actions/setup + with: + foundry: 'on' # needed by npm run test:pragma - name: Copy non-upgradeable contracts as dependency run: | mkdir -p lib/openzeppelin-contracts @@ -78,21 +86,12 @@ jobs: with: token: ${{ github.token }} - tests-foundry: + coverage: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: submodules: recursive - - name: Set up environment - uses: ./.github/actions/setup - - name: Run tests - run: forge test -vvv - - coverage: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v6 - name: Set up environment uses: ./.github/actions/setup - name: Run coverage @@ -105,6 +104,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + submodules: recursive - name: Set up environment uses: ./.github/actions/setup - name: Compile harnesses diff --git a/.github/workflows/formal-verification.yml b/.github/workflows/formal-verification.yml index f8a10cac91c..e6bea02d375 100644 --- a/.github/workflows/formal-verification.yml +++ b/.github/workflows/formal-verification.yml @@ -55,6 +55,7 @@ jobs: - name: Set up environment uses: ./.github/actions/setup with: + foundry: 'on' python: 'on' python-requirements: 'fv-requirements.txt' - name: Run Halmos diff --git a/foundry.toml b/foundry.toml index 3d9b8421ebc..47e068c5b4c 100644 --- a/foundry.toml +++ b/foundry.toml @@ -6,15 +6,4 @@ optimizer_runs = 200 src = 'contracts' out = 'out' libs = ['node_modules', 'lib'] -test = 'test' cache_path = 'cache_forge' -fs_permissions = [{ access = "read", path = "./node_modules/hardhat-predeploy/bin" }] - -[lint] -exclude_lints = ["mixed-case-function", "asm-keccak256", "screaming-snake-case-immutable", "incorrect-shift", "mixed-case-variable"] -ignore = ["./contracts/interfaces/**/*.sol", "./contracts/mocks/Stateless.sol"] -lint_on_build = false - -[fuzz] -runs = 5000 -max_test_rejects = 150000 diff --git a/hardhat.config.js b/hardhat.config.js deleted file mode 100644 index c32c7977a99..00000000000 --- a/hardhat.config.js +++ /dev/null @@ -1,124 +0,0 @@ -/// ENVVAR -// - COMPILER: compiler version (default: 0.8.31) -// - SRC: contracts folder to compile (default: contracts) -// - RUNS: number of optimization runs (default: 200) -// - IR: enable IR compilation (default: false) -// - COVERAGE: enable coverage report (default: false) -// - GAS: enable gas report (default: false) -// - COINMARKETCAP: coinmarketcap api key for USD value in gas report -// - CI: output gas report to file instead of stdout - -const fs = require('fs'); -const path = require('path'); - -const { argv } = require('yargs/yargs')() - .env('') - .options({ - // Compilation settings - compiler: { - alias: 'compileVersion', - type: 'string', - default: '0.8.31', - }, - src: { - alias: 'source', - type: 'string', - default: 'contracts', - }, - runs: { - alias: 'optimizationRuns', - type: 'number', - default: 200, - }, - ir: { - alias: 'enableIR', - type: 'boolean', - default: false, - }, - evm: { - alias: 'evmVersion', - type: 'string', - default: 'osaka', - }, - // Extra modules - coverage: { - type: 'boolean', - default: false, - }, - gas: { - alias: 'enableGasReport', - type: 'boolean', - default: false, - }, - coinmarketcap: { - alias: 'coinmarketcapApiKey', - type: 'string', - }, - }); - -require('@nomicfoundation/hardhat-chai-matchers'); -require('@nomicfoundation/hardhat-ethers'); -require('hardhat-exposed'); -require('hardhat-gas-reporter'); -require('hardhat-ignore-warnings'); -require('hardhat-predeploy'); -require('solidity-coverage'); -require('solidity-docgen'); - -for (const f of fs.readdirSync(path.join(__dirname, 'hardhat'))) { - require(path.join(__dirname, 'hardhat', f)); -} - -/** - * @type import('hardhat/config').HardhatUserConfig - */ -module.exports = { - solidity: { - version: argv.compiler, - settings: { - optimizer: { - enabled: true, - runs: argv.runs, - }, - evmVersion: argv.evm, - viaIR: argv.ir, - outputSelection: { '*': { '*': ['storageLayout'] } }, - }, - }, - warnings: { - 'contracts-exposed/**/*': { - 'code-size': 'off', - 'initcode-size': 'off', - }, - '*': { - 'unused-param': !argv.coverage, // coverage causes unused-param warnings - 'transient-storage': false, - default: 'error', - }, - }, - networks: { - hardhat: { - hardfork: argv.evm, - // Exposed contracts often exceed the maximum contract size. For normal contract, - // we rely on the `code-size` compiler warning, that will cause a compilation error. - allowUnlimitedContractSize: true, - initialBaseFeePerGas: argv.coverage ? 0 : undefined, - }, - }, - exposed: { - imports: true, - initializers: true, - exclude: ['vendor/**/*', '**/*WithInit.sol'], - }, - gasReporter: { - enabled: argv.gas, - showMethodSig: true, - includeBytecodeInJSON: true, - currency: 'USD', - coinmarketcap: argv.coinmarketcap, - }, - paths: { - sources: argv.src, - }, - docgen: require('./docs/config'), -}; diff --git a/hardhat.config.ts b/hardhat.config.ts new file mode 100644 index 00000000000..d23f1ad7dbf --- /dev/null +++ b/hardhat.config.ts @@ -0,0 +1,95 @@ +import { defineConfig } from 'hardhat/config'; + +// Plugins +import hardhatEthers from '@nomicfoundation/hardhat-ethers'; +import hardhatEthersChaiMatchers from '@nomicfoundation/hardhat-ethers-chai-matchers'; +import hardhatIgnoreWarnings from 'hardhat-ignore-warnings'; +import hardhatMocha from '@nomicfoundation/hardhat-mocha'; +import hardhatNetworkHelpers from '@nomicfoundation/hardhat-network-helpers'; +import hardhatPredeploy from 'hardhat-predeploy'; +import hardhatExposed from './hardhat/hardhat-exposed/plugin.ts'; +import hardhatTranspiler from './hardhat/hardhat-transpiler/plugin.ts'; +import hardhatOzContractsHelpers from './hardhat/hardhat-oz-contracts-helpers/plugin.ts'; +import './hardhat/async-test-sanity.js'; + +// Parameters +import yargs from 'yargs/yargs'; +const argv = await yargs() + .env('') + .options({ + compiler: { type: 'string', default: '0.8.31' }, + src: { type: 'string', default: 'contracts' }, + runs: { type: 'number', default: 200 }, + ir: { type: 'boolean', default: false }, + evm: { type: 'string', default: 'osaka' }, + }) + .parse(); + +// Configuration +export default defineConfig({ + plugins: [ + // Imported plugins + hardhatEthers, + hardhatEthersChaiMatchers, + hardhatIgnoreWarnings, + hardhatMocha, + hardhatNetworkHelpers, + hardhatPredeploy, + // Local plugins + hardhatExposed, + hardhatTranspiler, + hardhatOzContractsHelpers, + ], + paths: { + sources: argv.src, + }, + solidity: { + version: argv.compiler, + settings: { + optimizer: { + enabled: true, + runs: argv.runs, + }, + evmVersion: argv.evm, + viaIR: argv.ir, + outputSelection: { '*': { '*': ['storageLayout'] } }, + }, + }, + networks: { + default: { + type: 'edr-simulated', + hardfork: argv.evm, + // Exposed contracts often exceed the maximum contract size. For normal contract, + // we rely on the `code-size` compiler warning, that will cause a compilation error. + allowUnlimitedContractSize: true, + }, + }, + test: { + solidity: { + fuzz: { + runs: 5000, + maxTestRejects: 150000, + }, + fsPermissions: { + readDirectory: ['node_modules/hardhat-predeploy/bin'], + }, + }, + }, + warnings: { + 'npm/**/*': 'off', + 'test/**/*': 'off', + 'contracts-exposed/**/*': { + 'code-size': 'off', + 'initcode-size': 'off', + }, + '*': { + 'transient-storage': 'off', + default: 'error', + }, + }, + exposed: { + initializers: true, + include: ['contracts/**/*.sol'], + exclude: ['**/*WithInit.sol'], + }, +}); diff --git a/hardhat/env-artifacts.js b/hardhat/env-artifacts.js deleted file mode 100644 index e97ae6468e3..00000000000 --- a/hardhat/env-artifacts.js +++ /dev/null @@ -1,29 +0,0 @@ -const { HardhatError } = require('hardhat/internal/core/errors'); - -function isExpectedError(e, suffix) { - // HH700: Artifact not found - from https://hardhat.org/hardhat-runner/docs/errors#HH700 - return HardhatError.isHardhatError(e) && e.number === 700 && suffix !== ''; -} - -// Modifies the artifact require functions so that instead of X it loads the XUpgradeable contract. -// This allows us to run the same test suite on both the original and the transpiled and renamed Upgradeable contracts. -extendEnvironment(hre => { - const suffixes = ['UpgradeableWithInit', 'Upgradeable', '']; - - // Ethers - const originalReadArtifact = hre.artifacts.readArtifact; - hre.artifacts.readArtifact = async function (name) { - for (const suffix of suffixes) { - try { - return await originalReadArtifact.call(this, name + suffix); - } catch (e) { - if (isExpectedError(e, suffix)) { - continue; - } else { - throw e; - } - } - } - throw new Error('Unreachable'); - }; -}); diff --git a/hardhat/hardhat-exposed/hook-handlers/clean.ts b/hardhat/hardhat-exposed/hook-handlers/clean.ts new file mode 100644 index 00000000000..dfe0c71c348 --- /dev/null +++ b/hardhat/hardhat-exposed/hook-handlers/clean.ts @@ -0,0 +1,9 @@ +import fs from 'node:fs/promises'; + +import type { CleanHooks } from 'hardhat/types/hooks'; + +export type * from '../type-extensions.ts'; + +export default async (): Promise> => ({ + onClean: context => fs.rm(context.config.exposed.outDir, { recursive: true, force: true }), +}); diff --git a/hardhat/hardhat-exposed/hook-handlers/config.ts b/hardhat/hardhat-exposed/hook-handlers/config.ts new file mode 100644 index 00000000000..2b5ac87f05d --- /dev/null +++ b/hardhat/hardhat-exposed/hook-handlers/config.ts @@ -0,0 +1,61 @@ +import path from 'node:path'; + +import type { ConfigHooks } from 'hardhat/types/hooks'; + +export type * from '../type-extensions.ts'; + +export default async (): Promise> => ({ + validateUserConfig: async userConfig => { + const results: Array<{ path: string[]; message: string }> = []; + + if (userConfig.exposed?.prefix !== undefined && typeof userConfig.exposed?.prefix !== 'string') { + results.push({ path: ['exposed', 'prefix'], message: 'Expected an optional string.' }); + } + if ( + userConfig.exposed?.exclude !== undefined && + (!Array.isArray(userConfig.exposed.exclude) || userConfig.exposed.exclude.some(e => typeof e !== 'string')) + ) { + results.push({ path: ['exposed', 'exclude'], message: 'Expected an optional string[].' }); + } + if ( + userConfig.exposed?.include !== undefined && + (!Array.isArray(userConfig.exposed.include) || userConfig.exposed.include.some(e => typeof e !== 'string')) + ) { + results.push({ path: ['exposed', 'include'], message: 'Expected an optional string[].' }); + } + if (userConfig.exposed?.outDir !== undefined && typeof userConfig.exposed?.outDir !== 'string') { + results.push({ path: ['exposed', 'outDir'], message: 'Expected an optional string.' }); + } + if (userConfig.exposed?.initializers !== undefined && typeof userConfig.exposed?.initializers !== 'boolean') { + results.push({ path: ['exposed', 'initializers'], message: 'Expected an optional boolean.' }); + } + return results; + }, + + resolveUserConfig: async (userConfig, resolveConfigurationVariable, next) => { + const partiallyResolvedConfig = await next(userConfig, resolveConfigurationVariable); + + const makeAbsolutePath = (p: string) => + path.isAbsolute(p) ? p : path.resolve(partiallyResolvedConfig.paths.root, p); + + const outDir = makeAbsolutePath(userConfig.exposed?.outDir ?? 'contracts-exposed'); + + return { + ...partiallyResolvedConfig, + paths: { + ...partiallyResolvedConfig.paths, + sources: { + ...partiallyResolvedConfig.paths.sources, + solidity: [...partiallyResolvedConfig.paths.sources.solidity, outDir], + }, + }, + exposed: { + prefix: userConfig.exposed?.prefix ?? '$', + exclude: (userConfig.exposed?.exclude ?? []).map(makeAbsolutePath), + include: (userConfig.exposed?.include ?? ['**/*']).map(makeAbsolutePath), + outDir, + initializers: userConfig.exposed?.initializers ?? false, + }, + }; + }, +}); diff --git a/hardhat/hardhat-exposed/internal/build-info.ts b/hardhat/hardhat-exposed/internal/build-info.ts new file mode 100644 index 00000000000..8be806af26e --- /dev/null +++ b/hardhat/hardhat-exposed/internal/build-info.ts @@ -0,0 +1,26 @@ +import type { CompilationJob, SolidityBuildInfo } from 'hardhat/types/solidity'; + +export async function compilationJobToAstOnlyBuildInfo(compilationJob: CompilationJob): Promise { + const originalBuildId = await compilationJob.getBuildId(); + const originalSolcInput = await compilationJob.getSolcInput(); + + return { + _format: 'hh3-sol-build-info-1', + id: originalBuildId + '-ast-only', + solcVersion: compilationJob.solcConfig.version, + solcLongVersion: compilationJob.solcLongVersion, + input: { + ...originalSolcInput, + settings: { + ...originalSolcInput.settings, + optimizer: { enabled: false }, + outputSelection: { + '*': { + '': ['ast'], + }, + }, + }, + }, + userSourceNameMap: compilationJob.dependencyGraph.getRootsUserSourceNameMap(), + }; +} diff --git a/hardhat/hardhat-exposed/internal/expose.ts b/hardhat/hardhat-exposed/internal/expose.ts new file mode 100644 index 00000000000..592d312d2e3 --- /dev/null +++ b/hardhat/hardhat-exposed/internal/expose.ts @@ -0,0 +1,725 @@ +import type { HardhatConfig } from 'hardhat/types/config'; +import type { CompilerOutput, SolidityBuildInfo } from 'hardhat/types/solidity'; + +// AST manipulation +import type { + Visibility, + SourceUnit, + ContractDefinition, + FunctionDefinition, + VariableDeclaration, + StorageLocation, + TypeName, + UserDefinedTypeName, + ModifierDefinition, +} from 'solidity-ast'; +import type { ASTDereferencer } from 'solidity-ast/utils.js'; +import { findAll, astDereferencer } from 'solidity-ast/utils.js'; + +import type { Lines } from './format-lines.ts'; +import { formatLines, spaceBetween } from './format-lines.ts'; +import assert from 'node:assert'; +import path from 'node:path'; + +const exposedVersionPragma = '>=0.6.0'; + +type ExposedFile = { + absolutePath: string; + content: string; +}; + +export function getExposed( + solidityBuildInfo: SolidityBuildInfo, + solcOutput: CompilerOutput, + config: HardhatConfig, +): Map { + const res = new Map(); + const deref = astDereferencer(solcOutput); + + for (const [sourceName, inputSourceName] of Object.entries(solidityBuildInfo.userSourceNameMap)) { + const ast = solcOutput.sources[inputSourceName].ast; + + const exposedFile = getExposedFile(sourceName, inputSourceName, ast, deref, config); + if (exposedFile !== undefined) { + res.set(exposedFile.absolutePath, exposedFile.content); + } + } + + return res; +} + +function getImportPathFromExposedContract( + exposedFileAbsolutePath: string, + importedFileInputSourceName: string, +): string { + return ( + importedFileInputSourceName.startsWith('project/') + ? path.relative(path.dirname(exposedFileAbsolutePath), importedFileInputSourceName.replace(/^project\//, '')) + : importedFileInputSourceName + ).replaceAll(/\\/g, '/'); // Normalize windows paths to unix paths +} + +function getExposedFile( + sourceName: string, + inputSourceName: string, + ast: SourceUnit, + deref: ASTDereferencer, + config: HardhatConfig, +): ExposedFile | undefined { + const exposedFileAbsolutePath = path.join( + config.exposed.outDir, + inputSourceName.startsWith('project/') ? sourceName : inputSourceName.replace('npm:', ''), + ); + + const content = getExposedContent( + exposedFileAbsolutePath, + ast, + deref, + config.exposed.prefix, + config.exposed.initializers, + ); + + return content === undefined ? undefined : { absolutePath: exposedFileAbsolutePath, content }; +} + +function getExposedContent( + exposedFileAbsolutePath: string, + ast: SourceUnit, + deref: ASTDereferencer, + prefix: string, + initializers: boolean, +): string | undefined { + if (prefix === '' || /^\d|[^0-9a-z_$]/i.test(prefix)) { + throw new Error(`Prefix '${prefix}' is not valid`); + } + + const contractPrefix = prefix.replace(/^./, c => c.toUpperCase()); + + const imports = Array.from(getNeededImports(ast, deref), u => + getImportPathFromExposedContract(exposedFileAbsolutePath, u.absolutePath), + ); + + const contracts = [...findAll('ContractDefinition', ast)].filter(c => c.contractKind !== 'interface'); + + if (contracts.length === 0) { + return undefined; + } + + return formatLines( + ...spaceBetween( + ['// SPDX-License-Identifier: UNLICENSED'], + [`pragma solidity ${exposedVersionPragma};`], + imports.map(i => `import "${i}";`), + + ...contracts.map(c => { + const isLibrary = c.contractKind === 'library'; + const contractHeader = [`contract ${contractPrefix}${c.name}`]; + if (!areFunctionsFullyImplemented(c, deref)) { + contractHeader.unshift('abstract'); + } + if (!isLibrary) { + contractHeader.push(`is ${c.name}`); + } + contractHeader.push('{'); + + const subset: Visibility[] = isLibrary ? ['internal', 'public', 'external'] : ['internal']; + + const hasReceiveFunction = getFunctions(c, deref, ['external']).some(fn => fn.kind === 'receive'); + const externalizableVariables = getVariables(c, deref, subset).filter( + v => + (v.typeName?.nodeType !== 'UserDefinedTypeName' && v.typeName?.nodeType !== 'ArrayTypeName') || + isTypeExternalizable(v.typeName, deref), + ); + const modifiers = getModifiers(c, deref); + const externalizableFunctions = getFunctions(c, deref, subset).filter(f => isExternalizable(f, deref)); + const returnedEventFunctions = externalizableFunctions.filter(fn => isNonViewWithReturns(fn)); + + // Pre-compute arguments per function/modifier to avoid redundant AST traversals + const argsCache = new Map(); + for (const fn of externalizableFunctions) { + argsCache.set(fn.id, getFunctionArguments(fn, c, deref)); + } + for (const m of modifiers) { + argsCache.set(m.id, getFunctionArguments(m, c, deref)); + } + + const clashingFunctions: Record = {}; + for (const fn of externalizableFunctions) { + const id = getFunctionIdFromArgs(fn, argsCache.get(fn.id)!); + clashingFunctions[id] ??= 0; + clashingFunctions[id] += 1; + } + + const clashingEvents: Record = {}; + for (const fn of returnedEventFunctions) { + clashingEvents[fn.name] ??= 0; + clashingEvents[fn.name]! += 1; + } + + const allStorageArgs = getAllStorageArgumentsFromCache([...externalizableFunctions, ...modifiers], argsCache); + + return [ + contractHeader.join(' '), + [`bytes32 public constant __hh_exposed_bytecode_marker = "hardhat-exposed";\n`], + spaceBetween( + // slots for storage function parameters + ...allStorageArgs.map(a => [`mapping(uint256 => ${a.storageType}) internal ${prefix}${a.storageVar};`]), + // events for internal returns + ...returnedEventFunctions.map(fn => { + const fnArgs = argsCache.get(fn.id)!; + const evName = + clashingEvents[fn.name] === 1 ? fn.name : getFunctionNameQualifiedFromArgs(fn, fnArgs, false); + const params = getFunctionReturnParameters(fn, c, deref, null); + return [`event return${prefix}${evName}(${params.map(printArgument).join(', ')});`]; + }), + // constructor + makeConstructor(c, deref, initializers), + // accessor to internal variables + ...externalizableVariables.map(v => { + const varArgs = getVarGetterArgs(v, c, deref); + return [ + [ + 'function', + `${prefix}${v.name}(${varArgs.map(printArgument).join(', ')})`, + 'external', + v.mutability === 'mutable' || (v.mutability === 'immutable' && !v.value) ? 'view' : 'pure', + 'returns', + `(${getVarGetterReturnType(v, c, deref)})`, + '{', + ].join(' '), + [`return ${isLibrary ? c.name + '.' : ''}${v.name}${varArgs.map(a => `[${a.name}]`).join('')};`], + '}', + ]; + }), + // modifiers + ...modifiers.map(m => { + const fnArgs = argsCache.get(m.id)!; + + // function header + const header = [ + 'function', + `${prefix}${m.name}(${fnArgs.map(printArgument).join(', ')})`, + 'external', + 'payable', + `${m.name}(${fnArgs.map(a => (a.storageVar ? `${prefix}${a.storageVar}[${a.name}]` : a.name)).join(', ')})`, + '{}', + ]; + + return [header.join(' ')]; + }), + // external functions + ...externalizableFunctions.map(fn => { + const fnArgs = argsCache.get(fn.id)!; + const fnName = + clashingFunctions[getFunctionIdFromArgs(fn, fnArgs)] === 1 + ? fn.name + : getFunctionNameQualifiedFromArgs(fn, fnArgs, true); + const fnRets = getFunctionReturnParameters(fn, c, deref); + const evName = + isNonViewWithReturns(fn) && + (clashingEvents[fn.name] === 1 ? fn.name : getFunctionNameQualifiedFromArgs(fn, fnArgs, false)); + + // function header + const header = ['function', `${prefix}${fnName}(${fnArgs.map(printArgument)})`, 'external']; + + if (fn.stateMutability === 'nonpayable') { + header.push('payable'); + } else if (fn.stateMutability === 'pure' && fnArgs.some(a => a.storageVar)) { + header.push('view'); + } else { + header.push(fn.stateMutability); + } + + if (fn.returnParameters.parameters.length > 0) { + header.push(`returns (${fnRets.map(printArgument).join(', ')})`); + } + + header.push('{'); + + // function body + const body = [ + (fnRets.length === 0 ? '' : `(${fnRets.map(p => p.name).join(', ')}) = `) + + `${isLibrary ? c.name : 'super'}.${fn.name}(${fnArgs.map(a => (a.storageVar ? `${prefix}${a.storageVar}[${a.name}]` : a.name))});`, + ]; + + if (evName) { + body.push(`emit return${prefix}${evName}(${fnRets.map(p => p.name).join(', ')});`); + } + + // return function + return [header.join(' '), body, `}`]; + }), + // receive function + !hasReceiveFunction ? ['receive() external payable {}'] : [], + ), + `}`, + ]; + }), + ), + ); +} + +// Note this is not the same as contract.fullyImplemented, because this does +// not consider missing constructor calls. We don't use contract.abstract +// because even if a user declares a contract abstract, we want to make it +// concrete if it is possible. +function areFunctionsFullyImplemented(contract: ContractDefinition, deref: ASTDereferencer): boolean { + const parents = contract.linearizedBaseContracts.map(deref('ContractDefinition')); + const abstractFunctionIds = new Set( + parents.flatMap(p => [...findAll('FunctionDefinition', p)].filter(f => !f.implemented).map(f => f.id)), + ); + for (const p of parents) { + for (const f of findAll(['FunctionDefinition', 'VariableDeclaration'], p)) { + for (const b of f.baseFunctions ?? []) { + abstractFunctionIds.delete(b); + } + } + } + return abstractFunctionIds.size === 0; +} + +function getFunctionIdFromArgs(fn: FunctionDefinition, args: Argument[]): string { + return fn.name + args.map(a => a.abiType).join(','); +} + +function getFunctionNameQualifiedFromArgs(fn: FunctionDefinition, args: Argument[], onlyConflicting: boolean): string { + return ( + fn.name + + args + .filter(a => !onlyConflicting || a.type !== a.abiType || a.storageType !== undefined) + .map(arg => arg.storageType ?? arg.type) + .map(type => type.replace(/ .*/, '').replace(/[^0-9a-zA-Z$_]+/g, '_')) // sanitize + .join('_') + .replace(/^./, '_$&') + ); +} + +function makeConstructor(contract: ContractDefinition, deref: ASTDereferencer, initializers: boolean): Lines[] { + const parents = contract.linearizedBaseContracts.map(deref('ContractDefinition')).reverse(); + + const constructors = new Map( + parents + .map(p => getConstructor(p, initializers)) + .filter(notNull) + .map(c => [c.scope, c]), + ); + + const initializedParents = new Set(); + + for (const p of parents) { + for (const c of p.baseContracts) { + if (c.arguments?.length) { + initializedParents.add(c.baseName.referencedDeclaration); + } + } + + const ctor = constructors.get(p.id); + + if (ctor) { + if (ctor.kind === 'constructor') { + for (const m of ctor.modifiers) { + if (m.modifierName.referencedDeclaration != undefined) { + initializedParents.add(m.modifierName.referencedDeclaration); + } + } + } + + if (initializers) { + for (const fnCall of findAll('FunctionCall', ctor)) { + if (fnCall.expression.nodeType === 'Identifier' && isInitializerName(fnCall.expression.name, 'any')) { + const fnDef = deref('FunctionDefinition', fnCall.expression.referencedDeclaration!); + if (fnDef.scope !== p.id) { + initializedParents.add(fnDef.scope); + } + } + } + } + } + } + + const uninitializedParents = parents.filter( + c => c.contractKind === 'contract' && constructors.has(c.id) && !initializedParents.has(c.id), + ); + + const missingArguments = new Map(); // name -> type + const parentArguments = new Map(); + + for (const c of uninitializedParents) { + const args = []; + for (const a of constructors.get(c.id)?.parameters.parameters ?? []) { + const name = missingArguments.has(a.name) ? `${c.name}_${a.name}` : a.name; + const type = getVarType(a, c, deref, 'memory'); + missingArguments.set(name, type); + args.push(name); + } + parentArguments.set(c.name, args); + } + + const parentConstructorCalls = []; + const parentInitializerCalls = []; + + for (const p of uninitializedParents) { + const ctor = constructors.get(p.id); + if (ctor) { + const params = mustGet(parentArguments, p.name).join(', '); + if (ctor.kind === 'constructor') { + if (ctor.parameters.parameters.length) { + parentConstructorCalls.push(`${p.name}(${params})`); + } + } else { + parentInitializerCalls.push(`${ctor.name}(${params})`); + } + } + } + + return [ + [ + `constructor(${[...missingArguments].map(([name, type]) => `${type} ${name}`).join(', ')})`, + ...parentConstructorCalls, + ...(parentInitializerCalls.length ? ['initializer'] : []), + 'payable', + '{', + ].join(' '), + parentInitializerCalls.map(e => `${e};`), + '}', + ]; +} + +function getConstructor(contract: ContractDefinition, initializers: boolean): FunctionDefinition | undefined { + let ctor; + let init; + + for (const fnDef of findAll('FunctionDefinition', contract)) { + if (fnDef.kind === 'constructor') { + ctor = fnDef; + if (!initializers) break; + } + if (initializers && isInitializerName(fnDef.name)) { + init = fnDef; + if (ctor) break; + } + } + return init || ctor; +} + +function isInitializerName(fnName: string, kind?: 'unchained' | 'any'): boolean { + const m = fnName.match(/^__[a-zA-Z0-9$_]+_init(_unchained)?$/); + const isUnchained = m?.[1] === '_unchained'; + const wantsUnchained = kind === 'unchained'; + return m !== null && (kind === 'any' || isUnchained === wantsUnchained); +} + +function notNull(value: T): value is NonNullable { + return value != undefined; +} + +function isExternalizable(fnDef: FunctionDefinition, deref: ASTDereferencer): boolean { + return ( + fnDef.kind !== 'constructor' && + fnDef.visibility !== 'private' && + fnDef.implemented && + !fnDef.parameters.parameters.some(p => p.typeName?.nodeType === 'FunctionTypeName') && + fnDef.returnParameters.parameters.every(p => isTypeExternalizable(p.typeName, deref)) + ); +} + +function isTypeExternalizable(typeName: TypeName | null | undefined, deref: ASTDereferencer): boolean { + if (typeName == undefined) { + return true; + } else if (typeName.nodeType === 'UserDefinedTypeName') { + const typeDef = derefUserDefinedTypeName(deref, typeName); + if (typeDef.nodeType !== 'StructDefinition') { + return true; + } else { + return typeDef.members.every(m => isTypeExternalizable(m.typeName, deref)); + } + } else if (typeName.nodeType === 'ArrayTypeName' && typeName.length != undefined) { + const value = typeName.length.typeDescriptions.typeIdentifier?.match(/^t_rational_([^_]*)_by_1$/)?.[1]; + return value !== undefined && parseInt(value) < 2 ** 27; + } else { + return typeName.nodeType !== 'Mapping' && typeName.nodeType !== 'FunctionTypeName'; + } +} + +function isNonViewWithReturns(fnDef: FunctionDefinition): boolean { + return ['payable', 'nonpayable'].includes(fnDef.stateMutability) && fnDef.returnParameters.parameters.length > 0; +} + +interface Argument { + type: string; + name: string; + abiType: string; + storageVar?: string; + storageType?: string; +} + +const printArgument = (arg: Argument) => `${arg.type} ${arg.name}`; + +function getFunctionArguments( + fnDef: FunctionDefinition | ModifierDefinition, + context: ContractDefinition, + deref: ASTDereferencer, +): Argument[] { + return fnDef.parameters.parameters.map((p, i) => { + const name = p.name || `arg${i}`; + if (p.storageLocation === 'storage') { + const storageType = getVarType(p, context, deref, null); + const storageVar = 'v_' + storageType.replace(/[^0-9a-zA-Z$_]+/g, '_'); + // The argument is an index to an array in storage. + const type = 'uint256'; + return { name, type, abiType: type, storageVar, storageType }; + } else { + const type = getVarType(p, context, deref, 'calldata'); + const abiType = getVarAbiType(p, context, deref, 'calldata'); + return { name, type, abiType }; + } + }); +} + +function getAllStorageArgumentsFromCache( + fns: (FunctionDefinition | ModifierDefinition)[], + argsCache: Map, +): Required[] { + const storageArgs = fns.flatMap(fn => + (argsCache.get(fn.id) ?? []).filter((a): a is Required => !!(a.storageVar && a.storageType)), + ); + return [...new Map(storageArgs.map(a => [a.storageVar, a])).values()]; +} + +function getFunctionReturnParameters( + fnDef: FunctionDefinition, + context: ContractDefinition, + deref: ASTDereferencer, + location: StorageLocation | null = 'memory', +): Argument[] { + return fnDef.returnParameters.parameters.map((p, i) => { + const name = p.name || `ret${i}`; + const type = getVarType(p, context, deref, location); + const abiType = getVarAbiType(p, context, deref, location); + return { name, type, abiType }; + }); +} + +function getVarType( + varDecl: VariableDeclaration, + context: ContractDefinition, + deref: ASTDereferencer, + location: StorageLocation | null = varDecl.storageLocation, +): string { + if (!varDecl.typeName) { + throw new Error('Missing type information'); + } + return getType(varDecl.typeName, context, deref, location); +} + +function getType( + typeName: TypeName, + context: ContractDefinition, + deref: ASTDereferencer, + location: StorageLocation | null, +): string { + const { typeString, typeIdentifier } = typeName.typeDescriptions; + if (typeof typeString !== 'string' || typeof typeIdentifier !== 'string') { + throw new Error('Missing type information'); + } + + let type = + typeString.replace(/^(struct|enum|contract) /, '') + + (typeIdentifier.endsWith('_ptr') && location ? ` ${location}` : ''); + + const typeScopeMatch = type.match(/^([a-zA-Z0-9_$]+)\./); + if (context.contractKind !== 'library' && typeScopeMatch) { + const [, typeScope] = typeScopeMatch; + + const isScopeImplicit = context.linearizedBaseContracts.some( + c => deref('ContractDefinition', c).name === typeScope, + ); + + if (isScopeImplicit) { + type = type.replace(`${typeScope}.`, ''); + } + } + + return type; +} + +function getVarAbiType( + varDecl: VariableDeclaration, + context: ContractDefinition, + deref: ASTDereferencer, + location: StorageLocation | null = varDecl.storageLocation, +): string { + if (!varDecl.typeName) { + throw new Error('Missing type information'); + } + return getAbiType(varDecl.typeName, context, deref, location); +} + +function getAbiType( + typeName: TypeName, + context: ContractDefinition, + deref: ASTDereferencer, + location: StorageLocation | null, +): string { + switch (typeName.nodeType) { + case 'ElementaryTypeName': + case 'ArrayTypeName': + const { typeString } = typeName.typeDescriptions; + assert(typeString != undefined); + return typeString; + + case 'UserDefinedTypeName': + const typeDef = derefUserDefinedTypeName(deref, typeName); + switch (typeDef.nodeType) { + case 'UserDefinedValueTypeDefinition': + const { typeString } = typeDef.underlyingType.typeDescriptions; + assert(typeString != undefined); + return typeString; + + case 'EnumDefinition': + assert(typeDef.members.length < 256); + return 'uint8'; + + case 'ContractDefinition': + return 'address'; + + case 'StructDefinition': + if (location === 'storage') { + throw new Error('Unexpected error'); // is treated separately in getFunctionArguments + } else { + return '(' + typeDef.members.map(v => getVarAbiType(v, context, deref, location)).join(',') + ')'; + } + } + + default: + throw new Error('Unknown ABI type'); + } +} + +function getVariables( + contract: ContractDefinition, + deref: ASTDereferencer, + subset?: Visibility[], +): VariableDeclaration[] { + const parents = contract.linearizedBaseContracts.map(deref('ContractDefinition')); + + const res = []; + + for (const parent of parents) { + for (const v of findAll('VariableDeclaration', parent)) { + if (v.stateVariable && (!subset || subset.includes(v.visibility))) { + res.push(v); + } + } + } + + return res; +} + +function getVarGetterArgs(v: VariableDeclaration, context: ContractDefinition, deref: ASTDereferencer): Argument[] { + if (!v.typeName) { + throw new Error('missing typenName'); + } + const types = []; + for (let t = v.typeName; t.nodeType === 'Mapping'; t = t.valueType) { + types.push({ + name: `arg${types.length}`, + type: getType(t.keyType, context, deref, 'memory'), + abiType: getAbiType(t.keyType, context, deref, 'memory'), + }); + } + return types; +} + +function getVarGetterReturnType(v: VariableDeclaration, context: ContractDefinition, deref: ASTDereferencer): string { + if (!v.typeName) { + throw new Error('missing typenName'); + } + let t = v.typeName; + while (t.nodeType === 'Mapping') { + t = t.valueType; + } + return getType(t, context, deref, 'memory'); +} + +function getFunctions( + contract: ContractDefinition, + deref: ASTDereferencer, + subset?: Visibility[], +): FunctionDefinition[] { + const parents = contract.linearizedBaseContracts.map(deref('ContractDefinition')); + + const overridden = new Set(); + const res = []; + + for (const parent of parents) { + for (const fn of findAll('FunctionDefinition', parent)) { + if (!overridden.has(fn.id) && (!subset || subset.includes(fn.visibility))) { + res.push(fn); + } + for (const b of fn.baseFunctions ?? []) { + overridden.add(b); + } + } + } + + return res; +} + +function getModifiers(contract: ContractDefinition, deref: ASTDereferencer): ModifierDefinition[] { + const parents = contract.linearizedBaseContracts.map(deref('ContractDefinition')); + + const overridden = new Set(); + const res = []; + + for (const parent of parents) { + for (const m of findAll('ModifierDefinition', parent)) { + if (!overridden.has(m.id)) { + res.push(m); + } + for (const b of m.baseModifiers ?? []) { + overridden.add(b); + } + } + } + + return res; +} + +function* getNeededImports(ast: SourceUnit, deref: ASTDereferencer): Iterable { + const needed = new Set( + [ast].concat( + [...findAll('ContractDefinition', ast)].flatMap(c => + c.linearizedBaseContracts.map(p => { + const { sourceUnit } = deref.withSourceUnit('ContractDefinition', p); + return sourceUnit; + }), + ), + ), + ); + + for (const n of needed) { + yield n; + + for (const imp of findAll('ImportDirective', n)) { + if (imp.symbolAliases.length > 0) { + needed.add(deref('SourceUnit', imp.sourceUnit)); + } + } + } +} + +function mustGet(map: Map, key: K): V { + const value = map.get(key); + if (value === undefined) { + throw new Error('Key not found'); + } + return value; +} + +function derefUserDefinedTypeName(deref: ASTDereferencer, typeName: UserDefinedTypeName) { + return deref( + ['StructDefinition', 'EnumDefinition', 'ContractDefinition', 'UserDefinedValueTypeDefinition'], + typeName.referencedDeclaration, + ); +} diff --git a/hardhat/hardhat-exposed/internal/format-lines.ts b/hardhat/hardhat-exposed/internal/format-lines.ts new file mode 100644 index 00000000000..c7418b1afe6 --- /dev/null +++ b/hardhat/hardhat-exposed/internal/format-lines.ts @@ -0,0 +1,26 @@ +export type Lines = string | typeof whitespace | Lines[]; + +const whitespace: string = '\xa0'; //Symbol('whitespace'); + +export function formatLines(...lines: Lines[]): string { + return [...indentEach(0, lines)].join('\n') + '\n'; +} + +function* indentEach(indent: number, lines: Lines[]): Generator { + for (const line of lines) { + if (line === whitespace) { + yield ''; + } else if (Array.isArray(line)) { + yield* indentEach(indent + 1, line); + } else { + yield ' '.repeat(indent) + line; + } + } +} + +export function spaceBetween(...lines: Lines[][]): Lines[] { + return lines + .filter(l => l.length > 0) + .flatMap(l => [whitespace, ...l]) + .slice(1); +} diff --git a/hardhat/hardhat-exposed/internal/types.ts b/hardhat/hardhat-exposed/internal/types.ts new file mode 100644 index 00000000000..d4627ea8275 --- /dev/null +++ b/hardhat/hardhat-exposed/internal/types.ts @@ -0,0 +1,15 @@ +export interface ExposedUserConfig { + prefix?: string; + exclude?: string[]; + include?: string[]; + outDir?: string; + initializers?: boolean; +} + +export interface ExposedConfig { + prefix: string; + exclude: string[]; + include: string[]; + outDir: string; + initializers: boolean; +} diff --git a/hardhat/hardhat-exposed/plugin.ts b/hardhat/hardhat-exposed/plugin.ts new file mode 100644 index 00000000000..8fe4897db26 --- /dev/null +++ b/hardhat/hardhat-exposed/plugin.ts @@ -0,0 +1,24 @@ +import type { HardhatPlugin } from 'hardhat/types/plugins'; +import { overrideTask, task } from 'hardhat/config'; + +export type * from './type-extensions.ts'; + +const hardhatExposedPlugin: HardhatPlugin = { + id: 'hardhat-exposed', + hookHandlers: { + clean: () => import('./hook-handlers/clean.ts'), + config: () => import('./hook-handlers/config.ts'), + }, + tasks: [ + overrideTask('build') + .addFlag({ name: 'noExpose', description: 'Skip generation of exposed contracts.' }) + .setAction(() => import('./tasks/build.ts')) + .build(), + task('generate-exposed-contracts', 'Generates the exposed contracts') + .addFlag({ name: 'force', description: 'Generate all contracts, ignoring the compilation cache' }) + .setAction(() => import('./tasks/generate-exposed-contracts.ts')) + .build(), + ], +}; + +export default hardhatExposedPlugin; diff --git a/hardhat/hardhat-exposed/tasks/build.ts b/hardhat/hardhat-exposed/tasks/build.ts new file mode 100644 index 00000000000..b344b20bc9c --- /dev/null +++ b/hardhat/hardhat-exposed/tasks/build.ts @@ -0,0 +1,18 @@ +import type { HardhatRuntimeEnvironment } from 'hardhat/types/hre'; +import type { TaskArguments } from 'hardhat/types/tasks'; + +export interface BuildOverrideArguments { + noExpose: boolean; +} + +export default async function build( + args: BuildOverrideArguments, + hre: HardhatRuntimeEnvironment, + runSuper: (taskArguments: TaskArguments) => Promise, +) { + if (args.noExpose !== true) { + await hre.tasks.getTask('generate-exposed-contracts').run({ force: 'force' in args ? args.force : false }); + } + + return await runSuper(args); +} diff --git a/hardhat/hardhat-exposed/tasks/generate-exposed-contracts.ts b/hardhat/hardhat-exposed/tasks/generate-exposed-contracts.ts new file mode 100644 index 00000000000..f44df90c36c --- /dev/null +++ b/hardhat/hardhat-exposed/tasks/generate-exposed-contracts.ts @@ -0,0 +1,104 @@ +import { createSpinner } from '@nomicfoundation/hardhat-utils/spinner'; + +import type { HardhatRuntimeEnvironment } from 'hardhat/types/hre'; +import type { SolidityBuildInfo } from 'hardhat/types/solidity'; +import type { Result } from 'hardhat/types/utils'; +import assert from 'node:assert'; +import path from 'node:path'; +import fs from 'node:fs'; +import { getExposed } from '../internal/expose.ts'; +import { compilationJobToAstOnlyBuildInfo } from '../internal/build-info.ts'; +import { errorResult, successfulResult } from 'hardhat/utils/result'; + +export type * from '../type-extensions'; + +export interface GenerateExposedContractsArguments { + force: boolean; +} + +export default async function generateExposedContracts( + args: GenerateExposedContractsArguments, + hre: HardhatRuntimeEnvironment, +): Promise> { + const rootPaths = await hre.solidity.getRootFilePaths(); + + const includes = async (rootPath: string) => + hre.config.exposed.include.some(p => path.matchesGlob(rootPath, p)) && + !hre.config.exposed.exclude.some(p => path.matchesGlob(rootPath, p)) && + !rootPath.startsWith(hre.config.exposed.outDir) && + (await hre.solidity.getScope(rootPath)) === 'contracts'; + + const inclusionResults = await Promise.all(rootPaths.map(root => includes(root))); + const rootPathsToExpose = rootPaths.filter((root, i) => { + if (!inclusionResults[i]) return false; + + // sanity check: No exposed contract should be a root file to expose + assert( + !root.startsWith(hre.config.exposed.outDir), + 'A root file to be exposed must not be part of the in the hardhat-exposed outDir', + ); + + return true; + }); + + const compilationJobs = await hre.solidity.getCompilationJobs(rootPathsToExpose, { force: args.force }); + + if (!compilationJobs.success) { + console.error("Failed to generate exposed contracts: couldn't get the compilations jobs"); + console.error(compilationJobs.formattedReason); + return errorResult(); + } + + const filteredRootPathsToExpose = rootPathsToExpose.filter(p => !compilationJobs.cacheHits.has(p) || args.force); + + if (filteredRootPathsToExpose.length === 0) { + return successfulResult(); + } + + const astOnlyBuildInfos = new Set(); + const compilationJobIdToAstOnlyBuildInfo = new Map(); + for (const rootPath of filteredRootPathsToExpose) { + const compilationJob = compilationJobs.compilationJobsPerFile.get(rootPath)!; + const compilationJobId = await compilationJob.getBuildId(); + + if (compilationJobIdToAstOnlyBuildInfo.has(compilationJobId)) { + continue; + } + + const astOnlyBuildInfo = await compilationJobToAstOnlyBuildInfo(compilationJob); + compilationJobIdToAstOnlyBuildInfo.set(compilationJobId, astOnlyBuildInfo); + astOnlyBuildInfos.add(astOnlyBuildInfo); + } + + const exposedPaths: Set = new Set(); + const spinner = createSpinner({ text: `Generating exposed contracts...` }); + spinner.start(); + + try { + for (const buildInfo of astOnlyBuildInfos) { + // Sanity check: No exposed contract should be included as part of the + // sources of the ast-only build-info + for (const inputSourceName of Object.keys(buildInfo.input.sources)) { + assert( + !inputSourceName.startsWith(hre.config.exposed.outDir), + 'No exposed contract should be included in the ast-only compilation jobs', + ); + } + + const buildOutput = await hre.solidity.compileBuildInfo(buildInfo); + + const exposed = await getExposed(buildInfo, buildOutput, hre.config); + + for (const [exposedPath, exposedContent] of exposed) { + fs.mkdirSync(path.dirname(exposedPath), { recursive: true }); + fs.writeFileSync(exposedPath, exposedContent); + exposedPaths.add(exposedPath); + } + } + } finally { + spinner.stop(); + } + + console.log(`Generated ${exposedPaths.size} exposed contract files`); + return successfulResult(); +} diff --git a/hardhat/hardhat-exposed/type-extensions.ts b/hardhat/hardhat-exposed/type-extensions.ts new file mode 100644 index 00000000000..e158f545519 --- /dev/null +++ b/hardhat/hardhat-exposed/type-extensions.ts @@ -0,0 +1,13 @@ +import 'hardhat/types/config'; + +import type { ExposedUserConfig, ExposedConfig } from './internal/types.ts'; + +declare module 'hardhat/types/config' { + export interface HardhatUserConfig { + exposed?: ExposedUserConfig; + } + + export interface HardhatConfig { + exposed: ExposedConfig; + } +} diff --git a/hardhat/hardhat-oz-contracts-helpers/hook-handlers/hre.ts b/hardhat/hardhat-oz-contracts-helpers/hook-handlers/hre.ts new file mode 100644 index 00000000000..a24e66ccefc --- /dev/null +++ b/hardhat/hardhat-oz-contracts-helpers/hook-handlers/hre.ts @@ -0,0 +1,26 @@ +import type { HardhatRuntimeEnvironmentHooks, HookContext } from 'hardhat/types/hooks'; +import type { HardhatRuntimeEnvironment } from 'hardhat/types/hre'; +import type { ArtifactManager } from 'hardhat/types/artifacts'; + +const suffixes = ['UpgradeableWithInit', 'Upgradeable']; + +const overrideReadArtifact = + (artifactExists: ArtifactManager['artifactExists'], runSuper: ArtifactManager['readArtifact']) => + (contractNameOrFullyQualifiedName: ContractNameT) => + suffixes + .map(suffix => contractNameOrFullyQualifiedName + suffix) + .reduce>( + (acc, artifactWithSuffix) => + acc.then(result => result || artifactExists(artifactWithSuffix).then(exists => exists && artifactWithSuffix)), + Promise.resolve(false), + ) + .then(artifactWithSuffix => runSuper((artifactWithSuffix || contractNameOrFullyQualifiedName) as ContractNameT)); + +export default async (): Promise> => ({ + created: async (context: HookContext, hre: HardhatRuntimeEnvironment): Promise => { + hre.artifacts.readArtifact = overrideReadArtifact( + hre.artifacts.artifactExists.bind(hre.artifacts), + hre.artifacts.readArtifact.bind(hre.artifacts), + ); + }, +}); diff --git a/hardhat/hardhat-oz-contracts-helpers/hook-handlers/network.ts b/hardhat/hardhat-oz-contracts-helpers/hook-handlers/network.ts new file mode 100644 index 00000000000..15e6337b7d9 --- /dev/null +++ b/hardhat/hardhat-oz-contracts-helpers/hook-handlers/network.ts @@ -0,0 +1,36 @@ +import type { HookContext, NetworkHooks } from 'hardhat/types/hooks'; +import type { ChainType, NetworkConnection } from 'hardhat/types/network'; + +import { impersonate } from '../../../test/helpers/account.js'; +import { getLocalChain } from '../../../test/helpers/chains.js'; +import { getSlot, getAddressInSlot, setSlot } from '../../../test/helpers/storage.js'; +import { clock, clockFromReceipt, increaseBy, increaseTo, duration } from '../../../test/helpers/time.js'; + +export type * from '../type-extensions.js'; + +export default async (): Promise> => ({ + newConnection: async ( + context: HookContext, + next: (nextContext: HookContext) => Promise>, + ): Promise> => + next(context).then(async connection => + Object.assign(connection, { + helpers: { + chain: await getLocalChain(connection.provider), + impersonate: impersonate(connection), + storage: { + getSlot: getSlot(connection), + getAddressInSlot: getAddressInSlot(connection), + setSlot: setSlot(connection), + }, + time: { + clock: clock(connection), + clockFromReceipt: clockFromReceipt(connection), + increaseBy: increaseBy(connection), + increaseTo: increaseTo(connection), + duration: duration(connection), + }, + }, + }), + ), +}); diff --git a/hardhat/hardhat-oz-contracts-helpers/hook-handlers/test.ts b/hardhat/hardhat-oz-contracts-helpers/hook-handlers/test.ts new file mode 100644 index 00000000000..c4495cba7d3 --- /dev/null +++ b/hardhat/hardhat-oz-contracts-helpers/hook-handlers/test.ts @@ -0,0 +1,24 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +import type { TestHooks, HookContext } from 'hardhat/types/hooks'; + +const ignoredIfProxy: Set = new Set([ + 'test/proxy/beacon/BeaconProxy.test.js', + 'test/proxy/beacon/UpgradeableBeacon.test.js', + 'test/proxy/ERC1967/ERC1967Proxy.test.js', + 'test/proxy/transparent/ProxyAdmin.test.js', + 'test/proxy/transparent/TransparentUpgradeableProxy.test.js', + 'test/proxy/utils/UUPSUpgradeable.test.js', +]); + +export default async (): Promise> => ({ + registerFileForTestRunner: ( + context: HookContext, + filePath: string, + next: (nextContext: HookContext, filePath: string) => Promise, + ): Promise => { + const hasProxies = fs.existsSync(path.join(context.config.paths.root, 'contracts/proxy/Proxy.sol')); + return hasProxies || !ignoredIfProxy.has(filePath) ? next(context, filePath) : Promise.resolve('ignored'); + }, +}); diff --git a/hardhat/hardhat-oz-contracts-helpers/plugin.ts b/hardhat/hardhat-oz-contracts-helpers/plugin.ts new file mode 100644 index 00000000000..62a3a1e9a08 --- /dev/null +++ b/hardhat/hardhat-oz-contracts-helpers/plugin.ts @@ -0,0 +1,15 @@ +import type { HardhatPlugin } from 'hardhat/types/plugins'; + +export type * from './type-extensions.ts'; + +const hardhatOzContractsHelpers: HardhatPlugin = { + id: 'hardhat-oz-contracts-helpers', + hookHandlers: { + hre: () => import('./hook-handlers/hre.ts'), + network: () => import('./hook-handlers/network.ts'), + test: () => import('./hook-handlers/test.ts'), + }, + dependencies: () => [import('@nomicfoundation/hardhat-ethers')], +}; + +export default hardhatOzContractsHelpers; diff --git a/hardhat/hardhat-oz-contracts-helpers/type-extensions.ts b/hardhat/hardhat-oz-contracts-helpers/type-extensions.ts new file mode 100644 index 00000000000..6dddb5e3294 --- /dev/null +++ b/hardhat/hardhat-oz-contracts-helpers/type-extensions.ts @@ -0,0 +1,37 @@ +import 'hardhat/types/network'; + +import type { HardhatEthersSigner } from '@nomicfoundation/hardhat-ethers/types'; +import type { Contract, TransactionReceipt } from 'ethers'; +import type { InteroperableAddress } from 'interoperable-addresses'; + +type AddressLike = HardhatEthersSigner | Contract | string; + +export interface Chain { + namespace: string; + reference: string; + caip2: string; + erc7930: InteroperableAddress; + toCaip10: (other: AddressLike) => string; + toErc7930: (other: AddressLike) => InteroperableAddress; +} + +export type ClockType = Map<'blocknumber' | 'timestamp', T>; + +declare module 'hardhat/types/network' { + interface NetworkConnection< + // eslint-disable-next-line @typescript-eslint/no-unused-vars -- the ChainTypeT must be declared in the interface but in this scenario it's not used + ChainTypeT extends ChainType | string = DefaultChainType, + > { + helpers: { + chain: Chain; + impersonate: (connection: ChainTypeT) => (account: AddressLike, balance?: bigint) => Promise; + time: { + clock: ClockType<() => Promise>; + clockFromReceipt: ClockType<(receipt: TransactionReceipt) => Promise>; + increaseBy: ClockType<(delay: bigint, mine?: boolean) => Promise>; + increaseTo: ClockType<(to: bigint, mine?: boolean) => Promise>; + duration: ClockType bigint>>; + }; + }; + } +} diff --git a/hardhat/hardhat-transpiler/plugin.ts b/hardhat/hardhat-transpiler/plugin.ts new file mode 100644 index 00000000000..7d0106ba375 --- /dev/null +++ b/hardhat/hardhat-transpiler/plugin.ts @@ -0,0 +1,20 @@ +import type { HardhatPlugin } from 'hardhat/types/plugins'; +import { ArgumentType } from 'hardhat/types/arguments'; +import { task } from 'hardhat/config'; + +const hardhatTranspilerPlugin: HardhatPlugin = { + id: 'hardhat-transpiler', + tasks: [ + task('transpile', 'Transpile contracts.') + .addOption({ + name: 'settings', + description: 'Path to the transpiler config file.', + type: ArgumentType.STRING_WITHOUT_DEFAULT, + defaultValue: undefined, + }) + .setAction(() => import('./tasks/transpile.ts')) + .build(), + ], +}; + +export default hardhatTranspilerPlugin; diff --git a/hardhat/hardhat-transpiler/tasks/transpile.ts b/hardhat/hardhat-transpiler/tasks/transpile.ts new file mode 100644 index 00000000000..065c1f0de5c --- /dev/null +++ b/hardhat/hardhat-transpiler/tasks/transpile.ts @@ -0,0 +1,134 @@ +import assert from 'node:assert'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { HardhatRuntimeEnvironment } from 'hardhat/types/hre'; + +import { transpile } from '@openzeppelin/upgrade-safe-transpiler/dist/index.js'; +import { findAlreadyInitializable } from '@openzeppelin/upgrade-safe-transpiler/dist/find-already-initializable.js'; + +interface TranspileOptions { + initializablePath?: string; + deleteOriginals?: boolean; + skipWithInit?: boolean; + exclude?: string[]; + publicInitializers?: string[]; + namespaced?: boolean; + namespaceExclude?: string[]; + peerProject?: string; +} + +// Map function, key the keys intact and transform values +function transformKeys(obj: Record, fn: (key: string) => string): Record { + return Object.fromEntries(Object.entries(obj).map(([k, v]) => [fn(k), v])); +} + +// Filter function, only keep entries where fn returns true +function filterRecord(obj: Record, fn: (key: string, value: U) => boolean): Record { + return Object.fromEntries(Object.entries(obj).filter(([k, v]) => fn(k, v))); +} + +export default async function ({ settings }: { settings?: string }, hre: HardhatRuntimeEnvironment) { + assert(settings, 'Transpile settings file must be provided'); + const options: TranspileOptions = await fs.readFile(settings, 'utf-8').then(JSON.parse); + + const { contractRootPaths } = await hre.tasks.getTask('compile').run({ noTests: true }); + const compilationJobs = await hre.solidity.getCompilationJobs(contractRootPaths); + assert('cacheHits' in compilationJobs, 'Compilation jobs not found'); + + const buildIds: Set = new Set(); + for (const { buildId } of compilationJobs.cacheHits.values()) { + buildIds.add(buildId); + } + + const keep: Set = new Set(); + const seen: Set = new Set(); + + for (const buildId of buildIds) { + // Load build info + const { input, solcVersion } = await hre.artifacts + .getBuildInfoPath(buildId) + .then(file => fs.readFile(file!, 'utf-8')) + .then(JSON.parse); + const { output } = await hre.artifacts + .getBuildInfoOutputPath(buildId) + .then(file => fs.readFile(file!, 'utf-8')) + .then(JSON.parse); + + const mainSources = hre.config.paths.sources.solidity.at(0)!; + const mainSourcesRel = path.relative(hre.config.paths.root, mainSources); + + // Adjust paths to match transpiler expectations + input.sources = filterRecord( + transformKeys(input.sources, k => k.replace(/^project\//, '')), + k => k.startsWith(mainSourcesRel + '/'), + ); + output.sources = filterRecord( + transformKeys(output.sources, k => k.replace(/^project\//, '')), + k => k.startsWith(mainSourcesRel + '/'), + ); + output.contracts = filterRecord( + transformKeys(output.contracts, k => k.replace(/^project\//, '')), + k => k.startsWith(mainSourcesRel + '/'), + ); + Object.values(output.sources).forEach((s: any) => { + s.ast.absolutePath = s.ast.absolutePath.replace(/^project\//, ''); + }); + + // Run transpilation on the first source folder + const transpiled = await transpile( + input, + output, + { root: hre.config.paths.root, sources: mainSources }, + { ...options, solcVersion }, + ); + + // Write transpiled files to disk + await Promise.all( + transpiled.map(async t => { + const outputPath = path.join(hre.config.paths.root, t.path.replace(/^project\//, '')); + await fs.mkdir(path.dirname(outputPath), { recursive: true }); + await fs.writeFile(outputPath, t.source); + }), + ); + + // Delete originals files + if (options.deleteOriginals) { + const alreadyInitializable = findAlreadyInitializable(output, options.initializablePath); + + // keep all newly transpiled files, plus any already-initializable files (even if not transpiled, to avoid deleting them) + ([] as string[]) + .concat( + transpiled.map(t => t.path), + alreadyInitializable, + ) + .map(p => path.join(hre.config.paths.root, p.replace(/^project\//, ''))) + .forEach(p => keep.add(p)); + + // If we have an initializablePath and no peer project, we need to preserve the initializablePath. + if (options.initializablePath && options.peerProject === undefined) { + keep.add(path.join(hre.config.paths.root, options.initializablePath.replace(/^project\//, ''))); + } + + Object.keys(output.sources) + .map(s => path.join(hre.config.paths.root, s.replace(/^project\//, ''))) + .forEach(p => seen.add(p)); + + // If we have a peer project, initializable file present in the main source must be removed from the peer source + // to avoid conflicts. Since we don't know which source location may contain the peer project, we check all the + // solidity source file. Note that if the file does not exist, it will simply be ignored when we try to delete it. + if (options.peerProject) { + alreadyInitializable + .filter(f => f.startsWith(mainSourcesRel + '/')) + .flatMap(f => + hre.config.paths.sources.solidity + .slice(1) + .map(peerSources => path.join(peerSources, path.relative(mainSourcesRel, f))), + ) + .forEach(p => seen.add(p)); + } + } + } + + // Perform delete + await Promise.all([...seen].filter(p => !keep.has(p)).map(p => fs.unlink(p).catch(() => {}))); +} diff --git a/hardhat/ignore-unreachable-warnings.js b/hardhat/ignore-unreachable-warnings.js deleted file mode 100644 index eeacf0a1a5e..00000000000 --- a/hardhat/ignore-unreachable-warnings.js +++ /dev/null @@ -1,45 +0,0 @@ -// Warnings about unreachable code are emitted with a source location that corresponds to the unreachable code. -// We have some testing contracts that purposely cause unreachable code, but said code is in the library contracts, and -// with hardhat-ignore-warnings we are not able to selectively ignore them without potentially ignoring relevant -// warnings that we don't want to miss. -// Thus, we need to handle these warnings separately. We force Hardhat to compile them in a separate compilation job and -// then ignore the warnings about unreachable code coming from that compilation job. - -const { task } = require('hardhat/config'); -const { - TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE, - TASK_COMPILE_SOLIDITY_COMPILE, -} = require('hardhat/builtin-tasks/task-names'); - -const marker = Symbol('unreachable'); -const markedCache = new WeakMap(); - -task(TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE, async (params, _, runSuper) => { - const job = await runSuper(params); - // If the file is in the unreachable directory, we make a copy of the config and mark it, which will cause it to get - // compiled separately (along with the other marked files). - if (params.file.sourceName.startsWith('contracts/mocks/') && /\bunreachable\b/.test(params.file.sourceName)) { - const originalConfig = job.solidityConfig; - let markedConfig = markedCache.get(originalConfig); - if (markedConfig === undefined) { - markedConfig = { ...originalConfig, [marker]: true }; - markedCache.set(originalConfig, markedConfig); - } - job.solidityConfig = markedConfig; - } - return job; -}); - -const W_UNREACHABLE_CODE = '5740'; - -task(TASK_COMPILE_SOLIDITY_COMPILE, async (params, _, runSuper) => { - const marked = params.compilationJob.solidityConfig[marker]; - const result = await runSuper(params); - if (marked) { - result.output = { - ...result.output, - errors: result.output.errors?.filter(e => e.severity !== 'warning' || e.errorCode !== W_UNREACHABLE_CODE), - }; - } - return result; -}); diff --git a/hardhat/remappings.js b/hardhat/remappings.js deleted file mode 100644 index cd9984d440b..00000000000 --- a/hardhat/remappings.js +++ /dev/null @@ -1,18 +0,0 @@ -const fs = require('fs'); -const { task } = require('hardhat/config'); -const { TASK_COMPILE_GET_REMAPPINGS } = require('hardhat/builtin-tasks/task-names'); - -task(TASK_COMPILE_GET_REMAPPINGS).setAction((taskArgs, env, runSuper) => - runSuper().then(remappings => - Object.assign( - remappings, - Object.fromEntries( - fs - .readFileSync('remappings.txt', 'utf-8') - .split('\n') - .filter(Boolean) - .map(line => line.trim().split('=')), - ), - ), - ), -); diff --git a/hardhat/skip-foundry-tests.js b/hardhat/skip-foundry-tests.js deleted file mode 100644 index 965ba37c39e..00000000000 --- a/hardhat/skip-foundry-tests.js +++ /dev/null @@ -1,6 +0,0 @@ -const { subtask } = require('hardhat/config'); -const { TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS } = require('hardhat/builtin-tasks/task-names'); - -subtask(TASK_COMPILE_SOLIDITY_GET_SOURCE_PATHS).setAction(async (_, __, runSuper) => - (await runSuper()).filter(path => !path.endsWith('.t.sol')), -); diff --git a/hardhat/task-test-get-files.js b/hardhat/task-test-get-files.js deleted file mode 100644 index 108f40a42c0..00000000000 --- a/hardhat/task-test-get-files.js +++ /dev/null @@ -1,25 +0,0 @@ -const { internalTask } = require('hardhat/config'); -const { TASK_TEST_GET_TEST_FILES } = require('hardhat/builtin-tasks/task-names'); - -// Modifies `hardhat test` to skip the proxy tests after proxies are removed by the transpiler for upgradeability. - -internalTask(TASK_TEST_GET_TEST_FILES).setAction(async (args, hre, runSuper) => { - const path = require('path'); - const { promises: fs } = require('fs'); - - const hasProxies = await fs - .access(path.join(hre.config.paths.sources, 'proxy/Proxy.sol')) - .then(() => true) - .catch(() => false); - - const ignoredIfProxy = [ - 'proxy/beacon/BeaconProxy.test.js', - 'proxy/beacon/UpgradeableBeacon.test.js', - 'proxy/ERC1967/ERC1967Proxy.test.js', - 'proxy/transparent/ProxyAdmin.test.js', - 'proxy/transparent/TransparentUpgradeableProxy.test.js', - 'proxy/utils/UUPSUpgradeable.test.js', - ].map(p => path.join(hre.config.paths.tests, p)); - - return (await runSuper(args)).filter(file => hasProxies || !ignoredIfProxy.includes(file)); -}); diff --git a/package-lock.json b/package-lock.json index 964ca83a1f4..1e1f130ffc3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,25 +16,26 @@ "@eslint/compat": "^1.2.1", "@ethereumjs/mpt": "^10.1.0", "@noble/curves": "^2.0.1", - "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", - "@nomicfoundation/hardhat-ethers": "^3.0.9", - "@nomicfoundation/hardhat-network-helpers": "^1.0.13", + "@nomicfoundation/hardhat-ethers": "^4.0.7", + "@nomicfoundation/hardhat-ethers-chai-matchers": "^3.0.4", + "@nomicfoundation/hardhat-mocha": "^3.0.15", + "@nomicfoundation/hardhat-network-helpers": "^3.0.4", "@openzeppelin/docs-utils": "^0.1.6", "@openzeppelin/merkle-tree": "^1.0.7", "@openzeppelin/upgrade-safe-transpiler": "^0.4.1", "@openzeppelin/upgrades-core": "^1.20.6", - "chai": "^4.2.0", + "@types/node": "^25.0.9", + "@types/yargs": "^17.0.35", + "chai": "^5.2.2", "eslint": "^9.0.0", "eslint-config-prettier": "^10.0.0", "ethers": "^6.16.0", "glob": "^13.0.0", "globals": "^17.0.0", "graphlib": "^2.1.8", - "hardhat": "^2.28.5", - "hardhat-exposed": "^0.3.15", - "hardhat-gas-reporter": "^2.1.0", - "hardhat-ignore-warnings": "^0.2.11", - "hardhat-predeploy": "^0.4.1", + "hardhat": "^3.5.0", + "hardhat-ignore-warnings": "^0.3.0", + "hardhat-predeploy": "^1.0.1", "husky": "^9.1.7", "interoperable-addresses": "^0.1.3", "lint-staged": "^17.0.0", @@ -45,26 +46,20 @@ "prettier-plugin-solidity": "^2.0.0", "rimraf": "^6.0.0", "semver": "^7.3.5", - "solhint": "^6.0.1", + "solhint": "^6.0.3", "solhint-plugin-openzeppelin": "file:scripts/solhint-custom", - "solidity-ast": "^0.4.50", - "solidity-coverage": "^0.8.14", - "solidity-docgen": "^0.6.0-beta.29", + "solidity-ast": "^0.4.61", "undici": "^8.2.0", "yargs": "^18.0.0" } }, "node_modules/@adraffy/ens-normalize": { "version": "1.10.1", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz", - "integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==", "dev": true, "license": "MIT" }, "node_modules/@babel/code-frame": { "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz", - "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -78,8 +73,6 @@ }, "node_modules/@babel/helper-validator-identifier": { "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -88,8 +81,6 @@ }, "node_modules/@babel/runtime": { "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", - "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", "dev": true, "license": "MIT", "engines": { @@ -98,15 +89,11 @@ }, "node_modules/@bytecodealliance/preview2-shim": { "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.0.tgz", - "integrity": "sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ==", "dev": true, "license": "(Apache-2.0 WITH LLVM-exception)" }, "node_modules/@changesets/apply-release-plan": { "version": "7.0.14", - "resolved": "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-7.0.14.tgz", - "integrity": "sha512-ddBvf9PHdy2YY0OUiEl3TV78mH9sckndJR14QAt87KLEbIov81XO0q0QAmvooBxXlqRRP8I9B7XOzZwQG7JkWA==", "dev": true, "license": "MIT", "dependencies": { @@ -127,8 +114,6 @@ }, "node_modules/@changesets/apply-release-plan/node_modules/prettier": { "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "license": "MIT", "bin": { @@ -143,8 +128,6 @@ }, "node_modules/@changesets/assemble-release-plan": { "version": "6.0.9", - "resolved": "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-6.0.9.tgz", - "integrity": "sha512-tPgeeqCHIwNo8sypKlS3gOPmsS3wP0zHt67JDuL20P4QcXiw/O4Hl7oXiuLnP9yg+rXLQ2sScdV1Kkzde61iSQ==", "dev": true, "license": "MIT", "dependencies": { @@ -158,8 +141,6 @@ }, "node_modules/@changesets/changelog-git": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.2.1.tgz", - "integrity": "sha512-x/xEleCFLH28c3bQeQIyeZf8lFXyDFVn1SgcBiR2Tw/r4IAWlk1fzxCEZ6NxQAjF2Nwtczoen3OA2qR+UawQ8Q==", "dev": true, "license": "MIT", "dependencies": { @@ -180,8 +161,6 @@ }, "node_modules/@changesets/cli": { "version": "2.29.8", - "resolved": "https://registry.npmjs.org/@changesets/cli/-/cli-2.29.8.tgz", - "integrity": "sha512-1weuGZpP63YWUYjay/E84qqwcnt5yJMM0tep10Up7Q5cS/DGe2IZ0Uj3HNMxGhCINZuR7aO9WBMdKnPit5ZDPA==", "dev": true, "license": "MIT", "dependencies": { @@ -220,8 +199,6 @@ }, "node_modules/@changesets/cli/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { @@ -236,8 +213,6 @@ }, "node_modules/@changesets/config": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@changesets/config/-/config-3.1.2.tgz", - "integrity": "sha512-CYiRhA4bWKemdYi/uwImjPxqWNpqGPNbEBdX1BdONALFIDK7MCUj6FPkzD+z9gJcvDFUQJn9aDVf4UG7OT6Kog==", "dev": true, "license": "MIT", "dependencies": { @@ -252,8 +227,6 @@ }, "node_modules/@changesets/errors": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@changesets/errors/-/errors-0.2.0.tgz", - "integrity": "sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==", "dev": true, "license": "MIT", "dependencies": { @@ -262,8 +235,6 @@ }, "node_modules/@changesets/get-dependents-graph": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-2.1.3.tgz", - "integrity": "sha512-gphr+v0mv2I3Oxt19VdWRRUxq3sseyUpX9DaHpTUmLj92Y10AGy+XOtV+kbM6L/fDcpx7/ISDFK6T8A/P3lOdQ==", "dev": true, "license": "MIT", "dependencies": { @@ -286,8 +257,6 @@ }, "node_modules/@changesets/get-release-plan": { "version": "4.0.14", - "resolved": "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-4.0.14.tgz", - "integrity": "sha512-yjZMHpUHgl4Xl5gRlolVuxDkm4HgSJqT93Ri1Uz8kGrQb+5iJ8dkXJ20M2j/Y4iV5QzS2c5SeTxVSKX+2eMI0g==", "dev": true, "license": "MIT", "dependencies": { @@ -301,15 +270,11 @@ }, "node_modules/@changesets/get-version-range-type": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.4.0.tgz", - "integrity": "sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==", "dev": true, "license": "MIT" }, "node_modules/@changesets/git": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@changesets/git/-/git-3.0.4.tgz", - "integrity": "sha512-BXANzRFkX+XcC1q/d27NKvlJ1yf7PSAgi8JG6dt8EfbHFHi4neau7mufcSca5zRhwOL8j9s6EqsxmT+s+/E6Sw==", "dev": true, "license": "MIT", "dependencies": { @@ -322,8 +287,6 @@ }, "node_modules/@changesets/logger": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@changesets/logger/-/logger-0.1.1.tgz", - "integrity": "sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==", "dev": true, "license": "MIT", "dependencies": { @@ -332,8 +295,6 @@ }, "node_modules/@changesets/parse": { "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@changesets/parse/-/parse-0.4.2.tgz", - "integrity": "sha512-Uo5MC5mfg4OM0jU3up66fmSn6/NE9INK+8/Vn/7sMVcdWg46zfbvvUSjD9EMonVqPi9fbrJH9SXHn48Tr1f2yA==", "dev": true, "license": "MIT", "dependencies": { @@ -343,8 +304,6 @@ }, "node_modules/@changesets/pre": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@changesets/pre/-/pre-2.0.2.tgz", - "integrity": "sha512-HaL/gEyFVvkf9KFg6484wR9s0qjAXlZ8qWPDkTyKF6+zqjBe/I2mygg3MbpZ++hdi0ToqNUF8cjj7fBy0dg8Ug==", "dev": true, "license": "MIT", "dependencies": { @@ -356,8 +315,6 @@ }, "node_modules/@changesets/read": { "version": "0.6.6", - "resolved": "https://registry.npmjs.org/@changesets/read/-/read-0.6.6.tgz", - "integrity": "sha512-P5QaN9hJSQQKJShzzpBT13FzOSPyHbqdoIBUd2DJdgvnECCyO6LmAOWSV+O8se2TaZJVwSXjL+v9yhb+a9JeJg==", "dev": true, "license": "MIT", "dependencies": { @@ -372,8 +329,6 @@ }, "node_modules/@changesets/should-skip-package": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@changesets/should-skip-package/-/should-skip-package-0.1.2.tgz", - "integrity": "sha512-qAK/WrqWLNCP22UDdBTMPH5f41elVDlsNyat180A33dWxuUDyNpg6fPi/FyTZwRriVjg0L8gnjJn2F9XAoF0qw==", "dev": true, "license": "MIT", "dependencies": { @@ -383,15 +338,11 @@ }, "node_modules/@changesets/types": { "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-6.1.0.tgz", - "integrity": "sha512-rKQcJ+o1nKNgeoYRHKOS07tAMNd3YSN0uHaJOZYjBAgxfV7TUE7JE+z4BzZdQwb5hKaYbayKN5KrYV7ODb2rAA==", "dev": true, "license": "MIT" }, "node_modules/@changesets/write": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@changesets/write/-/write-0.4.0.tgz", - "integrity": "sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q==", "dev": true, "license": "MIT", "dependencies": { @@ -403,8 +354,6 @@ }, "node_modules/@changesets/write/node_modules/prettier": { "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "license": "MIT", "bin": { @@ -417,3604 +366,2311 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/@colors/colors": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", - "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", - "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", - "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/compat": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@eslint/compat/-/compat-1.4.1.tgz", - "integrity": "sha512-cfO82V9zxxGBxcQDr1lfaYB7wykTa0b00mGa36FrJl7iTFd0Z2cHfEYuxcBRP/iNijCsWsEkA+jzT8hGYmv33w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "peerDependencies": { - "eslint": "^8.40 || 9" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.2.tgz", - "integrity": "sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@ethereumjs/common": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/common/-/common-3.2.0.tgz", - "integrity": "sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ethereumjs/util": "^8.1.0", - "crc-32": "^1.2.0" - } - }, - "node_modules/@ethereumjs/common/node_modules/@ethereumjs/rlp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", - "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", - "dev": true, - "license": "MPL-2.0", - "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/common/node_modules/@ethereumjs/util": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", - "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@ethereumjs/rlp": "^4.0.1", - "ethereum-cryptography": "^2.0.0", - "micro-ftch": "^0.3.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/common/node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/common/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/common/node_modules/@scure/base": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", - "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/common/node_modules/@scure/bip32": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", - "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.4.0", - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/common/node_modules/@scure/bip39": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", - "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/common/node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" - } - }, - "node_modules/@ethereumjs/mpt": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/mpt/-/mpt-10.1.1.tgz", - "integrity": "sha512-Kh1vNhUwSIyuehOJk9Hqxzgu8D5B2L3jidKVaH4VB/dSo/6mVA0IKQ312c0ophXY8uU4f8NOTW602FJe6Ezaag==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@ethereumjs/rlp": "^10.1.1", - "@ethereumjs/util": "^10.1.1", - "@noble/hashes": "^2.0.1", - "debug": "^4.4.0", - "lru-cache": "11.0.2" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@ethereumjs/rlp": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-10.1.1.tgz", - "integrity": "sha512-jbnWTEwcpoY+gE0r+wxfDG9zgiu54DcTcwnc9sX3DsqKR4l5K7x2V8mQL3Et6hURa4DuT9g7z6ukwpBLFchszg==", - "dev": true, - "license": "MPL-2.0", - "bin": { - "rlp": "bin/rlp.cjs" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@ethereumjs/tx": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/tx/-/tx-4.2.0.tgz", - "integrity": "sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@ethereumjs/common": "^3.2.0", - "@ethereumjs/rlp": "^4.0.1", - "@ethereumjs/util": "^8.1.0", - "ethereum-cryptography": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/tx/node_modules/@ethereumjs/rlp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", - "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", - "dev": true, - "license": "MPL-2.0", - "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/tx/node_modules/@ethereumjs/util": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", - "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@ethereumjs/rlp": "^4.0.1", - "ethereum-cryptography": "^2.0.0", - "micro-ftch": "^0.3.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/@ethereumjs/tx/node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/tx/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/tx/node_modules/@scure/base": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", - "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/tx/node_modules/@scure/bip32": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", - "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.4.0", - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/tx/node_modules/@scure/bip39": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", - "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@ethereumjs/tx/node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" - } - }, - "node_modules/@ethereumjs/util": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-10.1.1.tgz", - "integrity": "sha512-r2EhaeEmLZXVs1dT2HJFQysAkr63ZWATu/9tgYSp1IlvjvwyC++DLg5kCDwMM49HBq3sOAhrPnXkoqf9DV2gbw==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@ethereumjs/rlp": "^10.1.1", - "@noble/curves": "^2.0.1", - "@noble/hashes": "^2.0.1" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/@ethersproject/abi": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.8.0.tgz", - "integrity": "sha512-b9YS/43ObplgyV6SlyQsG53/vkSal0MNA1fskSC4mbnCMi8R+NkcH8K9FPYNESf6jUefBUniE4SOKms0E/KK1Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/hash": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/abstract-provider": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-provider/-/abstract-provider-5.8.0.tgz", - "integrity": "sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/networks": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/transactions": "^5.8.0", - "@ethersproject/web": "^5.8.0" - } - }, - "node_modules/@ethersproject/abstract-signer": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/abstract-signer/-/abstract-signer-5.8.0.tgz", - "integrity": "sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-provider": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0" - } - }, - "node_modules/@ethersproject/address": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/address/-/address-5.8.0.tgz", - "integrity": "sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/rlp": "^5.8.0" - } - }, - "node_modules/@ethersproject/base64": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/base64/-/base64-5.8.0.tgz", - "integrity": "sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0" - } - }, - "node_modules/@ethersproject/bignumber": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bignumber/-/bignumber-5.8.0.tgz", - "integrity": "sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "bn.js": "^5.2.1" - } - }, - "node_modules/@ethersproject/bytes": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/bytes/-/bytes-5.8.0.tgz", - "integrity": "sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/constants": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/constants/-/constants-5.8.0.tgz", - "integrity": "sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0" - } - }, - "node_modules/@ethersproject/hash": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/hash/-/hash-5.8.0.tgz", - "integrity": "sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/abstract-signer": "^5.8.0", - "@ethersproject/address": "^5.8.0", - "@ethersproject/base64": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@ethersproject/keccak256": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/keccak256/-/keccak256-5.8.0.tgz", - "integrity": "sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "js-sha3": "0.8.0" - } - }, - "node_modules/@ethersproject/logger": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/logger/-/logger-5.8.0.tgz", - "integrity": "sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT" - }, - "node_modules/@ethersproject/networks": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/networks/-/networks-5.8.0.tgz", - "integrity": "sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/properties": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/properties/-/properties-5.8.0.tgz", - "integrity": "sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], - "license": "MIT", - "dependencies": { - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/rlp": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/rlp/-/rlp-5.8.0.tgz", - "integrity": "sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/signing-key": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/signing-key/-/signing-key-5.8.0.tgz", - "integrity": "sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "bn.js": "^5.2.1", - "elliptic": "6.6.1", - "hash.js": "1.1.7" - } - }, - "node_modules/@ethersproject/strings": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/strings/-/strings-5.8.0.tgz", - "integrity": "sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } + "optional": true, + "os": [ + "aix" ], - "license": "MIT", - "dependencies": { - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0" + "engines": { + "node": ">=18" } }, - "node_modules/@ethersproject/transactions": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/transactions/-/transactions-5.8.0.tgz", - "integrity": "sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" ], - "license": "MIT", - "dependencies": { - "@ethersproject/address": "^5.8.0", - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/keccak256": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/rlp": "^5.8.0", - "@ethersproject/signing-key": "^5.8.0" - } - }, - "node_modules/@ethersproject/units": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/units/-/units-5.8.0.tgz", - "integrity": "sha512-lxq0CAnc5kMGIiWW4Mr041VT8IhNM+Pn5T3haO74XZWFulk7wH1Gv64HqE96hT4a7iiNMdOCFEBgaxWuk8ETKQ==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "dependencies": { - "@ethersproject/bignumber": "^5.8.0", - "@ethersproject/constants": "^5.8.0", - "@ethersproject/logger": "^5.8.0" - } - }, - "node_modules/@ethersproject/web": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/@ethersproject/web/-/web-5.8.0.tgz", - "integrity": "sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://gitcoin.co/grants/13/ethersjs-complete-simple-and-tiny-2" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } + "optional": true, + "os": [ + "android" ], - "license": "MIT", - "dependencies": { - "@ethersproject/base64": "^5.8.0", - "@ethersproject/bytes": "^5.8.0", - "@ethersproject/logger": "^5.8.0", - "@ethersproject/properties": "^5.8.0", - "@ethersproject/strings": "^5.8.0" - } - }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/@frangio/servbot": { - "version": "0.3.0-1", - "resolved": "https://registry.npmjs.org/@frangio/servbot/-/servbot-0.3.0-1.tgz", - "integrity": "sha512-eKXRqt8Zh3aqtVYoyayuLiktcW6vnYCuwlcqg91cv3HSdM5foTmIECJEJiwI+GBmSLY37mzczpt/ZfvYqzrQWQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.x", - "pnpm": "10.x" - } - }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" - }, - "engines": { - "node": ">=18.18.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/momoa": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@humanwhocodes/momoa/-/momoa-2.0.4.tgz", - "integrity": "sha512-RE815I4arJFtt+FVeU1Tgp9/Xvecacji8w/V6XtXsWWH/wz/eNkNbhb+ny/+PlVZjV0rxQpRSQKNKE3lcktHEA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@inquirer/external-editor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", - "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", - "dev": true, - "license": "MIT", - "dependencies": { - "chardet": "^2.1.1", - "iconv-lite": "^0.7.0" - }, "engines": { "node": ">=18" - }, - "peerDependencies": { - "@types/node": ">=18" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=18" } }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=18" } }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=18" } }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=18" } }, - "node_modules/@manypkg/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.5.5", - "@types/node": "^12.7.1", - "find-up": "^4.1.0", - "fs-extra": "^8.1.0" + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@manypkg/find-root/node_modules/@types/node": { - "version": "12.20.55", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz", - "integrity": "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@manypkg/find-root/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=6 <7 || >=8" + "node": ">=18" } }, - "node_modules/@manypkg/get-packages": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-1.1.3.tgz", - "integrity": "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==", + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.5.5", - "@changesets/types": "^4.0.1", - "@manypkg/find-root": "^1.1.0", - "fs-extra": "^8.1.0", - "globby": "^11.0.0", - "read-yaml-file": "^1.1.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz", - "integrity": "sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@manypkg/get-packages/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6 <7 || >=8" + "node": ">=18" } }, - "node_modules/@metamask/abi-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@metamask/abi-utils/-/abi-utils-2.0.4.tgz", - "integrity": "sha512-StnIgUB75x7a7AgUhiaUZDpCsqGp7VkNnZh2XivXkJ6mPkE83U8ARGQj5MbRis7VJY8BC5V1AbB1fjdh0hupPQ==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "(Apache-2.0 AND MIT)", - "dependencies": { - "@metamask/superstruct": "^3.1.0", - "@metamask/utils": "^9.0.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=16.0.0" + "node": ">=18" } }, - "node_modules/@metamask/superstruct": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@metamask/superstruct/-/superstruct-3.2.1.tgz", - "integrity": "sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=16.0.0" + "node": ">=18" } }, - "node_modules/@metamask/utils": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@metamask/utils/-/utils-9.3.0.tgz", - "integrity": "sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "ISC", - "dependencies": { - "@ethereumjs/tx": "^4.2.0", - "@metamask/superstruct": "^3.1.0", - "@noble/hashes": "^1.3.1", - "@scure/base": "^1.1.3", - "@types/debug": "^4.1.7", - "debug": "^4.3.4", - "pony-cause": "^2.1.10", - "semver": "^7.5.4", - "uuid": "^9.0.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=16.0.0" + "node": ">=18" } }, - "node_modules/@metamask/utils/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=18" } }, - "node_modules/@noble/ciphers": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@noble/ciphers/-/ciphers-1.3.0.tgz", - "integrity": "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=18" } }, - "node_modules/@noble/curves": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-2.0.1.tgz", - "integrity": "sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==", + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], "dev": true, "license": "MIT", - "dependencies": { - "@noble/hashes": "2.0.1" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=18" } }, - "node_modules/@noble/hashes": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-2.0.1.tgz", - "integrity": "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==", + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=18" } }, - "node_modules/@noble/secp256k1": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@noble/secp256k1/-/secp256k1-1.7.1.tgz", - "integrity": "sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } + "license": "MIT", + "optional": true, + "os": [ + "netbsd" ], - "license": "MIT" + "engines": { + "node": ">=18" + } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 8" + "node": ">=18" } }, - "node_modules/@nomicfoundation/edr": { - "version": "0.12.0-next.23", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.12.0-next.23.tgz", - "integrity": "sha512-F2/6HZh8Q9RsgkOIkRrckldbhPjIZY7d4mT9LYuW68miwGQ5l7CkAgcz9fRRiurA0+YJhtsbx/EyrD9DmX9BOw==", + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", - "dependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.23", - "@nomicfoundation/edr-darwin-x64": "0.12.0-next.23", - "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.23", - "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.23", - "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.23", - "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.23", - "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.23" - }, + "optional": true, + "os": [ + "openharmony" + ], "engines": { - "node": ">= 20" + "node": ">=18" } }, - "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.12.0-next.23", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.12.0-next.23.tgz", - "integrity": "sha512-Amh7mRoDzZyJJ4efqoePqdoZOzharmSOttZuJDlVE5yy07BoE8hL6ZRpa5fNYn0LCqn/KoWs8OHANWxhKDGhvQ==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">= 20" + "node": ">=18" } }, - "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.12.0-next.23", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.12.0-next.23.tgz", - "integrity": "sha512-9wn489FIQm7m0UCD+HhktjWx6vskZzeZD9oDc2k9ZvbBzdXwPp5tiDqUBJ+eQpByAzCDfteAJwRn2lQCE0U+Iw==", + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 20" + "node": ">=18" } }, - "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.12.0-next.23", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.12.0-next.23.tgz", - "integrity": "sha512-nlk5EejSzEUfEngv0Jkhqq3/wINIfF2ED9wAofc22w/V1DV99ASh9l3/e/MIHOQFecIZ9MDqt0Em9/oDyB1Uew==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 20" + "node": ">=18" } }, - "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.12.0-next.23", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.12.0-next.23.tgz", - "integrity": "sha512-SJuPBp3Rc6vM92UtVTUxZQ/QlLhLfwTftt2XUiYohmGKB3RjGzpgduEFMCA0LEnucUckU6UHrJNFHiDm77C4PQ==", + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 20" + "node": ">=18" } }, - "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.12.0-next.23", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.12.0-next.23.tgz", - "integrity": "sha512-NU+Qs3u7Qt6t3bJFdmmjd5CsvgI2bPPzO31KifM2Ez96/jsXYho5debtTQnimlb5NAqiHTSlxjh/F8ROcptmeQ==", + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.1", "dev": true, "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, "engines": { - "node": ">= 20" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, - "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.12.0-next.23", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.12.0-next.23.tgz", - "integrity": "sha512-F78fZA2h6/ssiCSZOovlgIu0dUeI7ItKPsDDF3UUlIibef052GCXmliMinC90jVPbrjUADMd1BUwjfI0Z8OllQ==", + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">= 20" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.12.0-next.23", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.12.0-next.23.tgz", - "integrity": "sha512-IfJZQJn7d/YyqhmguBIGoCKjE9dKjbu6V6iNEPApfwf5JyyjHYyyfkLU4rf7hygj57bfH4sl1jtQ6r8HnT62lw==", + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", "dev": true, "license": "MIT", "engines": { - "node": ">= 20" + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, - "node_modules/@nomicfoundation/hardhat-chai-matchers": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-2.1.0.tgz", - "integrity": "sha512-GPhBNafh1fCnVD9Y7BYvoLnblnvfcq3j8YDbO1gGe/1nOFWzGmV7gFu5DkwFXF+IpYsS+t96o9qc/mPu3V3Vfw==", + "node_modules/@eslint/compat": { + "version": "1.4.1", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@types/chai-as-promised": "^7.1.3", - "chai-as-promised": "^7.1.1", - "deep-eql": "^4.0.1", - "ordinal": "^1.0.3" + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "@nomicfoundation/hardhat-ethers": "^3.1.0", - "chai": "^4.2.0", - "ethers": "^6.14.0", - "hardhat": "^2.26.0" + "eslint": "^8.40 || 9" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/@nomicfoundation/hardhat-ethers": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-3.1.3.tgz", - "integrity": "sha512-208JcDeVIl+7Wu3MhFUUtiA8TJ7r2Rn3Wr+lSx9PfsDTKkbsAsWPY6N6wQ4mtzDv0/pB9nIbJhkjoHe1EsgNsA==", + "node_modules/@eslint/config-array": { + "version": "0.21.1", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "debug": "^4.1.1", - "lodash.isequal": "^4.5.0" + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" }, - "peerDependencies": { - "ethers": "^6.14.0", - "hardhat": "^2.28.0" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@nomicfoundation/hardhat-network-helpers": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.1.2.tgz", - "integrity": "sha512-p7HaUVDbLj7ikFivQVNhnfMHUBgiHYMwQWvGn9AriieuopGOELIrwj2KjyM2a6z70zai5YKO264Vwz+3UFJZPQ==", + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "ethereumjs-util": "^7.1.4" + "brace-expansion": "^1.1.7" }, - "peerDependencies": { - "hardhat": "^2.26.0" + "engines": { + "node": "*" } }, - "node_modules/@nomicfoundation/slang": { - "version": "0.18.3", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-0.18.3.tgz", - "integrity": "sha512-YqAWgckqbHM0/CZxi9Nlf4hjk9wUNLC9ngWCWBiqMxPIZmzsVKYuChdlrfeBPQyvQQBoOhbx+7C1005kLVQDZQ==", + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@bytecodealliance/preview2-shim": "0.17.0" + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@nomicfoundation/solidity-analyzer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.2.tgz", - "integrity": "sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==", + "node_modules/@eslint/core": { + "version": "0.17.0", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" }, - "optionalDependencies": { - "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", - "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", - "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", - "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.2.tgz", - "integrity": "sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==", + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", "dev": true, "license": "MIT", - "optional": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">= 12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.2.tgz", - "integrity": "sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==", + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", "dev": true, "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.2.tgz", - "integrity": "sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==", + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", "dev": true, "license": "MIT", - "optional": true, "engines": { - "node": ">= 12" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.2.tgz", - "integrity": "sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==", + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", "dev": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 12" - } + "license": "MIT" }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.2.tgz", - "integrity": "sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==", + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", "dev": true, - "license": "MIT", - "optional": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">= 12" + "node": "*" } }, - "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.2.tgz", - "integrity": "sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==", + "node_modules/@eslint/js": { + "version": "9.39.2", "dev": true, "license": "MIT", - "optional": true, "engines": { - "node": ">= 12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, - "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.2.tgz", - "integrity": "sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==", + "node_modules/@eslint/object-schema": { + "version": "2.1.7", "dev": true, - "license": "MIT", - "optional": true, + "license": "Apache-2.0", "engines": { - "node": ">= 12" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@openzeppelin/docs-utils": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@openzeppelin/docs-utils/-/docs-utils-0.1.6.tgz", - "integrity": "sha512-cVLtDPrCdVgnLV9QRK9D1jrTB8ezQ8tCLTM4g6PHe9TIK3DbO6lSizLF98DhncK2bk6uodOLRT3LO1WtNzei1Q==", + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@frangio/servbot": "^0.3.0-1", - "chalk": "^3.0.0", - "chokidar": "^3.5.3", - "env-paths": "^2.2.0", - "find-up": "^4.1.0", - "is-port-reachable": "^3.0.0", - "js-yaml": "^3.13.1", - "lodash.startcase": "^4.4.0", - "minimist": "^1.2.0" + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" }, - "bin": { - "oz-docs": "oz-docs.js" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@openzeppelin/docs-utils/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@ethereumjs/common": { + "version": "3.2.0", "dev": true, "license": "MIT", "dependencies": { - "sprintf-js": "~1.0.2" + "@ethereumjs/util": "^8.1.0", + "crc-32": "^1.2.0" } }, - "node_modules/@openzeppelin/docs-utils/node_modules/esprima": { + "node_modules/@ethereumjs/common/node_modules/@ethereumjs/rlp": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, - "license": "BSD-2-Clause", + "license": "MPL-2.0", "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" + "rlp": "bin/rlp" }, "engines": { - "node": ">=4" + "node": ">=14" } }, - "node_modules/@openzeppelin/docs-utils/node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "node_modules/@ethereumjs/common/node_modules/@ethereumjs/util": { + "version": "8.1.0", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=14" } }, - "node_modules/@openzeppelin/merkle-tree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@openzeppelin/merkle-tree/-/merkle-tree-1.0.8.tgz", - "integrity": "sha512-E2c9/Y3vjZXwVvPZKqCKUn7upnvam1P1ZhowJyZVQSkzZm5WhumtaRr+wkUXrZVfkIc7Gfrl7xzabElqDL09ow==", + "node_modules/@ethereumjs/common/node_modules/@noble/curves": { + "version": "1.4.2", "dev": true, "license": "MIT", "dependencies": { - "@metamask/abi-utils": "^2.0.4", - "ethereum-cryptography": "^3.0.0" + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@openzeppelin/upgrade-safe-transpiler": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrade-safe-transpiler/-/upgrade-safe-transpiler-0.4.1.tgz", - "integrity": "sha512-IxNqDuHLBUp7WcTtrfNrl7ccHzaKLB0Pn9YLE6HyMdzppbBiKls47cHFIC/uLI91cvZP0cheIyvtA3g/3FEdOA==", + "node_modules/@ethereumjs/common/node_modules/@noble/hashes": { + "version": "1.4.0", "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^8.0.0", - "compare-versions": "^6.0.0", - "ethereum-cryptography": "^3.0.0", - "lodash": "^4.17.20", - "minimatch": "^10.0.3", - "minimist": "^1.2.5", - "solidity-ast": "^0.4.51" + "engines": { + "node": ">= 16" }, - "bin": { - "upgrade-safe-transpiler": "dist/cli.js" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@openzeppelin/upgrades-core": { - "version": "1.44.2", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.44.2.tgz", - "integrity": "sha512-m6iorjyhPK9ow5/trNs7qsBC/SOzJCO51pvvAF2W9nOiZ1t0RtCd+rlRmRmlWTv4M33V0wzIUeamJ2BPbzgUXA==", + "node_modules/@ethereumjs/common/node_modules/@scure/base": { + "version": "1.1.9", "dev": true, "license": "MIT", - "dependencies": { - "@nomicfoundation/slang": "^0.18.3", - "bignumber.js": "^9.1.2", - "cbor": "^10.0.0", - "chalk": "^4.1.0", - "compare-versions": "^6.0.0", - "debug": "^4.1.1", - "ethereumjs-util": "^7.0.3", - "minimatch": "^9.0.5", - "minimist": "^1.2.7", - "proper-lockfile": "^4.1.1", - "solidity-ast": "^0.4.60" - }, - "bin": { - "openzeppelin-upgrades-core": "dist/cli/cli.js" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@openzeppelin/upgrades-core/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "node_modules/@ethereumjs/common/node_modules/@scure/bip32": { + "version": "1.4.0", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@openzeppelin/upgrades-core/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@ethereumjs/common/node_modules/@scure/bip39": { + "version": "1.3.0", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/@openzeppelin/upgrades-core/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/@ethereumjs/common/node_modules/ethereum-cryptography": { + "version": "2.2.1", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "node_modules/@ethereumjs/mpt": { + "version": "10.1.1", "dev": true, - "license": "MIT", - "optional": true, + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^10.1.1", + "@ethereumjs/util": "^10.1.1", + "@noble/hashes": "^2.0.1", + "debug": "^4.4.0", + "lru-cache": "11.0.2" + }, "engines": { - "node": ">=14" + "node": ">=20" } }, - "node_modules/@pnpm/config.env-replace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz", - "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==", + "node_modules/@ethereumjs/rlp": { + "version": "10.1.1", "dev": true, - "license": "MIT", + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp.cjs" + }, "engines": { - "node": ">=12.22.0" + "node": ">=20" } }, - "node_modules/@pnpm/network.ca-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", - "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==", + "node_modules/@ethereumjs/tx": { + "version": "4.2.0", "dev": true, - "license": "MIT", + "license": "MPL-2.0", "dependencies": { - "graceful-fs": "4.2.10" + "@ethereumjs/common": "^3.2.0", + "@ethereumjs/rlp": "^4.0.1", + "@ethereumjs/util": "^8.1.0", + "ethereum-cryptography": "^2.0.0" }, "engines": { - "node": ">=12.22.0" + "node": ">=14" } }, - "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "dev": true, - "license": "ISC" - }, - "node_modules/@pnpm/npm-conf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-3.0.2.tgz", - "integrity": "sha512-h104Kh26rR8tm+a3Qkc5S4VLYint3FE48as7+/5oCEcKR2idC/pF1G6AhIXKI+eHPJa/3J9i5z0Al47IeGHPkA==", + "node_modules/@ethereumjs/tx/node_modules/@ethereumjs/rlp": { + "version": "4.0.1", "dev": true, - "license": "MIT", - "dependencies": { - "@pnpm/config.env-replace": "^1.1.0", - "@pnpm/network.ca-file": "^1.0.1", - "config-chain": "^1.1.11" + "license": "MPL-2.0", + "bin": { + "rlp": "bin/rlp" }, "engines": { - "node": ">=12" + "node": ">=14" } }, - "node_modules/@scure/base": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.2.6.tgz", - "integrity": "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==", + "node_modules/@ethereumjs/tx/node_modules/@ethereumjs/util": { + "version": "8.1.0", "dev": true, - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" + "license": "MPL-2.0", + "dependencies": { + "@ethereumjs/rlp": "^4.0.1", + "ethereum-cryptography": "^2.0.0", + "micro-ftch": "^0.3.1" + }, + "engines": { + "node": ">=14" } }, - "node_modules/@scure/bip32": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.7.0.tgz", - "integrity": "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==", + "node_modules/@ethereumjs/tx/node_modules/@noble/curves": { + "version": "1.4.2", "dev": true, "license": "MIT", "dependencies": { - "@noble/curves": "~1.9.0", - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" + "@noble/hashes": "1.4.0" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip32/node_modules/@noble/curves": { - "version": "1.9.7", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.7.tgz", - "integrity": "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==", + "node_modules/@ethereumjs/tx/node_modules/@noble/hashes": { + "version": "1.4.0", "dev": true, "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">= 16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip32/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/@ethereumjs/tx/node_modules/@scure/base": { + "version": "1.1.9", "dev": true, "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip39": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.6.0.tgz", - "integrity": "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==", + "node_modules/@ethereumjs/tx/node_modules/@scure/bip32": { + "version": "1.4.0", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "~1.8.0", - "@scure/base": "~1.2.5" + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@scure/bip39/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/@ethereumjs/tx/node_modules/@scure/bip39": { + "version": "1.3.0", "dev": true, "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" + "dependencies": { + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/@sentry/core": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.30.0.tgz", - "integrity": "sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==", + "node_modules/@ethereumjs/tx/node_modules/ethereum-cryptography": { + "version": "2.2.1", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" - }, - "engines": { - "node": ">=6" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, - "node_modules/@sentry/core/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@sentry/hub": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.30.0.tgz", - "integrity": "sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==", + "node_modules/@ethereumjs/util": { + "version": "10.1.1", "dev": true, - "license": "BSD-3-Clause", + "license": "MPL-2.0", "dependencies": { - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" + "@ethereumjs/rlp": "^10.1.1", + "@noble/curves": "^2.0.1", + "@noble/hashes": "^2.0.1" }, "engines": { - "node": ">=6" + "node": ">=20" } }, - "node_modules/@sentry/hub/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@sentry/minimal": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.30.0.tgz", - "integrity": "sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==", + "node_modules/@frangio/servbot": { + "version": "0.3.0-1", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=12.x", + "pnpm": "10.x" } }, - "node_modules/@sentry/minimal/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@sentry/node": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-5.30.0.tgz", - "integrity": "sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==", + "node_modules/@humanfs/core": { + "version": "0.19.1", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sentry/core": "5.30.0", - "@sentry/hub": "5.30.0", - "@sentry/tracing": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6" + "node": ">=18.18.0" } }, - "node_modules/@sentry/node/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@sentry/tracing": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-5.30.0.tgz", - "integrity": "sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==", + "node_modules/@humanfs/node": { + "version": "0.16.7", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "dependencies": { - "@sentry/hub": "5.30.0", - "@sentry/minimal": "5.30.0", - "@sentry/types": "5.30.0", - "@sentry/utils": "5.30.0", - "tslib": "^1.9.3" + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" }, "engines": { - "node": ">=6" + "node": ">=18.18.0" } }, - "node_modules/@sentry/tracing/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@sentry/types": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.30.0.tgz", - "integrity": "sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==", + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", "dev": true, - "license": "BSD-3-Clause", + "license": "Apache-2.0", "engines": { - "node": ">=6" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@sentry/utils": { - "version": "5.30.0", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.30.0.tgz", - "integrity": "sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==", + "node_modules/@humanwhocodes/momoa": { + "version": "2.0.4", "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sentry/types": "5.30.0", - "tslib": "^1.9.3" - }, + "license": "Apache-2.0", "engines": { - "node": ">=6" + "node": ">=10.10.0" } }, - "node_modules/@sentry/utils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true, - "license": "0BSD" - }, - "node_modules/@sindresorhus/is": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz", - "integrity": "sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==", + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">=14.16" + "node": ">=18.18" }, "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@solidity-parser/parser": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.20.2.tgz", - "integrity": "sha512-rbu0bzwNvMcwAjH86hiEAcOeRI2EeK8zCkHDrFykh/Al8mvJeFmjy3UrE7GYQjNwOgbGUUtCn5/k8CB8zIu7QA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@szmarczak/http-timer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", - "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", "dev": true, "license": "MIT", "dependencies": { - "defer-to-connect": "^2.0.1" + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" }, "engines": { - "node": ">=14.16" - } - }, - "node_modules/@types/bn.js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-5.2.0.tgz", - "integrity": "sha512-DLbJ1BPqxvQhIGbeu8VbUC1DiAiahHtAYvA0ZEAa4P31F7IaArc8z3C3BRQdWX4mtLQuABG4yzp76ZrS02Ui1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@types/chai": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", - "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "node_modules/@isaacs/cliui": { + "version": "8.0.2", "dev": true, - "license": "MIT", + "license": "ISC", + "peer": true, "dependencies": { - "@types/deep-eql": "*", - "assertion-error": "^2.0.1" + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" } }, - "node_modules/@types/chai-as-promised": { - "version": "7.1.8", - "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz", - "integrity": "sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==", + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", "dev": true, "license": "MIT", - "dependencies": { - "@types/chai": "*" + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/@types/debug": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", - "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", "dev": true, "license": "MIT", - "dependencies": { - "@types/ms": "*" + "peer": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@types/deep-eql": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", - "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", "dev": true, "license": "MIT", - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } + "peer": true }, - "node_modules/@types/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimatch": { + "node_modules/@isaacs/cliui/node_modules/string-width": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", - "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", - "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "25.2.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.2.0.tgz", - "integrity": "sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "undici-types": "~7.16.0" + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@types/node/node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==", + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@types/node": "*" + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/@types/secp256k1": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.7.tgz", - "integrity": "sha512-Rcvjl6vARGAKRO6jHeKMatGrvOMGrR/AR11N1x2LqintPCyDZ7NBhrh238Z2VZc7aM7KIwnFpFQ7fnfK4H/9Qw==", + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@types/node": "*" - } - }, - "node_modules/abbrev": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==", - "dev": true, - "license": "ISC" - }, - "node_modules/abitype": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.2.3.tgz", - "integrity": "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/wevm" + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" }, - "peerDependencies": { - "typescript": ">=5.0.4", - "zod": "^3.22.0 || ^4.0.0" + "engines": { + "node": ">=12" }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - }, - "zod": { - "optional": true - } + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "node_modules/@manypkg/find-root": { + "version": "1.1.0", "dev": true, "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "dependencies": { + "@babel/runtime": "^7.5.5", + "@types/node": "^12.7.1", + "find-up": "^4.1.0", + "fs-extra": "^8.1.0" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "node_modules/@manypkg/find-root/node_modules/@types/node": { + "version": "12.20.55", + "dev": true, + "license": "MIT" + }, + "node_modules/@manypkg/find-root/node_modules/fs-extra": { + "version": "8.1.0", "dev": true, "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" } }, - "node_modules/adm-zip": { - "version": "0.4.16", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz", - "integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==", + "node_modules/@manypkg/get-packages": { + "version": "1.1.3", "dev": true, "license": "MIT", - "engines": { - "node": ">=0.3.0" + "dependencies": { + "@babel/runtime": "^7.5.5", + "@changesets/types": "^4.0.1", + "@manypkg/find-root": "^1.1.0", + "fs-extra": "^8.1.0", + "globby": "^11.0.0", + "read-yaml-file": "^1.1.0" } }, - "node_modules/aes-js": { - "version": "4.0.0-beta.5", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz", - "integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==", + "node_modules/@manypkg/get-packages/node_modules/@changesets/types": { + "version": "4.1.0", "dev": true, "license": "MIT" }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "node_modules/@manypkg/get-packages/node_modules/fs-extra": { + "version": "8.1.0", "dev": true, "license": "MIT", "dependencies": { - "debug": "4" + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, "engines": { - "node": ">= 6.0.0" + "node": ">=6 <7 || >=8" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "node_modules/@metamask/abi-utils": { + "version": "2.0.4", "dev": true, - "license": "MIT", + "license": "(Apache-2.0 AND MIT)", "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" + "@metamask/superstruct": "^3.1.0", + "@metamask/utils": "^9.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.0.0" } }, - "node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "node_modules/@metamask/superstruct": { + "version": "3.2.1", "dev": true, "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@metamask/utils": { + "version": "9.3.0", + "dev": true, + "license": "ISC", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" + "@ethereumjs/tx": "^4.2.0", + "@metamask/superstruct": "^3.1.0", + "@noble/hashes": "^1.3.1", + "@scure/base": "^1.1.3", + "@types/debug": "^4.1.7", + "debug": "^4.3.4", + "pony-cause": "^2.1.10", + "semver": "^7.5.4", + "uuid": "^9.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "node_modules/@metamask/utils/node_modules/@noble/hashes": { + "version": "1.8.0", "dev": true, "license": "MIT", - "peerDependencies": { - "ajv": ">=5.0.0" + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==", + "node_modules/@noble/ciphers": { + "version": "1.3.0", "dev": true, - "license": "BSD-3-Clause OR MIT", - "optional": true, + "license": "MIT", "engines": { - "node": ">=0.4.2" + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "node_modules/@noble/curves": { + "version": "2.0.1", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^4.1.0" + "@noble/hashes": "2.0.1" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "node_modules/@noble/hashes": { + "version": "2.0.1", "dev": true, "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", "dev": true, "license": "MIT", "dependencies": { - "type-fest": "^0.21.3" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 8" } }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 8" } }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">= 8" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@nomicfoundation/edr": { + "version": "0.12.0-next.33", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.12.0-next.33.tgz", + "integrity": "sha512-+jwZcGgUKVUykqP+hbVEXClpqZbIdo/MztP/6Xp8DDmB8c+WxJvwCDmPrnfkV+s3NNj2lSDCyOZoPw9/UNcmXw==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@nomicfoundation/edr-darwin-arm64": "0.12.0-next.33", + "@nomicfoundation/edr-darwin-x64": "0.12.0-next.33", + "@nomicfoundation/edr-linux-arm64-gnu": "0.12.0-next.33", + "@nomicfoundation/edr-linux-arm64-musl": "0.12.0-next.33", + "@nomicfoundation/edr-linux-x64-gnu": "0.12.0-next.33", + "@nomicfoundation/edr-linux-x64-musl": "0.12.0-next.33", + "@nomicfoundation/edr-win32-x64-msvc": "0.12.0-next.33" }, "engines": { - "node": ">= 8" + "node": ">= 20" } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/@nomicfoundation/edr-darwin-arm64": { + "version": "0.12.0-next.33", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.12.0-next.33.tgz", + "integrity": "sha512-CEaDltNmTRLyJPMwSVHNtYuXthJ3vm44SkRAQLiDYuhLbbzxAWmkCdnvKyo5QPmaRKxBGFwtahCJz2biBM43Ig==", "dev": true, - "license": "Python-2.0" + "license": "MIT", + "engines": { + "node": ">= 20" + } }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "node_modules/@nomicfoundation/edr-darwin-x64": { + "version": "0.12.0-next.33", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.12.0-next.33.tgz", + "integrity": "sha512-3V5XgzKLXFO+Cw0sWoO3ug2hHYL3VThskA1Iu98EPO44P4w0S6tW3bdsIH2OJPD+zi5RIHjg8H6HDZ+xeipXAA==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 20" } }, - "node_modules/assertion-error": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", - "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { + "version": "0.12.0-next.33", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.12.0-next.33.tgz", + "integrity": "sha512-5+1wkqlUEem9yhKX2AwSINlaiNk6NYfm4WbvaeEAmDZivLEDhW56BNe5+fuue1B4Fa50OONaimw9wEe3d1xYNA==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">= 20" } }, - "node_modules/ast-parents": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", - "integrity": "sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==", + "node_modules/@nomicfoundation/edr-linux-arm64-musl": { + "version": "0.12.0-next.33", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.12.0-next.33.tgz", + "integrity": "sha512-/Zr+9HxJfOSjtSTr3PkErSrGkP40j5op2koY1vVwsC1CqRiNnxKfXpwa6WH8zEUzIkEAGLq5ZwjD251irrf1uA==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 20" + } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "node_modules/@nomicfoundation/edr-linux-x64-gnu": { + "version": "0.12.0-next.33", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.12.0-next.33.tgz", + "integrity": "sha512-KrK/eUlVJo6FdHOBx9kXnzq8g+j8A2218ZVoVI/TJYgZFRXkhUI0tBeDmmdmfcRtk8J4Hw5QGRJVIXA2TAWUZQ==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 20" } }, - "node_modules/async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==", + "node_modules/@nomicfoundation/edr-linux-x64-musl": { + "version": "0.12.0-next.33", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.12.0-next.33.tgz", + "integrity": "sha512-o6Kmj4YKdRNZ6U4wn2hd0wyh3r2Pu0/RjBBiqs+zeeRopI/san7H4n6kIxe+8PbqlAcC48MI+oWLSNwnkqONwg==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 20" + } }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "node_modules/@nomicfoundation/edr-win32-x64-msvc": { + "version": "0.12.0-next.33", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.12.0-next.33.tgz", + "integrity": "sha512-PPiOTOIShzhK7+i+QMDz6/0m2JcEHBMqCthLj8dru2RFhXT1Jory35u12awaVS2fU91flBg7zz7Qju4v8hrnLw==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">= 20" + } }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "node_modules/@nomicfoundation/hardhat-errors": { + "version": "3.0.13", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-errors/-/hardhat-errors-3.0.13.tgz", + "integrity": "sha512-h0nWNzKbmP6XhINMgSUfGixevzksT8BQPK08KNnsr/8kQORAeYzsv6bf0CLUD8mZfmBEP45m4QMlNP6xcoc0Ow==", "dev": true, "license": "MIT", "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@nomicfoundation/hardhat-utils": "^4.1.2" } }, - "node_modules/axios": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.15.2.tgz", - "integrity": "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A==", + "node_modules/@nomicfoundation/hardhat-ethers": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers/-/hardhat-ethers-4.0.7.tgz", + "integrity": "sha512-7wT4/ikhnL44fzJpe4Bh+bnsuWN55P02rbULCvhmcOOCbh/vouIrfVd008Te4+gwx+rYmJtL92vthj/I9dUd0g==", "dev": true, "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.11", - "form-data": "^4.0.5", - "proxy-from-env": "^2.1.0" + "@nomicfoundation/hardhat-errors": "^3.0.10", + "@nomicfoundation/hardhat-utils": "^4.0.2", + "debug": "^4.3.2", + "ethereum-cryptography": "^2.2.1", + "ethers": "^6.14.0" + }, + "peerDependencies": { + "hardhat": "^3.1.11" } }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "node_modules/@nomicfoundation/hardhat-ethers-chai-matchers": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-ethers-chai-matchers/-/hardhat-ethers-chai-matchers-3.0.4.tgz", + "integrity": "sha512-ikChHtkA50U4uyKZ1bJav1Y3wNY4UcDtXw5b3zyYJLWC82UZ9LTkb8tf7wGbU0WQQognUFwkUk7XlWQcylHRZw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@nomicfoundation/hardhat-utils": "^4.0.2", + "@types/chai-as-promised": "^8.0.1", + "chai-as-promised": "^8.0.0", + "deep-eql": "^5.0.1" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ethers": "^4.0.7", + "chai": ">=5.1.2 <7", + "ethers": "^6.14.0", + "hardhat": "^3.0.0" + } }, - "node_modules/base-x": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.11.tgz", - "integrity": "sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==", + "node_modules/@nomicfoundation/hardhat-ethers-chai-matchers/node_modules/@types/chai-as-promised": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-8.0.2.tgz", + "integrity": "sha512-meQ1wDr1K5KRCSvG2lX7n7/5wf70BeptTKst0axGvnN6zqaVpRqegoIbugiAPSqOW9K9aL8gDVrm7a2LXOtn2Q==", "dev": true, "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" + "@types/chai": "*" } }, - "node_modules/better-ajv-errors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/better-ajv-errors/-/better-ajv-errors-2.0.3.tgz", - "integrity": "sha512-t1vxUP+vYKsaYi/BbKo2K98nEAZmfi4sjwvmRT8aOPDzPJeAtLurfoIDazVkLILxO4K+Sw4YrLYnBQ46l6pePg==", + "node_modules/@nomicfoundation/hardhat-ethers-chai-matchers/node_modules/chai-as-promised": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.2.tgz", + "integrity": "sha512-1GadL+sEJVLzDjcawPM4kjfnL+p/9vrxiEUonowKOAzvVg0PixJUdtuDzdkDeQhK3zfOE76GqGkZIQ7/Adcrqw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@humanwhocodes/momoa": "^2.0.4", - "chalk": "^4.1.2", - "jsonpointer": "^5.0.1", - "leven": "^3.1.0 < 4" - }, - "engines": { - "node": ">= 18.20.6" + "license": "MIT", + "dependencies": { + "check-error": "^2.1.1" }, "peerDependencies": { - "ajv": "4.11.8 - 8" + "chai": ">= 2.1.2 < 7" } }, - "node_modules/better-ajv-errors/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@nomicfoundation/hardhat-ethers-chai-matchers/node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">= 16" } }, - "node_modules/better-path-resolve": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/better-path-resolve/-/better-path-resolve-1.0.0.tgz", - "integrity": "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==", + "node_modules/@nomicfoundation/hardhat-ethers-chai-matchers/node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, "license": "MIT", - "dependencies": { - "is-windows": "^1.0.0" - }, "engines": { - "node": ">=4" + "node": ">=6" } }, - "node_modules/bignumber.js": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", - "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dev": true, "license": "MIT", - "engines": { - "node": "*" + "dependencies": { + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 16" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/blakejs": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.2.1.tgz", - "integrity": "sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==", + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", "dev": true, - "license": "MIT" + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "node_modules/bn.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.2.tgz", - "integrity": "sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==", + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "node_modules/boxen": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-5.1.2.tgz", - "integrity": "sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==", + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", "dev": true, "license": "MIT", "dependencies": { - "ansi-align": "^3.0.0", - "camelcase": "^6.2.0", - "chalk": "^4.1.0", - "cli-boxes": "^2.2.1", - "string-width": "^4.2.2", - "type-fest": "^0.20.2", - "widest-line": "^3.1.0", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=10" + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/boxen/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/@nomicfoundation/hardhat-ethers/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" + } + }, + "node_modules/@nomicfoundation/hardhat-mocha": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-mocha/-/hardhat-mocha-3.0.15.tgz", + "integrity": "sha512-nQfLCilO2GEJtFCoJX/ZUgGLTd06Yq5LJAeyIhwdZDWUPrfNMoLCIz6HFWQklhXN8KYOW7aMM+asuFp4nx3lpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nomicfoundation/hardhat-errors": "^3.0.10", + "@nomicfoundation/hardhat-utils": "^4.0.2", + "@nomicfoundation/hardhat-zod-utils": "^3.0.3", + "chalk": "^5.3.0", + "debug": "^4.3.2", + "tsx": "^4.19.3", + "zod": "^3.23.8" }, + "peerDependencies": { + "hardhat": "^3.2.0", + "mocha": "^11.0.0" + } + }, + "node_modules/@nomicfoundation/hardhat-mocha/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/boxen/node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/@nomicfoundation/hardhat-network-helpers": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-3.0.4.tgz", + "integrity": "sha512-WTNISH3/ZkcSDNp//dML18zgV4z3ooeibNcxvv4soCh0AmI8I+2kKaTlKN/Ou1mhKOdiLUbCZCbKNz9LGK3uQw==", "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" + "license": "MIT", + "dependencies": { + "@nomicfoundation/hardhat-errors": "^3.0.7", + "@nomicfoundation/hardhat-utils": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "hardhat": "^3.0.0" } }, - "node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@nomicfoundation/hardhat-utils": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-utils/-/hardhat-utils-4.1.2.tgz", + "integrity": "sha512-jUQfbyIoTLHmSua+BMhIqUIk7uDwL2bhTtJgfwRoVooM3TTvm5rIdRK+eNkvZcZR/wAL/SBQOq/r9yOekj4Unw==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@streamparser/json-node": "^0.0.22", + "env-paths": "^2.2.0", + "ethereum-cryptography": "^2.2.1", + "fast-equals": "^5.4.0", + "json-stream-stringify": "^3.1.6", + "rfdc": "^1.3.1", + "undici": "^6.16.1" } }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "node_modules/@nomicfoundation/hardhat-utils/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dev": true, "license": "MIT", "dependencies": { - "fill-range": "^7.1.1" + "@noble/hashes": "1.4.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/brotli-wasm": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brotli-wasm/-/brotli-wasm-2.0.1.tgz", - "integrity": "sha512-+3USgYsC7bzb5yU0/p2HnnynZl0ak0E6uoIm4UW4Aby/8s8HFCq6NCfrrf1E9c3O8OCSzq3oYO1tUVqIi61Nww==", + "node_modules/@nomicfoundation/hardhat-utils/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", "dev": true, - "license": "Apache-2.0" + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "node_modules/browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "node_modules/@nomicfoundation/hardhat-utils/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", "dev": true, - "license": "ISC" + "license": "MIT", + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "node_modules/@nomicfoundation/hardhat-utils/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", "dev": true, "license": "MIT", "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/bs58": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", - "integrity": "sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==", + "node_modules/@nomicfoundation/hardhat-utils/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", "dev": true, "license": "MIT", "dependencies": { - "base-x": "^3.0.2" + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/bs58check": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", - "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", + "node_modules/@nomicfoundation/hardhat-utils/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dev": true, "license": "MIT", "dependencies": { - "bs58": "^4.0.0", - "create-hash": "^1.1.0", - "safe-buffer": "^5.1.2" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "node_modules/@nomicfoundation/hardhat-utils/node_modules/undici": { + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.23.0.tgz", + "integrity": "sha512-VfQPToRA5FZs/qJxLIinmU59u0r7LXqoJkCzinq3ckNJp3vKEh7jTWN589YQ5+aoAC/TGRLyJLCPKcLQbM8r9g==", "dev": true, "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=18.17" } }, - "node_modules/cacheable-lookup": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", - "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "node_modules/@nomicfoundation/hardhat-vendored": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-vendored/-/hardhat-vendored-3.0.4.tgz", + "integrity": "sha512-RO8Otj1FvRvxJmXzkxh1vTwK/+cqSVPYLqY6RrWkmzHEEcxnAwAFsBYdW7xyTEyW/pVbSSNd2gs3aoGdGZaoNA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.16" - } + "license": "MIT" }, - "node_modules/cacheable-request": { - "version": "10.2.14", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.14.tgz", - "integrity": "sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==", + "node_modules/@nomicfoundation/hardhat-zod-utils": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-zod-utils/-/hardhat-zod-utils-3.0.5.tgz", + "integrity": "sha512-A1G9Jcizf/vYcGMtqkf+st94zBPTDB+bXXlojOMu77gmBZYbywY0k7hdRM2B4uJY+8nM0oe0sNVGVkARITXdcw==", "dev": true, "license": "MIT", "dependencies": { - "@types/http-cache-semantics": "^4.0.2", - "get-stream": "^6.0.1", - "http-cache-semantics": "^4.1.1", - "keyv": "^4.5.3", - "mimic-response": "^4.0.0", - "normalize-url": "^8.0.0", - "responselike": "^3.0.0" + "@nomicfoundation/hardhat-errors": "^3.0.13", + "@nomicfoundation/hardhat-utils": "^4.1.2" }, - "engines": { - "node": ">=14.16" + "peerDependencies": { + "zod": "^3.23.8" } }, - "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "node_modules/@nomicfoundation/slang": { + "version": "0.18.3", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "@bytecodealliance/preview2-shim": "0.17.0" } }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "node_modules/@nomicfoundation/solidity-analyzer": { + "version": "0.1.2", "dev": true, "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, "engines": { - "node": ">= 0.4" + "node": ">= 12" + }, + "optionalDependencies": { + "@nomicfoundation/solidity-analyzer-darwin-arm64": "0.1.2", + "@nomicfoundation/solidity-analyzer-darwin-x64": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-arm64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-gnu": "0.1.2", + "@nomicfoundation/solidity-analyzer-linux-x64-musl": "0.1.2", + "@nomicfoundation/solidity-analyzer-win32-x64-msvc": "0.1.2" } }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "node_modules/@nomicfoundation/solidity-analyzer-darwin-arm64": { + "version": "0.1.2", "dev": true, "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, + "optional": true, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">= 12" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/@nomicfoundation/solidity-analyzer-darwin-x64": { + "version": "0.1.2", "dev": true, "license": "MIT", + "optional": true, "engines": { - "node": ">=6" + "node": ">= 12" } }, - "node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-gnu": { + "version": "0.1.2", "dev": true, "license": "MIT", + "optional": true, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 12" } }, - "node_modules/cbor": { - "version": "10.0.11", - "resolved": "https://registry.npmjs.org/cbor/-/cbor-10.0.11.tgz", - "integrity": "sha512-vIwORDd/WyB8Nc23o2zNN5RrtFGlR6Fca61TtjkUXueI3Jf2DOZDl1zsshvBntZ3wZHBM9ztjnkXSmzQDaq3WA==", + "node_modules/@nomicfoundation/solidity-analyzer-linux-arm64-musl": { + "version": "0.1.2", "dev": true, "license": "MIT", - "dependencies": { - "nofilter": "^3.0.2" - }, + "optional": true, "engines": { - "node": ">=20" + "node": ">= 12" } }, - "node_modules/chai": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz", - "integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==", + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-gnu": { + "version": "0.1.2", "dev": true, "license": "MIT", - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.1.0" - }, + "optional": true, "engines": { - "node": ">=4" + "node": ">= 12" } }, - "node_modules/chai-as-promised": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.2.tgz", - "integrity": "sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==", + "node_modules/@nomicfoundation/solidity-analyzer-linux-x64-musl": { + "version": "0.1.2", "dev": true, - "license": "WTFPL", - "dependencies": { - "check-error": "^1.0.2" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 6" + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 12" } }, - "node_modules/chai/node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "node_modules/@nomicfoundation/solidity-analyzer-win32-x64-msvc": { + "version": "0.1.2", "dev": true, "license": "MIT", + "optional": true, "engines": { - "node": "*" + "node": ">= 12" } }, - "node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "node_modules/@openzeppelin/docs-utils": { + "version": "0.1.6", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@frangio/servbot": "^0.3.0-1", + "chalk": "^3.0.0", + "chokidar": "^3.5.3", + "env-paths": "^2.2.0", + "find-up": "^4.1.0", + "is-port-reachable": "^3.0.0", + "js-yaml": "^3.13.1", + "lodash.startcase": "^4.4.0", + "minimist": "^1.2.0" }, - "engines": { - "node": ">=8" + "bin": { + "oz-docs": "oz-docs.js" } }, - "node_modules/chardet": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", - "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "node_modules/@openzeppelin/docs-utils/node_modules/argparse": { + "version": "1.0.10", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "node_modules/@openzeppelin/docs-utils/node_modules/esprima": { + "version": "4.0.1", "dev": true, - "license": "BSD-3-Clause", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, "engines": { - "node": "*" + "node": ">=4" } }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", + "node_modules/@openzeppelin/docs-utils/node_modules/js-yaml": { + "version": "3.14.2", "dev": true, "license": "MIT", "dependencies": { - "get-func-name": "^2.0.2" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "engines": { - "node": "*" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "node_modules/@openzeppelin/merkle-tree": { + "version": "1.0.8", "dev": true, "license": "MIT", "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "@metamask/abi-utils": "^2.0.4", + "ethereum-cryptography": "^3.0.0" } }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "node_modules/@openzeppelin/upgrade-safe-transpiler": { + "version": "0.4.1", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "ajv": "^8.0.0", + "compare-versions": "^6.0.0", + "ethereum-cryptography": "^3.0.0", + "lodash": "^4.17.20", + "minimatch": "^10.0.3", + "minimist": "^1.2.5", + "solidity-ast": "^0.4.51" + }, + "bin": { + "upgrade-safe-transpiler": "dist/cli.js" } }, - "node_modules/cipher-base": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.7.tgz", - "integrity": "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==", + "node_modules/@openzeppelin/upgrades-core": { + "version": "1.44.2", "dev": true, "license": "MIT", "dependencies": { - "inherits": "^2.0.4", - "safe-buffer": "^5.2.1", - "to-buffer": "^1.2.2" + "@nomicfoundation/slang": "^0.18.3", + "bignumber.js": "^9.1.2", + "cbor": "^10.0.0", + "chalk": "^4.1.0", + "compare-versions": "^6.0.0", + "debug": "^4.1.1", + "ethereumjs-util": "^7.0.3", + "minimatch": "^9.0.5", + "minimist": "^1.2.7", + "proper-lockfile": "^4.1.1", + "solidity-ast": "^0.4.60" }, - "engines": { - "node": ">= 0.10" + "bin": { + "openzeppelin-upgrades-core": "dist/cli/cli.js" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "node_modules/@openzeppelin/upgrades-core/node_modules/brace-expansion": { + "version": "2.0.2", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "balanced-match": "^1.0.0" } }, - "node_modules/cli-boxes": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.1.tgz", - "integrity": "sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==", + "node_modules/@openzeppelin/upgrades-core/node_modules/chalk": { + "version": "4.1.2", "dev": true, "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": ">=6" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/cli-cursor": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", - "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "node_modules/@openzeppelin/upgrades-core/node_modules/minimatch": { + "version": "9.0.5", "dev": true, - "license": "MIT", + "license": "ISC", "dependencies": { - "restore-cursor": "^5.0.0" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=18" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cli-table3": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz", - "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==", + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", "dev": true, "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, + "optional": true, + "peer": true, "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" + "node": ">=14" } }, - "node_modules/cli-truncate": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", - "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", + "node_modules/@pnpm/config.env-replace": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.22.0" + } + }, + "node_modules/@pnpm/network.ca-file": { + "version": "1.0.2", "dev": true, "license": "MIT", "dependencies": { - "slice-ansi": "^8.0.0", - "string-width": "^8.2.0" + "graceful-fs": "4.2.10" }, "engines": { - "node": ">=20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12.22.0" } }, - "node_modules/cli-truncate/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": { + "version": "4.2.10", + "dev": true, + "license": "ISC" + }, + "node_modules/@pnpm/npm-conf": { + "version": "3.0.2", "dev": true, "license": "MIT", + "dependencies": { + "@pnpm/config.env-replace": "^1.1.0", + "@pnpm/network.ca-file": "^1.0.1", + "config-chain": "^1.1.11" + }, "engines": { "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/cli-truncate/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "node_modules/@scure/base": { + "version": "1.2.6", "dev": true, "license": "MIT", - "engines": { - "node": ">=12" - }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/cli-truncate/node_modules/slice-ansi": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", - "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", + "node_modules/@scure/bip32": { + "version": "1.7.0", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.3", - "is-fullwidth-code-point": "^5.1.0" - }, - "engines": { - "node": ">=20" + "@noble/curves": "~1.9.0", + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/cli-truncate/node_modules/string-width": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", - "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", + "node_modules/@scure/bip32/node_modules/@noble/curves": { + "version": "1.9.7", "dev": true, "license": "MIT", "dependencies": { - "get-east-asian-width": "^1.5.0", - "strip-ansi": "^7.1.2" + "@noble/hashes": "1.8.0" }, "engines": { - "node": ">=20" + "node": "^14.21.3 || >=16" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/cli-truncate/node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "node_modules/@scure/bip32/node_modules/@noble/hashes": { + "version": "1.8.0", "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^6.2.2" - }, "engines": { - "node": ">=12" + "node": "^14.21.3 || >=16" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/cliui": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", - "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "node_modules/@scure/bip39": { + "version": "1.6.0", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "string-width": "^7.2.0", - "strip-ansi": "^7.1.0", - "wrap-ansi": "^9.0.0" + "@noble/hashes": "~1.8.0", + "@scure/base": "~1.2.5" }, - "engines": { - "node": ">=20" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "node_modules/@scure/bip39/node_modules/@noble/hashes": { + "version": "1.8.0", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": "^14.21.3 || >=16" }, "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "node_modules/@sentry/core": { + "version": "9.47.1", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-9.47.1.tgz", + "integrity": "sha512-KX62+qIt4xgy8eHKHiikfhz2p5fOciXd0Cl+dNzhgPFq8klq4MGMNaf148GB3M/vBqP4nw/eFvRMAayFCgdRQw==", "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@sindresorhus/is": { + "version": "5.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "node_modules/@solidity-parser/parser": { + "version": "0.20.2", "dev": true, "license": "MIT" }, - "node_modules/cliui/node_modules/string-width": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "node_modules/@streamparser/json": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@streamparser/json/-/json-0.0.22.tgz", + "integrity": "sha512-b6gTSBjJ8G8SuO3Gbbj+zXbVx8NSs1EbpbMKpzGLWMdkR+98McH9bEjSz3+0mPJf68c5nxa3CrJHp5EQNXM6zQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@streamparser/json-node": { + "version": "0.0.22", + "resolved": "https://registry.npmjs.org/@streamparser/json-node/-/json-node-0.0.22.tgz", + "integrity": "sha512-sJT2ptNRwqB1lIsQrQlCoWk5rF4tif9wDh+7yluAGijJamAhrHGYpFB/Zg3hJeceoZypi74ftXk8DHzwYpbZSg==", "dev": true, "license": "MIT", "dependencies": { - "emoji-regex": "^10.3.0", - "get-east-asian-width": "^1.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@streamparser/json": "^0.0.22" } }, - "node_modules/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "node_modules/@szmarczak/http-timer": { + "version": "5.0.1", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "defer-to-connect": "^2.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "node": ">=14.16" } }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", - "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "node_modules/@types/bn.js": { + "version": "5.2.0", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "string-width": "^7.0.0", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "@types/node": "*" } }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/@types/chai": { + "version": "5.2.3", "dev": true, "license": "MIT", "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "node_modules/@types/debug": { + "version": "4.1.12", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", "dev": true, "license": "MIT" }, - "node_modules/combined-stream": { + "node_modules/@types/estree": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } + "license": "MIT" }, - "node_modules/command-exists": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz", - "integrity": "sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==", + "node_modules/@types/http-cache-semantics": { + "version": "4.2.0", "dev": true, "license": "MIT" }, - "node_modules/compare-versions": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.1.tgz", - "integrity": "sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==", + "node_modules/@types/json-schema": { + "version": "7.0.15", "dev": true, "license": "MIT" }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "node_modules/@types/ms": { + "version": "2.1.0", "dev": true, "license": "MIT" }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", + "node_modules/@types/node": { + "version": "25.2.0", "dev": true, "license": "MIT", "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" + "undici-types": "~7.16.0" } }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "node_modules/@types/node/node_modules/undici-types": { + "version": "7.16.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/pbkdf2": { + "version": "3.1.2", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.6" + "dependencies": { + "@types/node": "*" } }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "node_modules/@types/secp256k1": { + "version": "4.0.7", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@types/node": "*" + } }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", "dev": true, "license": "MIT", "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@types/yargs-parser": "*" } }, - "node_modules/crc-32": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT" + }, + "node_modules/acorn": { + "version": "8.15.0", + "dev": true, + "license": "MIT", "bin": { - "crc32": "bin/crc32.njs" + "acorn": "bin/acorn" }, "engines": { - "node": ">=0.8" + "node": ">=0.4.0" } }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "node_modules/acorn-jsx": { + "version": "5.3.2", "dev": true, "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "node_modules/adm-zip": { + "version": "0.4.16", "dev": true, "license": "MIT", - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "engines": { + "node": ">=0.3.0" } }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "node_modules/aes-js": { + "version": "4.0.0-beta.5", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv": { + "version": "8.17.1", "dev": true, "license": "MIT", "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, - "engines": { - "node": ">= 8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "node_modules/ajv-errors": { + "version": "1.0.1", "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": "*" + "license": "MIT", + "peerDependencies": { + "ajv": ">=5.0.0" } }, - "node_modules/dataloader": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", - "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==", + "node_modules/ansi-colors": { + "version": "4.1.3", "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==", - "dev": true + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "node_modules/ansi-escapes": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz", + "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==", "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.3" + "environment": "^1.0.0" }, "engines": { - "node": ">=6.0" + "node": ">=18" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "node_modules/ansi-regex": { + "version": "5.0.1", "dev": true, "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "node_modules/ansi-styles": { + "version": "4.3.0", "dev": true, "license": "MIT", "dependencies": { - "mimic-response": "^3.1.0" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "node_modules/anymatch": { + "version": "3.1.3", "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">= 8" } }, - "node_modules/deep-eql": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz", - "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==", + "node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-union": { + "version": "2.1.0", "dev": true, "license": "MIT", - "dependencies": { - "type-detect": "^4.0.0" - }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "node_modules/assertion-error": { + "version": "2.0.1", "dev": true, "license": "MIT", "engines": { - "node": ">=4.0.0" + "node": ">=12" } }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "node_modules/ast-parents": { + "version": "0.0.1", "dev": true, "license": "MIT" }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "node_modules/astral-regex": { + "version": "2.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "node_modules/available-typed-arrays": { + "version": "1.0.7", "dev": true, "license": "MIT", "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" + "possible-typed-array-names": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -4023,245 +2679,241 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "node_modules/balanced-match": { + "version": "1.0.2", "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } + "license": "MIT" }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "node_modules/base-x": { + "version": "3.0.11", "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "safe-buffer": "^5.0.1" } }, - "node_modules/diff": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", - "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "node_modules/better-ajv-errors": { + "version": "2.0.3", "dev": true, - "license": "BSD-3-Clause", + "license": "Apache-2.0", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@humanwhocodes/momoa": "^2.0.4", + "chalk": "^4.1.2", + "jsonpointer": "^5.0.1", + "leven": "^3.1.0 < 4" + }, "engines": { - "node": ">=0.3.1" + "node": ">= 18.20.6" + }, + "peerDependencies": { + "ajv": "4.11.8 - 8" } }, - "node_modules/difflib": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/difflib/-/difflib-0.2.4.tgz", - "integrity": "sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==", + "node_modules/better-ajv-errors/node_modules/chalk": { + "version": "4.1.2", "dev": true, + "license": "MIT", "dependencies": { - "heap": ">= 0.2.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": "*" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "node_modules/better-path-resolve": { + "version": "1.0.0", "dev": true, "license": "MIT", "dependencies": { - "path-type": "^4.0.0" + "is-windows": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, - "node_modules/dotenv": { - "version": "8.6.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.6.0.tgz", - "integrity": "sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==", + "node_modules/bignumber.js": { + "version": "9.3.1", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "engines": { - "node": ">=10" + "node": "*" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "node_modules/binary-extensions": { + "version": "2.3.0", "dev": true, "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, "engines": { - "node": ">= 0.4" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "node_modules/blakejs": { + "version": "1.2.1", "dev": true, "license": "MIT" }, - "node_modules/elliptic": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.6.1.tgz", - "integrity": "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==", + "node_modules/bn.js": { + "version": "5.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", "dev": true, "license": "MIT", "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.2.tgz", - "integrity": "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw==", + "node_modules/brorand": { + "version": "1.1.0", "dev": true, "license": "MIT" }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "node_modules/browser-stdout": { + "version": "1.3.1", "dev": true, - "license": "MIT" + "license": "ISC", + "peer": true }, - "node_modules/enquirer": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.4.1.tgz", - "integrity": "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==", + "node_modules/browserify-aes": { + "version": "1.2.0", "dev": true, "license": "MIT", "dependencies": { - "ansi-colors": "^4.1.1", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8.6" + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" } }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "node_modules/bs58": { + "version": "4.0.1", "dev": true, "license": "MIT", - "engines": { - "node": ">=6" + "dependencies": { + "base-x": "^3.0.2" } }, - "node_modules/environment": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", - "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "node_modules/bs58check": { + "version": "2.1.2", "dev": true, "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" } }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/cacheable-lookup": { + "version": "7.0.0", "dev": true, "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" + "engines": { + "node": ">=14.16" } }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "node_modules/cacheable-request": { + "version": "10.2.14", "dev": true, "license": "MIT", + "dependencies": { + "@types/http-cache-semantics": "^4.0.2", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.3", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" + }, "engines": { - "node": ">= 0.4" + "node": ">=14.16" } }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "node_modules/call-bind": { + "version": "1.0.8", "dev": true, "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, "engines": { "node": ">= 0.4" } }, - "node_modules/es-set-tostringtag": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", - "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "node_modules/call-bound": { + "version": "1.0.4", "dev": true, "license": "MIT", "dependencies": { - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.6", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.2" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "node_modules/callsites": { + "version": "3.1.0", "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/camelcase": { + "version": "6.3.0", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -4269,1011 +2921,919 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==", + "node_modules/cbor": { + "version": "10.0.11", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "esprima": "^2.7.1", - "estraverse": "^1.9.1", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=0.12.0" + "nofilter": "^3.0.2" }, - "optionalDependencies": { - "source-map": "~0.2.0" - } - }, - "node_modules/escodegen/node_modules/estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==", - "dev": true, "engines": { - "node": ">=0.10.0" + "node": ">=20" } }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "dev": true, "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=18" } }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/chai/node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", "dev": true, "license": "MIT", - "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - }, "engines": { - "node": ">= 0.8.0" + "node": ">= 16" } }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "node_modules/chai/node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", + "node_modules/chalk": { + "version": "3.0.0", "dev": true, "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">= 0.8.0" + "node": ">=8" } }, - "node_modules/eslint": { - "version": "9.39.2", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.2.tgz", - "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", + "node_modules/chardet": { + "version": "2.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "3.6.0", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.21.1", - "@eslint/config-helpers": "^0.4.2", - "@eslint/core": "^0.17.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.39.2", - "@eslint/plugin-kit": "^0.4.1", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.4.0", - "eslint-visitor-keys": "^4.2.1", - "espree": "^10.4.0", - "esquery": "^1.5.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">= 8.10.0" }, "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" + "url": "https://paulmillr.com/funding/" }, - "peerDependenciesMeta": { - "jiti": { - "optional": true + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" } + ], + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/eslint-config-prettier": { - "version": "10.1.8", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", - "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", + "node_modules/cipher-base": { + "version": "1.0.7", "dev": true, "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "funding": { - "url": "https://opencollective.com/eslint-config-prettier" + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.2" }, - "peerDependencies": { - "eslint": ">=7.0.0" + "engines": { + "node": ">= 0.10" } }, - "node_modules/eslint-scope": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "restore-cursor": "^5.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "node_modules/cli-truncate": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz", + "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "dependencies": { + "slice-ansi": "^8.0.0", + "string-width": "^8.2.0" + }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=20" }, "funding": { - "url": "https://opencollective.com/eslint" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "node_modules/cli-truncate/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "engines": { + "node": ">=12" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/eslint/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/cli-truncate/node_modules/string-width": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.1.tgz", + "integrity": "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" }, "engines": { - "node": ">=10" + "node": ">=20" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/cli-truncate/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "ansi-regex": "^6.2.2" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/eslint/node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "node_modules/cliui": { + "version": "9.0.1", "dev": true, "license": "ISC", "dependencies": { - "is-glob": "^4.0.3" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=20" } }, - "node_modules/eslint/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/cliui/node_modules/ansi-regex": { + "version": "6.2.2", "dev": true, "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.3", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.6.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", "dev": true, "license": "MIT", "dependencies": { - "yocto-queue": "^0.1.0" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/cliui/node_modules/strip-ansi": { + "version": "7.1.2", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^3.0.2" + "ansi-regex": "^6.0.1" }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/eslint/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", "dev": true, "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "node_modules/color-convert": { + "version": "2.0.1", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "color-name": "~1.1.4" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=7.0.0" } }, - "node_modules/esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==", + "node_modules/color-name": { + "version": "1.1.4", "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=0.10.0" + "license": "MIT" + }, + "node_modules/compare-versions": { + "version": "6.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/config-chain": { + "version": "1.1.13", + "dev": true, + "license": "MIT", + "dependencies": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" } }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "node_modules/core-util-is": { + "version": "1.0.3", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "dev": true, + "license": "MIT", "dependencies": { - "estraverse": "^5.1.0" + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" }, "engines": { - "node": ">=0.10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/crc-32": { + "version": "1.2.2", "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" + "license": "Apache-2.0", + "bin": { + "crc32": "bin/crc32.njs" }, "engines": { - "node": ">=4.0" + "node": ">=0.8" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "node_modules/create-hash": { + "version": "1.2.0", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" } }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/create-hmac": { + "version": "1.1.7", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" } }, - "node_modules/ethereum-bloom-filters": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.2.0.tgz", - "integrity": "sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==", + "node_modules/cross-spawn": { + "version": "7.0.6", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "^1.4.0" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" } }, - "node_modules/ethereum-bloom-filters/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/dataloader": { + "version": "1.4.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/debug": { + "version": "4.4.3", "dev": true, "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=6.0" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/ethereum-cryptography": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-3.2.0.tgz", - "integrity": "sha512-Urr5YVsalH+Jo0sYkTkv1MyI9bLYZwW8BENZCeE1QYaTHETEYx0Nv/SVsWkSqpYrzweg6d8KMY1wTjH/1m/BIg==", + "node_modules/decamelize": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "@noble/ciphers": "1.3.0", - "@noble/curves": "1.9.0", - "@noble/hashes": "1.8.0", - "@scure/bip32": "1.7.0", - "@scure/bip39": "1.6.0" - }, + "peer": true, "engines": { - "node": "^14.21.3 || >=16", - "npm": ">=9" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ethereum-cryptography/node_modules/@noble/curves": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", - "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", + "node_modules/decompress-response": { + "version": "6.0.0", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "1.8.0" + "mimic-response": "^3.1.0" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=10" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ethereum-cryptography/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", "dev": true, "license": "MIT", "engines": { - "node": "^14.21.3 || >=16" + "node": ">=10" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ethereumjs-util": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz", - "integrity": "sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==", + "node_modules/deep-extend": { + "version": "0.6.0", "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@types/bn.js": "^5.1.0", - "bn.js": "^5.1.2", - "create-hash": "^1.1.2", - "ethereum-cryptography": "^0.1.3", - "rlp": "^2.2.4" - }, + "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=4.0.0" } }, - "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", - "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", + "node_modules/deep-is": { + "version": "0.1.4", "dev": true, - "license": "MIT", - "dependencies": { - "@types/pbkdf2": "^3.0.0", - "@types/secp256k1": "^4.0.1", - "blakejs": "^1.1.0", - "browserify-aes": "^1.2.0", - "bs58check": "^2.1.2", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "hash.js": "^1.1.7", - "keccak": "^3.0.0", - "pbkdf2": "^3.0.17", - "randombytes": "^2.1.0", - "safe-buffer": "^5.1.2", - "scrypt-js": "^3.0.0", - "secp256k1": "^4.0.1", - "setimmediate": "^1.0.5" - } + "license": "MIT" }, - "node_modules/ethers": { - "version": "6.16.0", - "resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz", - "integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==", + "node_modules/defer-to-connect": { + "version": "2.0.1", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/ethers-io/" - }, - { - "type": "individual", - "url": "https://www.buymeacoffee.com/ricmoo" - } - ], "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "1.10.1", - "@noble/curves": "1.2.0", - "@noble/hashes": "1.3.2", - "@types/node": "22.7.5", - "aes-js": "4.0.0-beta.5", - "tslib": "2.7.0", - "ws": "8.17.1" - }, "engines": { - "node": ">=14.0.0" + "node": ">=10" } }, - "node_modules/ethers/node_modules/@noble/curves": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz", - "integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==", + "node_modules/define-data-property": { + "version": "1.1.4", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "1.3.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ethers/node_modules/@noble/hashes": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz", - "integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==", + "node_modules/detect-indent": { + "version": "6.1.0", "dev": true, "license": "MIT", "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "node": ">=8" } }, - "node_modules/ethers/node_modules/@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==", + "node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=0.3.1" } }, - "node_modules/ethjs-unit": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", - "integrity": "sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==", + "node_modules/dir-glob": { + "version": "3.0.1", "dev": true, "license": "MIT", "dependencies": { - "bn.js": "4.11.6", - "number-to-bn": "1.7.0" + "path-type": "^4.0.0" }, "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "node": ">=8" } }, - "node_modules/ethjs-unit/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "license": "MIT" - }, - "node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "node_modules/dotenv": { + "version": "8.6.0", "dev": true, - "license": "MIT" + "license": "BSD-2-Clause", + "engines": { + "node": ">=10" + } }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "node_modules/dunder-proto": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/extendable-error": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/extendable-error/-/extendable-error-0.1.7.tgz", - "integrity": "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "node_modules/eastasianwidth": { + "version": "0.2.0", "dev": true, - "license": "Apache-2.0" + "license": "MIT", + "peer": true }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "node_modules/elliptic": { + "version": "6.6.1", "dev": true, "license": "MIT", "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" } }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.2", "dev": true, "license": "MIT" }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "node_modules/emoji-regex": { + "version": "8.0.0", "dev": true, "license": "MIT" }, - "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "node_modules/enquirer": { + "version": "2.4.1", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8.6" + } }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "node_modules/env-paths": { + "version": "2.2.1", "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, "engines": { - "node": ">=16.0.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "node_modules/error-ex": { + "version": "1.3.4", "dev": true, "license": "MIT", "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" + "is-arrayish": "^0.2.1" } }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "node_modules/es-define-property": { + "version": "1.0.1", "dev": true, "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, "engines": { - "node": ">=8" + "node": ">= 0.4" } }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "node_modules/es-errors": { + "version": "1.3.0", "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "node_modules/es-object-atoms": { + "version": "1.1.1", "dev": true, "license": "MIT", "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" + "es-errors": "^1.3.0" }, "engines": { - "node": ">=16" + "node": ">= 0.4" } }, - "node_modules/flatted": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", - "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", "dev": true, - "license": "ISC" + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } }, - "node_modules/follow-redirects": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.16.0.tgz", - "integrity": "sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==", + "node_modules/escalade": { + "version": "3.2.0", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], "license": "MIT", "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } + "node": ">=6" } }, - "node_modules/for-each": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", - "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "node_modules/escape-string-regexp": { + "version": "4.0.0", "dev": true, "license": "MIT", - "dependencies": { - "is-callable": "^1.2.7" - }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/foreground-child": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", - "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "node_modules/eslint": { + "version": "9.39.2", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.2", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", "cross-spawn": "^7.0.6", - "signal-exit": "^4.0.1" + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=14" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/foreground-child/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "node_modules/eslint-config-prettier": { + "version": "10.1.8", "dev": true, - "license": "ISC", - "engines": { - "node": ">=14" + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://opencollective.com/eslint-config-prettier" + }, + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/form-data": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", - "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "node_modules/eslint-scope": { + "version": "8.4.0", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "es-set-tostringtag": "^2.1.0", - "hasown": "^2.0.2", - "mime-types": "^2.1.12" + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" }, "engines": { - "node": ">= 6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/form-data-encoder": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", - "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">= 14.17" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/fp-ts": { - "version": "1.19.3", - "resolved": "https://registry.npmjs.org/fp-ts/-/fp-ts-1.19.3.tgz", - "integrity": "sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==", - "dev": true, - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" }, - "engines": { - "node": ">=6 <7 || >=8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "node_modules/eslint/node_modules/chalk": { + "version": "4.1.2", "dev": true, - "hasInstallScript": true, "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "node_modules/eslint/node_modules/find-up": { + "version": "5.0.0", "dev": true, "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", "dev": true, "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, "engines": { - "node": "6.* || 8.* || >= 10.*" + "node": ">=10.13.0" } }, - "node_modules/get-east-asian-width": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", - "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint/node_modules/locate-path": { + "version": "6.0.0", "dev": true, "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, "engines": { - "node": ">=18" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { "node": "*" } }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "node_modules/eslint/node_modules/p-limit": { + "version": "3.1.0", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">= 0.4" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "node_modules/eslint/node_modules/p-locate": { + "version": "5.0.0", "dev": true, "license": "MIT", "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" + "p-limit": "^3.0.2" }, "engines": { - "node": ">= 0.4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/eslint/node_modules/yocto-queue": { + "version": "0.1.0", "dev": true, "license": "MIT", "engines": { @@ -5283,879 +3843,769 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ghost-testrpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", - "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", + "node_modules/espree": { + "version": "10.4.0", "dev": true, - "license": "ISC", + "license": "BSD-2-Clause", "dependencies": { - "chalk": "^2.4.2", - "node-emoji": "^1.10.0" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, - "bin": { - "testrpc-sc": "index.js" + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/ghost-testrpc/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/esquery": { + "version": "1.7.0", "dev": true, - "license": "MIT", + "license": "BSD-3-Clause", "dependencies": { - "color-convert": "^1.9.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=4" + "node": ">=0.10" } }, - "node_modules/ghost-testrpc/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "node_modules/esrecurse": { + "version": "4.3.0", "dev": true, - "license": "MIT", + "license": "BSD-2-Clause", "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "estraverse": "^5.2.0" }, "engines": { - "node": ">=4" + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" } }, - "node_modules/ghost-testrpc/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "node_modules/ethereum-cryptography": { + "version": "3.2.0", "dev": true, "license": "MIT", "dependencies": { - "color-name": "1.1.3" + "@noble/ciphers": "1.3.0", + "@noble/curves": "1.9.0", + "@noble/hashes": "1.8.0", + "@scure/bip32": "1.7.0", + "@scure/bip39": "1.6.0" + }, + "engines": { + "node": "^14.21.3 || >=16", + "npm": ">=9" } }, - "node_modules/ghost-testrpc/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "node_modules/ethereum-cryptography/node_modules/@noble/curves": { + "version": "1.9.0", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "@noble/hashes": "1.8.0" + }, + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } }, - "node_modules/ghost-testrpc/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/ethereum-cryptography/node_modules/@noble/hashes": { + "version": "1.8.0", "dev": true, "license": "MIT", "engines": { - "node": ">=0.8.0" + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/ghost-testrpc/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "node_modules/ethereumjs-util": { + "version": "7.1.5", "dev": true, - "license": "MIT", + "license": "MPL-2.0", + "dependencies": { + "@types/bn.js": "^5.1.0", + "bn.js": "^5.1.2", + "create-hash": "^1.1.2", + "ethereum-cryptography": "^0.1.3", + "rlp": "^2.2.4" + }, "engines": { - "node": ">=4" + "node": ">=10.0.0" + } + }, + "node_modules/ethereumjs-util/node_modules/ethereum-cryptography": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" } }, - "node_modules/ghost-testrpc/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/ethers": { + "version": "6.16.0", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/ethers-io/" + }, + { + "type": "individual", + "url": "https://www.buymeacoffee.com/ricmoo" + } + ], "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@adraffy/ens-normalize": "1.10.1", + "@noble/curves": "1.2.0", + "@noble/hashes": "1.3.2", + "@types/node": "22.7.5", + "aes-js": "4.0.0-beta.5", + "tslib": "2.7.0", + "ws": "8.17.1" }, "engines": { - "node": ">=4" + "node": ">=14.0.0" } }, - "node_modules/glob": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", - "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", + "node_modules/ethers/node_modules/@noble/curves": { + "version": "1.2.0", "dev": true, - "license": "BlueOak-1.0.0", + "license": "MIT", "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" + "@noble/hashes": "1.3.2" }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ethers/node_modules/@noble/hashes": { + "version": "1.3.2", + "dev": true, + "license": "MIT", "engines": { - "node": "20 || >=22" + "node": ">= 16" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "node_modules/ethers/node_modules/@types/node": { + "version": "22.7.5", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" + "undici-types": "~6.19.2" + } + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" } }, - "node_modules/global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "node_modules/extendable-error": { + "version": "0.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-diff": { + "version": "1.3.0", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/fast-equals": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-5.4.0.tgz", + "integrity": "sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==", "dev": true, "license": "MIT", - "dependencies": { - "global-prefix": "^3.0.0" - }, "engines": { - "node": ">=6" + "node": ">=6.0.0" } }, - "node_modules/global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "node_modules/fast-glob": { + "version": "3.3.3", "dev": true, "license": "MIT", "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" }, "engines": { - "node": ">=6" + "node": ">=8.6.0" } }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.20.1", "dev": true, "license": "ISC", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" + "reusify": "^1.0.4" } }, - "node_modules/globals": { - "version": "17.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.3.0.tgz", - "integrity": "sha512-yMqGUQVVCkD4tqjOJf3TnrvaaHDMYp4VlUSObbkIiuCPe/ofdMBFIAcBbCSRFWOnos6qRiTVStDwqPLUclaxIw==", + "node_modules/file-entry-cache": { + "version": "8.0.0", "dev": true, "license": "MIT", - "engines": { - "node": ">=18" + "dependencies": { + "flat-cache": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=16.0.0" } }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "node_modules/fill-range": { + "version": "7.1.1", "dev": true, "license": "MIT", "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" + "to-regex-range": "^5.0.1" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "node_modules/find-up": { + "version": "4.1.0", "dev": true, "license": "MIT", - "engines": { - "node": ">= 0.4" + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=8" } }, - "node_modules/got": { - "version": "12.6.1", - "resolved": "https://registry.npmjs.org/got/-/got-12.6.1.tgz", - "integrity": "sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==", + "node_modules/flat": { + "version": "5.0.2", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", "dev": true, "license": "MIT", "dependencies": { - "@sindresorhus/is": "^5.2.0", - "@szmarczak/http-timer": "^5.0.1", - "cacheable-lookup": "^7.0.0", - "cacheable-request": "^10.2.8", - "decompress-response": "^6.0.0", - "form-data-encoder": "^2.1.2", - "get-stream": "^6.0.1", - "http2-wrapper": "^2.1.10", - "lowercase-keys": "^3.0.0", - "p-cancelable": "^3.0.0", - "responselike": "^3.0.0" + "flatted": "^3.2.9", + "keyv": "^4.5.4" }, "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" + "node": ">=16" } }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "node_modules/flatted": { + "version": "3.3.3", "dev": true, "license": "ISC" }, - "node_modules/graphlib": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz", - "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==", + "node_modules/for-each": { + "version": "0.3.5", "dev": true, "license": "MIT", "dependencies": { - "lodash": "^4.17.15" + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/handlebars": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", - "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", + "node_modules/foreground-child": { + "version": "3.3.1", "dev": true, - "license": "MIT", + "license": "ISC", + "peer": true, "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" }, "engines": { - "node": ">=0.4.7" + "node": ">=14" }, - "optionalDependencies": { - "uglify-js": "^3.1.4" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/handlebars/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", "dev": true, - "license": "BSD-3-Clause", + "license": "ISC", + "peer": true, "engines": { - "node": ">=0.10.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/hardhat": { - "version": "2.28.5", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.28.5.tgz", - "integrity": "sha512-AlTvFAiLYXdy732uyzVWMFw5qjEpfAI0x9xMNe73cBzzD98ST783EaElDzbOXddJ7ro1Z3447FbO0xSinXfTVA==", + "node_modules/form-data-encoder": { + "version": "2.1.4", "dev": true, "license": "MIT", - "dependencies": { - "@ethereumjs/util": "^9.1.0", - "@ethersproject/abi": "^5.1.2", - "@nomicfoundation/edr": "0.12.0-next.23", - "@nomicfoundation/solidity-analyzer": "^0.1.0", - "@sentry/node": "^5.18.1", - "adm-zip": "^0.4.16", - "aggregate-error": "^3.0.0", - "ansi-escapes": "^4.3.0", - "boxen": "^5.1.2", - "chokidar": "^4.0.0", - "ci-info": "^2.0.0", - "debug": "^4.1.1", - "enquirer": "^2.3.0", - "env-paths": "^2.2.0", - "ethereum-cryptography": "^1.0.3", - "find-up": "^5.0.0", - "fp-ts": "1.19.3", - "fs-extra": "^7.0.1", - "immutable": "^4.0.0-rc.12", - "io-ts": "1.10.4", - "json-stream-stringify": "^3.1.4", - "keccak": "^3.0.2", - "lodash": "^4.17.11", - "micro-eth-signer": "^0.14.0", - "mnemonist": "^0.38.0", - "mocha": "^10.0.0", - "p-map": "^4.0.0", - "picocolors": "^1.1.0", - "raw-body": "^2.4.1", - "resolve": "1.17.0", - "semver": "^6.3.0", - "solc": "0.8.26", - "source-map-support": "^0.5.13", - "stacktrace-parser": "^0.1.10", - "tinyglobby": "^0.2.6", - "tsort": "0.0.1", - "undici": "^5.14.0", - "uuid": "^8.3.2", - "ws": "^7.4.6" - }, - "bin": { - "hardhat": "internal/cli/bootstrap.js" - }, - "peerDependencies": { - "ts-node": "*", - "typescript": "*" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } + "engines": { + "node": ">= 14.17" } }, - "node_modules/hardhat-exposed": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/hardhat-exposed/-/hardhat-exposed-0.3.19.tgz", - "integrity": "sha512-vVye5TurJu8dWeo4ma+EfLAOQaJyica4uncd0/BGPO2tmexuDwZUmE1vYx81PlP4Iak3wqkNTEPxWQaE2ZnKnw==", + "node_modules/fs-extra": { + "version": "7.0.1", "dev": true, "license": "MIT", "dependencies": { - "micromatch": "^4.0.8", - "solidity-ast": "^0.4.59" + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" }, - "peerDependencies": { - "hardhat": "^2.3.0" + "engines": { + "node": ">=6 <7 || >=8" } }, - "node_modules/hardhat-gas-reporter": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/hardhat-gas-reporter/-/hardhat-gas-reporter-2.3.0.tgz", - "integrity": "sha512-ySdA+044xMQv1BlJu5CYXToHzMexKFfIWxlQTBNNoerx1x96+d15IMdN01iQZ/TJ7NH2V5sU73bz77LoS/PEVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ethersproject/abi": "^5.7.0", - "@ethersproject/bytes": "^5.7.0", - "@ethersproject/units": "^5.7.0", - "@solidity-parser/parser": "^0.20.1", - "axios": "^1.6.7", - "brotli-wasm": "^2.0.1", - "chalk": "4.1.2", - "cli-table3": "^0.6.3", - "ethereum-cryptography": "^2.1.3", - "glob": "^10.3.10", - "jsonschema": "^1.4.1", - "lodash": "^4.17.21", - "markdown-table": "2.0.0", - "sha1": "^1.1.1", - "viem": "^2.27.0" - }, - "peerDependencies": { - "hardhat": "^2.16.0" - } + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" }, - "node_modules/hardhat-gas-reporter/node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "dev": true, + "hasInstallScript": true, "license": "MIT", - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/hardhat-gas-reporter/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "node_modules/function-bind": { + "version": "1.1.2", "dev": true, "license": "MIT", - "engines": { - "node": ">= 16" - }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hardhat-gas-reporter/node_modules/@scure/base": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", - "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", + "node_modules/get-caller-file": { + "version": "2.0.5", "dev": true, - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "node_modules/hardhat-gas-reporter/node_modules/@scure/bip32": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", - "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", "dev": true, "license": "MIT", - "dependencies": { - "@noble/curves": "~1.4.0", - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" + "engines": { + "node": ">=18" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hardhat-gas-reporter/node_modules/@scure/bip39": { + "node_modules/get-intrinsic": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", - "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hardhat-gas-reporter/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "node_modules/get-proto": { + "version": "1.0.1", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "node_modules/hardhat-gas-reporter/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/get-stream": { + "version": "6.0.1", "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hardhat-gas-reporter/node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "node_modules/get-tsconfig": { + "version": "4.13.6", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", + "integrity": "sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw==", "dev": true, "license": "MIT", "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" - } - }, - "node_modules/hardhat-gas-reporter/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "dev": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/hardhat-gas-reporter/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/hardhat-gas-reporter/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "resolve-pkg-maps": "^1.0.0" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, - "node_modules/hardhat-gas-reporter/node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "node_modules/glob": { + "version": "13.0.0", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" }, "engines": { - "node": ">=16 || 14 >=14.18" + "node": "20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/hardhat-ignore-warnings": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/hardhat-ignore-warnings/-/hardhat-ignore-warnings-0.2.12.tgz", - "integrity": "sha512-SaxCLKzYBMk3Rd1275TnanUmmxwgU+bu4Ekf2MKcqXxxt6xTGcPTtTaM+USrLgmejZHC4Itg/PaWITlOp4RL3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimatch": "^5.1.0", - "node-interval-tree": "^2.0.1", - "solidity-comments": "^0.0.2" - } - }, - "node_modules/hardhat-ignore-warnings/node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/hardhat-ignore-warnings/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "node_modules/glob-parent": { + "version": "5.1.2", "dev": true, "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "is-glob": "^4.0.1" }, "engines": { - "node": ">=10" + "node": ">= 6" } }, - "node_modules/hardhat-predeploy": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/hardhat-predeploy/-/hardhat-predeploy-0.4.1.tgz", - "integrity": "sha512-53Eoj5YECKNTkEezGByjKP5rVbYU0s1is8CtEbm0DPbqMgstNrPMQ0dfcDxA5Fu+hlZhc5w0T+RmJ/d/GAbB6g==", + "node_modules/globals": { + "version": "17.3.0", "dev": true, "license": "MIT", - "peerDependencies": { - "@nomicfoundation/hardhat-ethers": "^3.0.8", - "hardhat": "^2.26.0" - } - }, - "node_modules/hardhat/node_modules/@ethereumjs/rlp": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-5.0.2.tgz", - "integrity": "sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==", - "dev": true, - "license": "MPL-2.0", - "bin": { - "rlp": "bin/rlp.cjs" - }, "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hardhat/node_modules/@ethereumjs/util": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-9.1.0.tgz", - "integrity": "sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog==", + "node_modules/globby": { + "version": "11.1.0", "dev": true, - "license": "MPL-2.0", + "license": "MIT", "dependencies": { - "@ethereumjs/rlp": "^5.0.2", - "ethereum-cryptography": "^2.2.1" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" }, "engines": { - "node": ">=18" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/hardhat/node_modules/@ethereumjs/util/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "node_modules/gopd": { + "version": "1.2.0", "dev": true, "license": "MIT", "engines": { - "node": ">= 16" + "node": ">= 0.4" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hardhat/node_modules/@ethereumjs/util/node_modules/@scure/bip32": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", - "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", + "node_modules/got": { + "version": "12.6.1", "dev": true, "license": "MIT", "dependencies": { - "@noble/curves": "~1.4.0", - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.8", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "engines": { + "node": ">=14.16" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "node_modules/hardhat/node_modules/@ethereumjs/util/node_modules/@scure/bip39": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", - "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", + "node_modules/graceful-fs": { + "version": "4.2.11", "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } + "license": "ISC" }, - "node_modules/hardhat/node_modules/@ethereumjs/util/node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", + "node_modules/graphlib": { + "version": "2.1.8", "dev": true, "license": "MIT", "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" + "lodash": "^4.17.15" } }, - "node_modules/hardhat/node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", + "node_modules/hardhat": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-3.5.0.tgz", + "integrity": "sha512-JT5YMXluyCD6RePp1ySezgZD9zZelS0v/wtarkQHb44pGqWqvVz1E68aEKSsbdMDRjHSHvW7/ILNJ3N1wt/MqQ==", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "1.4.0" + "@nomicfoundation/edr": "0.12.0-next.33", + "@nomicfoundation/hardhat-errors": "^3.0.13", + "@nomicfoundation/hardhat-utils": "^4.1.2", + "@nomicfoundation/hardhat-vendored": "^3.0.4", + "@nomicfoundation/hardhat-zod-utils": "^3.0.5", + "@nomicfoundation/solidity-analyzer": "^0.1.1", + "@sentry/core": "^9.4.0", + "adm-zip": "^0.4.16", + "chokidar": "^4.0.3", + "enquirer": "^2.3.0", + "ethereum-cryptography": "^2.2.1", + "micro-eth-signer": "^0.14.0", + "p-map": "^7.0.2", + "resolve.exports": "^2.0.3", + "semver": "^7.6.3", + "tsx": "^4.19.3", + "ws": "^8.18.0", + "zod": "^3.23.8" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "bin": { + "hardhat": "dist/src/cli.js" } }, - "node_modules/hardhat/node_modules/@noble/curves/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", + "node_modules/hardhat-ignore-warnings": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/hardhat-ignore-warnings/-/hardhat-ignore-warnings-0.3.0.tgz", + "integrity": "sha512-zpFICQhlRgN8NNq8WkQ0D86BfjrbwJOt+Tih1Mft0iXiqqlZoOI0cwcmc0bSb4wQZV4jWjfCk9g8x71Isp7MNA==", "dev": true, "license": "MIT", - "engines": { - "node": ">= 16" + "dependencies": { + "minimatch": "^10.1.1", + "node-interval-tree": "^2.0.1", + "solidity-comments": "^0.0.2" }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/hardhat/node_modules/@noble/hashes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.2.0.tgz", - "integrity": "sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "license": "MIT" - }, - "node_modules/hardhat/node_modules/@scure/base": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", - "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" + "peerDependencies": { + "hardhat": "^3.1.0" } }, - "node_modules/hardhat/node_modules/@scure/bip32": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.1.5.tgz", - "integrity": "sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==", + "node_modules/hardhat-predeploy": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hardhat-predeploy/-/hardhat-predeploy-1.0.1.tgz", + "integrity": "sha512-PDrPNW5rfwgsYzycDIObzj38pAzbasV4yqI/vTwuxvIEyxsefffkMh1yl5nmBtkgq4eYxLwLT7dLEpoYPRSbug==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.2.0", - "@noble/secp256k1": "~1.7.0", - "@scure/base": "~1.1.0" + "peerDependencies": { + "hardhat": "^3.0.0" } }, - "node_modules/hardhat/node_modules/@scure/bip39": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.1.1.tgz", - "integrity": "sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==", + "node_modules/hardhat/node_modules/@noble/curves": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", + "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], "license": "MIT", "dependencies": { - "@noble/hashes": "~1.2.0", - "@scure/base": "~1.1.0" + "@noble/hashes": "1.4.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/hardhat/node_modules/chokidar": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", - "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "node_modules/hardhat/node_modules/@noble/hashes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", + "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", "dev": true, "license": "MIT", - "dependencies": { - "readdirp": "^4.0.1" - }, "engines": { - "node": ">= 14.16.0" + "node": ">= 16" }, "funding": { "url": "https://paulmillr.com/funding/" } }, - "node_modules/hardhat/node_modules/ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/hardhat/node_modules/ethereum-cryptography": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz", - "integrity": "sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==", + "node_modules/hardhat/node_modules/@scure/base": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", + "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", "dev": true, "license": "MIT", - "dependencies": { - "@noble/hashes": "1.2.0", - "@noble/secp256k1": "1.7.1", - "@scure/bip32": "1.1.5", - "@scure/bip39": "1.1.1" + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "node_modules/hardhat/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "node_modules/hardhat/node_modules/@scure/bip32": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", + "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" + "@noble/curves": "~1.4.0", + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/hardhat/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/hardhat/node_modules/@scure/bip39": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", + "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", "dev": true, "license": "MIT", "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" + "@noble/hashes": "~1.4.0", + "@scure/base": "~1.1.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/hardhat/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/hardhat/node_modules/chokidar": { + "version": "4.0.3", "dev": true, "license": "MIT", "dependencies": { - "yocto-queue": "^0.1.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">=10" + "node": ">= 14.16.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://paulmillr.com/funding/" } }, - "node_modules/hardhat/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "node_modules/hardhat/node_modules/ethereum-cryptography": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", + "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", "dev": true, "license": "MIT", "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "@noble/curves": "1.4.2", + "@noble/hashes": "1.4.0", + "@scure/bip32": "1.4.0", + "@scure/bip39": "1.3.0" } }, "node_modules/hardhat/node_modules/readdirp": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", - "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, "license": "MIT", "engines": { @@ -6166,51 +4616,18 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/hardhat/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/hardhat/node_modules/undici": { - "version": "5.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.29.0.tgz", - "integrity": "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@fastify/busboy": "^2.0.0" - }, - "engines": { - "node": ">=14.0" - } - }, - "node_modules/hardhat/node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, "node_modules/hardhat/node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "dev": true, "license": "MIT", "engines": { - "node": ">=8.3.0" + "node": ">=10.0.0" }, "peerDependencies": { "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "utf-8-validate": ">=5.0.2" }, "peerDependenciesMeta": { "bufferutil": { @@ -6221,23 +4638,8 @@ } } }, - "node_modules/hardhat/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/has-flag": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, "license": "MIT", "engines": { @@ -6246,8 +4648,6 @@ }, "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dev": true, "license": "MIT", "dependencies": { @@ -6259,8 +4659,6 @@ }, "node_modules/has-symbols": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", "dev": true, "license": "MIT", "engines": { @@ -6272,8 +4670,6 @@ }, "node_modules/has-tostringtag": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "dev": true, "license": "MIT", "dependencies": { @@ -6288,8 +4684,6 @@ }, "node_modules/hash-base": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", - "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", "dev": true, "license": "MIT", "dependencies": { @@ -6304,15 +4698,11 @@ }, "node_modules/hash-base/node_modules/isarray": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true, "license": "MIT" }, "node_modules/hash-base/node_modules/readable-stream": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", "dev": true, "license": "MIT", "dependencies": { @@ -6327,15 +4717,11 @@ }, "node_modules/hash-base/node_modules/readable-stream/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "license": "MIT" }, "node_modules/hash-base/node_modules/string_decoder": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "license": "MIT", "dependencies": { @@ -6344,15 +4730,11 @@ }, "node_modules/hash-base/node_modules/string_decoder/node_modules/safe-buffer": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true, "license": "MIT" }, "node_modules/hash.js": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", "dev": true, "license": "MIT", "dependencies": { @@ -6362,8 +4744,6 @@ }, "node_modules/hasown": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6375,25 +4755,15 @@ }, "node_modules/he": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, "license": "MIT", + "peer": true, "bin": { "he": "bin/he" } }, - "node_modules/heap": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz", - "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==", - "dev": true, - "license": "MIT" - }, "node_modules/hmac-drbg": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, "license": "MIT", "dependencies": { @@ -6404,36 +4774,11 @@ }, "node_modules/http-cache-semantics": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", "dev": true, "license": "BSD-2-Clause" }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/http2-wrapper": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.1.tgz", - "integrity": "sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6444,24 +4789,8 @@ "node": ">=10.19.0" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/human-id": { "version": "4.1.3", - "resolved": "https://registry.npmjs.org/human-id/-/human-id-4.1.3.tgz", - "integrity": "sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q==", "dev": true, "license": "MIT", "bin": { @@ -6470,8 +4799,6 @@ }, "node_modules/husky": { "version": "9.1.7", - "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz", - "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==", "dev": true, "license": "MIT", "bin": { @@ -6486,8 +4813,6 @@ }, "node_modules/iconv-lite": { "version": "0.7.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", - "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, "license": "MIT", "dependencies": { @@ -6503,25 +4828,14 @@ }, "node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { "node": ">= 4" } }, - "node_modules/immutable": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.8.tgz", - "integrity": "sha512-d/Ld9aLbKpNwyl0KiM2CT1WYvkitQ1TSvmRtkcV8FKStiDoA7Slzgjmb/1G2yhKM1p0XeNOieaTbFZmU1d3Xuw==", - "dev": true, - "license": "MIT" - }, "node_modules/import-fresh": { "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6537,8 +4851,6 @@ }, "node_modules/import-fresh/node_modules/resolve-from": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true, "license": "MIT", "engines": { @@ -6547,29 +4859,14 @@ }, "node_modules/imurmurhash": { "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.8.19" } }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/inflight": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", "dev": true, "license": "ISC", "dependencies": { @@ -6579,22 +4876,16 @@ }, "node_modules/inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true, "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true, "license": "ISC" }, "node_modules/interoperable-addresses": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/interoperable-addresses/-/interoperable-addresses-0.1.3.tgz", - "integrity": "sha512-0URwTYBZzjg+BsjEssrvxQPB2XHYVIXLcMjUR0Bd4IoINQHgmR5nbHAOSsCAAR32FsrN1VLZNaqPl8ijQzIMVQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6603,37 +4894,13 @@ "typed-regex": "^0.0.8" } }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/io-ts": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/io-ts/-/io-ts-1.10.4.tgz", - "integrity": "sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fp-ts": "^1.0.0" - } - }, "node_modules/is-arrayish": { "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true, "license": "MIT" }, "node_modules/is-binary-path": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "license": "MIT", "dependencies": { @@ -6645,8 +4912,6 @@ }, "node_modules/is-callable": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", "dev": true, "license": "MIT", "engines": { @@ -6658,8 +4923,6 @@ }, "node_modules/is-extglob": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "license": "MIT", "engines": { @@ -6684,8 +4947,6 @@ }, "node_modules/is-glob": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", "dev": true, "license": "MIT", "dependencies": { @@ -6695,41 +4956,36 @@ "node": ">=0.10.0" } }, - "node_modules/is-hex-prefixed": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==", + "node_modules/is-number": { + "version": "7.0.0", "dev": true, "license": "MIT", "engines": { - "node": ">=6.5.0", - "npm": ">=3" + "node": ">=0.12.0" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", "dev": true, "license": "MIT", + "peer": true, "engines": { - "node": ">=0.12.0" + "node": ">=8" } }, "node_modules/is-plain-obj": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } }, "node_modules/is-port-reachable": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-3.1.0.tgz", - "integrity": "sha512-vjc0SSRNZ32s9SbZBzGaiP6YVB+xglLShhgZD/FHMZUXBvQWaV9CtzgeVhjccFJrI6RAMV+LX7NYxueW/A8W5A==", "dev": true, "license": "MIT", "engines": { @@ -6738,8 +4994,6 @@ }, "node_modules/is-subdir": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-subdir/-/is-subdir-1.2.0.tgz", - "integrity": "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==", "dev": true, "license": "MIT", "dependencies": { @@ -6751,8 +5005,6 @@ }, "node_modules/is-typed-array": { "version": "1.1.15", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", - "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", "dev": true, "license": "MIT", "dependencies": { @@ -6767,10 +5019,9 @@ }, "node_modules/is-unicode-supported": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -6780,8 +5031,6 @@ }, "node_modules/is-windows": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true, "license": "MIT", "engines": { @@ -6790,40 +5039,19 @@ }, "node_modules/isarray": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", "dev": true, "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true, "license": "ISC" }, - "node_modules/isows": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/isows/-/isows-1.0.7.tgz", - "integrity": "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "peerDependencies": { - "ws": "*" - } - }, "node_modules/jackspeak": { "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", "dev": true, "license": "BlueOak-1.0.0", + "peer": true, "dependencies": { "@isaacs/cliui": "^8.0.2" }, @@ -6834,24 +5062,13 @@ "@pkgjs/parseargs": "^0.11.0" } }, - "node_modules/js-sha3": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true, - "license": "MIT" - }, "node_modules/js-tokens": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -6863,29 +5080,21 @@ }, "node_modules/json-buffer": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "dev": true, "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true, "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true, "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true, "license": "MIT" }, @@ -6901,8 +5110,6 @@ }, "node_modules/jsonfile": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", "dev": true, "license": "MIT", "optionalDependencies": { @@ -6911,28 +5118,14 @@ }, "node_modules/jsonpointer": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/jsonschema": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.5.0.tgz", - "integrity": "sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/keccak": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.4.tgz", - "integrity": "sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -6947,28 +5140,14 @@ }, "node_modules/keyv": { "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", "dev": true, "license": "MIT", "dependencies": { "json-buffer": "3.0.1" } }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/latest-version": { "version": "7.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-7.0.0.tgz", - "integrity": "sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==", "dev": true, "license": "MIT", "dependencies": { @@ -6983,8 +5162,6 @@ }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, "license": "MIT", "engines": { @@ -6993,8 +5170,6 @@ }, "node_modules/levn": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "dev": true, "license": "MIT", "dependencies": { @@ -7007,15 +5182,13 @@ }, "node_modules/lines-and-columns": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true, "license": "MIT" }, "node_modules/lint-staged": { - "version": "17.0.4", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.0.4.tgz", - "integrity": "sha512-+rU9lSUyVOZ/hDUmRLVGzyS2v73cDdQjX+XQz1AaOdIE4RysLq0HoPW2HrrgeNCLklkhi904VBU1bmgWLHVnkA==", + "version": "17.0.5", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-17.0.5.tgz", + "integrity": "sha512-d12yC+/e8RhBjZtaxZn71FyrgU/P5e+uAPifhCLwdosQZP/zamSdKRWDC30ocVIbzDKiFG1McHc/LUgB92GIPw==", "dev": true, "license": "MIT", "dependencies": { @@ -7146,8 +5319,6 @@ }, "node_modules/locate-path": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "license": "MIT", "dependencies": { @@ -7158,47 +5329,32 @@ } }, "node_modules/lodash": { - "version": "4.18.1", + "version": "4.17.23", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "dev": true, "license": "MIT" }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "deprecated": "This package is deprecated. Use require('node:util').isDeepStrictEqual instead.", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true, "license": "MIT" }, "node_modules/lodash.startcase": { "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", - "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==", "dev": true, "license": "MIT" }, "node_modules/lodash.truncate": { "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true, "license": "MIT" }, "node_modules/log-symbols": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" @@ -7212,10 +5368,9 @@ }, "node_modules/log-symbols/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -7247,22 +5402,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/log-update/node_modules/ansi-escapes": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", - "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "environment": "^1.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/log-update/node_modules/ansi-regex": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", @@ -7283,19 +5422,36 @@ "dev": true, "license": "MIT", "engines": { - "node": ">=12" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/log-update/node_modules/emoji-regex": { - "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", - "dev": true, - "license": "MIT" - }, "node_modules/log-update/node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", @@ -7315,13 +5471,13 @@ } }, "node_modules/log-update/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" + "ansi-regex": "^6.2.2" }, "engines": { "node": ">=12" @@ -7349,19 +5505,14 @@ } }, "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "dev": true, - "license": "MIT", - "dependencies": { - "get-func-name": "^2.0.1" - } + "license": "MIT" }, "node_modules/lowercase-keys": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", - "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true, "license": "MIT", "engines": { @@ -7371,41 +5522,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lru-cache": { "version": "11.0.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz", - "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==", "dev": true, "license": "ISC", "engines": { "node": "20 || >=22" } }, - "node_modules/markdown-table": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", - "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", - "dev": true, - "license": "MIT", - "dependencies": { - "repeat-string": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, "license": "MIT", "engines": { @@ -7414,8 +5540,6 @@ }, "node_modules/md5.js": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "dev": true, "license": "MIT", "dependencies": { @@ -7424,19 +5548,8 @@ "safe-buffer": "^5.1.2" } }, - "node_modules/memorystream": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", - "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", - "dev": true, - "engines": { - "node": ">= 0.10.0" - } - }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true, "license": "MIT", "engines": { @@ -7445,8 +5558,6 @@ }, "node_modules/micro-eth-signer": { "version": "0.14.0", - "resolved": "https://registry.npmjs.org/micro-eth-signer/-/micro-eth-signer-0.14.0.tgz", - "integrity": "sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==", "dev": true, "license": "MIT", "dependencies": { @@ -7457,8 +5568,6 @@ }, "node_modules/micro-eth-signer/node_modules/@noble/curves": { "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", - "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", "dev": true, "license": "MIT", "dependencies": { @@ -7473,8 +5582,6 @@ }, "node_modules/micro-eth-signer/node_modules/@noble/hashes": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", "dev": true, "license": "MIT", "engines": { @@ -7486,15 +5593,11 @@ }, "node_modules/micro-ftch": { "version": "0.3.1", - "resolved": "https://registry.npmjs.org/micro-ftch/-/micro-ftch-0.3.1.tgz", - "integrity": "sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==", "dev": true, "license": "MIT" }, "node_modules/micro-packed": { "version": "0.7.3", - "resolved": "https://registry.npmjs.org/micro-packed/-/micro-packed-0.7.3.tgz", - "integrity": "sha512-2Milxs+WNC00TRlem41oRswvw31146GiSaoCT7s3Xi2gMUglW5QBeqlQaZeHr5tJx9nm3i57LNXPqxOOaWtTYg==", "dev": true, "license": "MIT", "dependencies": { @@ -7506,8 +5609,6 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "license": "MIT", "dependencies": { @@ -7518,29 +5619,6 @@ "node": ">=8.6" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/mimic-function": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", @@ -7556,8 +5634,6 @@ }, "node_modules/mimic-response": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", - "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "dev": true, "license": "MIT", "engines": { @@ -7569,22 +5645,16 @@ }, "node_modules/minimalistic-assert": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", "dev": true, "license": "ISC" }, "node_modules/minimalistic-crypto-utils": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", "dev": true, "license": "MIT" }, "node_modules/minimatch": { "version": "10.2.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz", - "integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -7599,8 +5669,6 @@ }, "node_modules/minimatch/node_modules/balanced-match": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "dev": true, "license": "MIT", "engines": { @@ -7609,8 +5677,6 @@ }, "node_modules/minimatch/node_modules/brace-expansion": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz", - "integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==", "dev": true, "license": "MIT", "dependencies": { @@ -7622,8 +5688,6 @@ }, "node_modules/minimist": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", "dev": true, "license": "MIT", "funding": { @@ -7632,63 +5696,40 @@ }, "node_modules/minipass": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, "license": "ISC", "engines": { "node": ">=16 || 14 >=14.17" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mnemonist": { - "version": "0.38.5", - "resolved": "https://registry.npmjs.org/mnemonist/-/mnemonist-0.38.5.tgz", - "integrity": "sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "obliterator": "^2.0.0" - } - }, "node_modules/mocha": { - "version": "10.8.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.8.2.tgz", - "integrity": "sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==", + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "ansi-colors": "^4.1.3", "browser-stdout": "^1.3.1", - "chokidar": "^3.5.3", + "chokidar": "^4.0.1", "debug": "^4.3.5", - "diff": "^5.2.0", + "diff": "^7.0.0", "escape-string-regexp": "^4.0.0", "find-up": "^5.0.0", - "glob": "^8.1.0", + "glob": "^10.4.5", "he": "^1.2.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "log-symbols": "^4.1.0", - "minimatch": "^5.1.6", + "minimatch": "^9.0.5", "ms": "^2.1.3", + "picocolors": "^1.1.1", "serialize-javascript": "^6.0.2", "strip-json-comments": "^3.1.1", "supports-color": "^8.1.1", - "workerpool": "^6.5.1", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", "yargs-unparser": "^2.0.0" }, "bin": { @@ -7696,7 +5737,7 @@ "mocha": "bin/mocha.js" }, "engines": { - "node": ">= 14.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/mocha/node_modules/brace-expansion": { @@ -7705,28 +5746,49 @@ "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "balanced-match": "^1.0.0" } }, + "node_modules/mocha/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/mocha/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/mocha/node_modules/find-up": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -7739,21 +5801,23 @@ } }, "node_modules/mocha/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "dev": true, "license": "ISC", + "peer": true, "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": ">=12" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -7761,10 +5825,9 @@ }, "node_modules/mocha/node_modules/locate-path": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -7775,25 +5838,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mocha/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC", + "peer": true + }, "node_modules/mocha/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "dev": true, "license": "ISC", + "peer": true, "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^2.0.2" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/mocha/node_modules/p-limit": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7806,10 +5880,9 @@ }, "node_modules/mocha/node_modules/p-locate": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -7820,12 +5893,44 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/mocha/node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "peer": true, + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/mocha/node_modules/supports-color": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -7837,30 +5942,30 @@ } }, "node_modules/mocha/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/mocha/node_modules/yocto-queue": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -7870,8 +5975,6 @@ }, "node_modules/mri": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true, "license": "MIT", "engines": { @@ -7880,46 +5983,21 @@ }, "node_modules/ms": { "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true, "license": "MIT" }, "node_modules/natural-compare": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true, "license": "MIT" }, "node_modules/node-addon-api": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", "dev": true, "license": "MIT" }, - "node_modules/node-emoji": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz", - "integrity": "sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.21" - } - }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dev": true, "license": "MIT", "dependencies": { @@ -7939,8 +6017,6 @@ }, "node_modules/node-gyp-build": { "version": "4.8.4", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", - "integrity": "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==", "dev": true, "license": "MIT", "bin": { @@ -7951,8 +6027,6 @@ }, "node_modules/node-interval-tree": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/node-interval-tree/-/node-interval-tree-2.1.2.tgz", - "integrity": "sha512-bJ9zMDuNGzVQg1xv0bCPzyEDxHgbrx7/xGj6CDokvizZZmastPsOh0JJLuY8wA5q2SfX1TLNMk7XNV8WxbGxzA==", "dev": true, "license": "MIT", "dependencies": { @@ -7964,31 +6038,14 @@ }, "node_modules/nofilter": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nofilter/-/nofilter-3.1.0.tgz", - "integrity": "sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==", "dev": true, "license": "MIT", "engines": { "node": ">=12.19" } }, - "node_modules/nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - } - }, "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true, "license": "MIT", "engines": { @@ -7997,8 +6054,6 @@ }, "node_modules/normalize-url": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.1.1.tgz", - "integrity": "sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==", "dev": true, "license": "MIT", "engines": { @@ -8008,181 +6063,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/number-to-bn": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", - "integrity": "sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==", - "dev": true, - "license": "MIT", - "dependencies": { - "bn.js": "4.11.6", - "strip-hex-prefix": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, - "node_modules/number-to-bn/node_modules/bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==", - "dev": true, - "license": "MIT" - }, - "node_modules/obliterator": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/obliterator/-/obliterator-2.0.5.tgz", - "integrity": "sha512-42CPE9AhahZRsMNslczq0ctAEtqk8Eka26QofnqC346BZdHDySk3LWka23LI7ULIw11NmltpiLagIq8gBozxTw==", - "dev": true, - "license": "MIT" - }, "node_modules/once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", - "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-function": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ordinal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/ordinal/-/ordinal-1.0.3.tgz", - "integrity": "sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/outdent": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/outdent/-/outdent-0.5.0.tgz", - "integrity": "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/ox": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/ox/-/ox-0.11.3.tgz", - "integrity": "sha512-1bWYGk/xZel3xro3l8WGg6eq4YEKlaqvyMtVhfMFpbJzK2F6rj4EDRtqDCWVEJMkzcmEi9uW2QxsqELokOlarw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@adraffy/ens-normalize": "^1.11.0", - "@noble/ciphers": "^1.3.0", - "@noble/curves": "1.9.1", - "@noble/hashes": "^1.8.0", - "@scure/bip32": "^1.7.0", - "@scure/bip39": "^1.6.0", - "abitype": "^1.2.3", - "eventemitter3": "5.0.1" - }, - "peerDependencies": { - "typescript": ">=5.4.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/ox/node_modules/@adraffy/ens-normalize": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.11.1.tgz", - "integrity": "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==", - "dev": true, - "license": "MIT" + } }, - "node_modules/ox/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, "license": "MIT", "dependencies": { - "@noble/hashes": "1.8.0" + "mimic-function": "^5.0.0" }, "engines": { - "node": "^14.21.3 || >=16" + "node": ">=18" }, "funding": { - "url": "https://paulmillr.com/funding/" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ox/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "node_modules/optionator": { + "version": "0.9.4", "dev": true, "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" }, - "funding": { - "url": "https://paulmillr.com/funding/" + "engines": { + "node": ">= 0.8.0" } }, - "node_modules/ox/node_modules/eventemitter3": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", - "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "node_modules/outdent": { + "version": "0.5.0", "dev": true, "license": "MIT" }, "node_modules/p-cancelable": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", - "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true, "license": "MIT", "engines": { @@ -8191,8 +6118,6 @@ }, "node_modules/p-filter": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", - "integrity": "sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==", "dev": true, "license": "MIT", "dependencies": { @@ -8204,8 +6129,6 @@ }, "node_modules/p-filter/node_modules/p-map": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", - "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", "dev": true, "license": "MIT", "engines": { @@ -8214,8 +6137,6 @@ }, "node_modules/p-limit": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.2.0.tgz", - "integrity": "sha512-ATHLtwoTNDloHRFFxFJdHnG6n2WUeFjaR8XQMFdKIv0xkXjrER8/iG9iu265jOM95zXHAfv9oTkqhrfbIzosrQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8230,8 +6151,6 @@ }, "node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "license": "MIT", "dependencies": { @@ -8243,8 +6162,6 @@ }, "node_modules/p-locate/node_modules/p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "license": "MIT", "dependencies": { @@ -8258,16 +6175,13 @@ } }, "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", "dev": true, "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8275,8 +6189,6 @@ }, "node_modules/p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true, "license": "MIT", "engines": { @@ -8285,8 +6197,6 @@ }, "node_modules/package-json": { "version": "8.1.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-8.1.1.tgz", - "integrity": "sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==", "dev": true, "license": "MIT", "dependencies": { @@ -8304,15 +6214,11 @@ }, "node_modules/package-json-from-dist": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "dev": true, "license": "BlueOak-1.0.0" }, "node_modules/package-manager-detector": { "version": "0.2.11", - "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz", - "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8321,8 +6227,6 @@ }, "node_modules/parent-module": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "license": "MIT", "dependencies": { @@ -8334,8 +6238,6 @@ }, "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "license": "MIT", "dependencies": { @@ -8353,45 +6255,22 @@ }, "node_modules/path-exists": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, "node_modules/path-scurry": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", - "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -8407,8 +6286,6 @@ }, "node_modules/path-type": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true, "license": "MIT", "engines": { @@ -8416,19 +6293,17 @@ } }, "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", "dev": true, "license": "MIT", "engines": { - "node": "*" + "node": ">= 14.16" } }, "node_modules/pbkdf2": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz", - "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8445,15 +6320,11 @@ }, "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "dev": true, "license": "ISC" }, "node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "version": "2.3.1", "dev": true, "license": "MIT", "engines": { @@ -8465,8 +6336,6 @@ }, "node_modules/pify": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, "license": "MIT", "engines": { @@ -8475,8 +6344,6 @@ }, "node_modules/pluralize": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", - "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "dev": true, "license": "MIT", "engines": { @@ -8485,8 +6352,6 @@ }, "node_modules/pony-cause": { "version": "2.1.11", - "resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-2.1.11.tgz", - "integrity": "sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==", "dev": true, "license": "0BSD", "engines": { @@ -8495,8 +6360,6 @@ }, "node_modules/possible-typed-array-names": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", - "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { @@ -8505,8 +6368,6 @@ }, "node_modules/prelude-ls": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true, "license": "MIT", "engines": { @@ -8515,8 +6376,6 @@ }, "node_modules/prettier": { "version": "3.8.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", - "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", "dev": true, "license": "MIT", "bin": { @@ -8531,8 +6390,6 @@ }, "node_modules/prettier-plugin-solidity": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-2.2.1.tgz", - "integrity": "sha512-LOHfxECJ/gHsY7qi4D7vanz8cVsCf6yFotBapJ5O0qaX0ZR1sGUzbWfMd4JeQYOItFl+wXW9IcjZOdfr6bmSvQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8549,15 +6406,11 @@ }, "node_modules/prettier-plugin-solidity/node_modules/@bytecodealliance/preview2-shim": { "version": "0.17.7", - "resolved": "https://registry.npmjs.org/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.7.tgz", - "integrity": "sha512-VFUQHwSScO+zO466DlsmNlNeCf6sUsHBazvisb3hmGCbiPxwAMn1rGmnwinM+6zcLJw0CqkV0h2JzL3MdudhJQ==", "dev": true, "license": "(Apache-2.0 WITH LLVM-exception)" }, "node_modules/prettier-plugin-solidity/node_modules/@nomicfoundation/slang": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@nomicfoundation/slang/-/slang-1.3.1.tgz", - "integrity": "sha512-gh0+JDjazmevEYCcwVgtuyfBJcV1209gIORZNRjUxbGzbQN0MOhQO9T0ptkzHKCf854gUy27SMxPbAyAu63fvQ==", "dev": true, "license": "MIT", "dependencies": { @@ -8566,15 +6419,11 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true, "license": "MIT" }, "node_modules/proper-lockfile": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", "dev": true, "license": "MIT", "dependencies": { @@ -8585,25 +6434,11 @@ }, "node_modules/proto-list": { "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", "dev": true, "license": "ISC" }, - "node_modules/proxy-from-env": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", - "integrity": "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/punycode": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", "dev": true, "license": "MIT", "engines": { @@ -8612,8 +6447,6 @@ }, "node_modules/quansync": { "version": "0.2.11", - "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz", - "integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==", "dev": true, "funding": [ { @@ -8629,8 +6462,6 @@ }, "node_modules/queue-microtask": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true, "funding": [ { @@ -8650,8 +6481,6 @@ }, "node_modules/quick-lru": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", "dev": true, "license": "MIT", "engines": { @@ -8663,47 +6492,14 @@ }, "node_modules/randombytes": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "^5.1.0" } }, - "node_modules/raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/rc": { "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", "dev": true, "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", "dependencies": { @@ -8718,8 +6514,6 @@ }, "node_modules/rc/node_modules/strip-json-comments": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true, "license": "MIT", "engines": { @@ -8728,8 +6522,6 @@ }, "node_modules/read-yaml-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-yaml-file/-/read-yaml-file-1.1.0.tgz", - "integrity": "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==", "dev": true, "license": "MIT", "dependencies": { @@ -8744,8 +6536,6 @@ }, "node_modules/read-yaml-file/node_modules/argparse": { "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "license": "MIT", "dependencies": { @@ -8754,8 +6544,6 @@ }, "node_modules/read-yaml-file/node_modules/esprima": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true, "license": "BSD-2-Clause", "bin": { @@ -8768,8 +6556,6 @@ }, "node_modules/read-yaml-file/node_modules/js-yaml": { "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -8782,8 +6568,6 @@ }, "node_modules/readable-stream": { "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dev": true, "license": "MIT", "dependencies": { @@ -8797,8 +6581,6 @@ }, "node_modules/readdirp": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", "dev": true, "license": "MIT", "dependencies": { @@ -8808,48 +6590,8 @@ "node": ">=8.10.0" } }, - "node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/recursive-readdir": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.3.tgz", - "integrity": "sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/recursive-readdir/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/registry-auth-token": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.1.tgz", - "integrity": "sha512-P7B4+jq8DeD2nMsAcdfaqHbssgHtZ7Z5+++a5ask90fvmJ8p5je4mOa+wzu+DB4vQ5tdJV/xywY+UnVFeQLV5Q==", "dev": true, "license": "MIT", "dependencies": { @@ -8861,8 +6603,6 @@ }, "node_modules/registry-url": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz", - "integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -8875,70 +6615,60 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } }, "node_modules/require-from-string": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/resolve-alpn": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "dev": true, "license": "MIT" }, "node_modules/resolve-from": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, "license": "MIT", "engines": { "node": ">=8" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/responselike": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", - "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dev": true, "license": "MIT", "dependencies": { @@ -8983,8 +6713,6 @@ }, "node_modules/retry": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, "license": "MIT", "engines": { @@ -8993,8 +6721,6 @@ }, "node_modules/reusify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", "dev": true, "license": "MIT", "engines": { @@ -9004,15 +6730,11 @@ }, "node_modules/rfdc": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", "dev": true, "license": "MIT" }, "node_modules/rimraf": { "version": "6.1.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.2.tgz", - "integrity": "sha512-cFCkPslJv7BAXJsYlK1dZsbP8/ZNLkCAQ0bi1hf5EKX2QHegmDFEFA6QhuYJlk7UDdc+02JjO80YSOrWPpw06g==", "dev": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -9031,8 +6753,6 @@ }, "node_modules/ripemd160": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", - "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", "dev": true, "license": "MIT", "dependencies": { @@ -9045,8 +6765,6 @@ }, "node_modules/rlp": { "version": "2.2.7", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.7.tgz", - "integrity": "sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==", "dev": true, "license": "MPL-2.0", "dependencies": { @@ -9058,8 +6776,6 @@ }, "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", "dev": true, "funding": [ { @@ -9082,8 +6798,6 @@ }, "node_modules/safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true, "funding": [ { @@ -9103,160 +6817,16 @@ }, "node_modules/safer-buffer": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/sc-istanbul": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.6.tgz", - "integrity": "sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "abbrev": "1.0.x", - "async": "1.x", - "escodegen": "1.8.x", - "esprima": "2.7.x", - "glob": "^5.0.15", - "handlebars": "^4.0.1", - "js-yaml": "3.x", - "mkdirp": "0.5.x", - "nopt": "3.x", - "once": "1.x", - "resolve": "1.1.x", - "supports-color": "^3.1.0", - "which": "^1.1.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "istanbul": "lib/cli.js" - } - }, - "node_modules/sc-istanbul/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/sc-istanbul/node_modules/glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sc-istanbul/node_modules/has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sc-istanbul/node_modules/js-yaml": { - "version": "3.14.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", - "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/sc-istanbul/node_modules/js-yaml/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/sc-istanbul/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/sc-istanbul/node_modules/resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==", "dev": true, "license": "MIT" }, - "node_modules/sc-istanbul/node_modules/supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/sc-istanbul/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, "node_modules/scrypt-js": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", "dev": true, "license": "MIT" }, "node_modules/secp256k1": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.4.tgz", - "integrity": "sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -9271,15 +6841,11 @@ }, "node_modules/secp256k1/node_modules/node-addon-api": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz", - "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", "dev": true, "license": "MIT" }, "node_modules/semver": { "version": "7.7.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", - "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -9291,18 +6857,15 @@ }, "node_modules/serialize-javascript": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "license": "BSD-3-Clause", + "peer": true, "dependencies": { "randombytes": "^2.1.0" } }, "node_modules/set-function-length": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dev": true, "license": "MIT", "dependencies": { @@ -9319,22 +6882,11 @@ }, "node_modules/setimmediate": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", "dev": true, "license": "MIT" }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, - "license": "ISC" - }, "node_modules/sha.js": { "version": "2.4.12", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", - "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", "dev": true, "license": "(MIT AND BSD-3-Clause)", "dependencies": { @@ -9352,31 +6904,13 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/sha1": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/sha1/-/sha1-1.1.1.tgz", - "integrity": "sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "charenc": ">= 0.0.1", - "crypt": ">= 0.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/shallowequal": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", "dev": true, "license": "MIT" }, "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, "license": "MIT", "dependencies": { @@ -9387,79 +6921,20 @@ } }, "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/shelljs/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/shelljs/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.0.0", "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", "engines": { - "node": "*" + "node": ">=8" } }, "node_modules/signal-exit": { "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "dev": true, "license": "ISC" }, "node_modules/slash": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "license": "MIT", "engines": { @@ -9467,17 +6942,17 @@ } }, "node_modules/slice-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", - "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz", + "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==", "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^6.2.1", - "is-fullwidth-code-point": "^5.0.0" + "ansi-styles": "^6.2.3", + "is-fullwidth-code-point": "^5.1.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/chalk/slice-ansi?sponsor=1" @@ -9496,52 +6971,8 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/solc": { - "version": "0.8.26", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.26.tgz", - "integrity": "sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "command-exists": "^1.2.8", - "commander": "^8.1.0", - "follow-redirects": "^1.12.1", - "js-sha3": "0.8.0", - "memorystream": "^0.3.1", - "semver": "^5.5.0", - "tmp": "0.0.33" - }, - "bin": { - "solcjs": "solc.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/solc/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/solc/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, "node_modules/solhint": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/solhint/-/solhint-6.0.3.tgz", - "integrity": "sha512-LYiy1bN8X9eUsti13mbS4fY6ILVxhP6VoOgqbHxCsHl5VPnxOWf7U1V9ZvgizxdInKBMW82D1FNJO+daAcWHbA==", "dev": true, "license": "MIT", "dependencies": { @@ -9577,8 +7008,6 @@ }, "node_modules/solhint/node_modules/ajv": { "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "license": "MIT", "dependencies": { @@ -9594,8 +7023,6 @@ }, "node_modules/solhint/node_modules/brace-expansion": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -9604,8 +7031,6 @@ }, "node_modules/solhint/node_modules/chalk": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "license": "MIT", "dependencies": { @@ -9621,8 +7046,6 @@ }, "node_modules/solhint/node_modules/commander": { "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", "dev": true, "license": "MIT", "engines": { @@ -9631,9 +7054,6 @@ }, "node_modules/solhint/node_modules/glob": { "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", "dev": true, "license": "ISC", "dependencies": { @@ -9652,15 +7072,11 @@ }, "node_modules/solhint/node_modules/json-schema-traverse": { "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true, "license": "MIT" }, "node_modules/solhint/node_modules/minimatch": { "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", "dev": true, "license": "ISC", "dependencies": { @@ -9672,8 +7088,6 @@ }, "node_modules/solhint/node_modules/prettier": { "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "license": "MIT", "optional": true, @@ -9689,15 +7103,11 @@ }, "node_modules/solidity-ast": { "version": "0.4.61", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.61.tgz", - "integrity": "sha512-OYBJYcYyG7gLV0VuXl9CUrvgJXjV/v0XnR4+1YomVe3q+QyENQXJJxAEASUz4vN6lMAl+C8RSRSr5MBAz09f6w==", "dev": true, "license": "MIT" }, "node_modules/solidity-comments": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments/-/solidity-comments-0.0.2.tgz", - "integrity": "sha512-G+aK6qtyUfkn1guS8uzqUeua1dURwPlcOjoTYW/TwmXAcE7z/1+oGCfZUdMSe4ZMKklNbVZNiG5ibnF8gkkFfw==", "dev": true, "license": "MIT", "engines": { @@ -9803,8 +7213,6 @@ }, "node_modules/solidity-comments-linux-x64-gnu": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-x64-gnu/-/solidity-comments-linux-x64-gnu-0.0.2.tgz", - "integrity": "sha512-zIqLehBK/g7tvrFmQljrfZXfkEeLt2v6wbe+uFu6kH/qAHZa7ybt8Vc0wYcmjo2U0PeBm15d79ee3AkwbIjFdQ==", "cpu": [ "x64" ], @@ -9820,8 +7228,6 @@ }, "node_modules/solidity-comments-linux-x64-musl": { "version": "0.0.2", - "resolved": "https://registry.npmjs.org/solidity-comments-linux-x64-musl/-/solidity-comments-linux-x64-musl-0.0.2.tgz", - "integrity": "sha512-R9FeDloVlFGTaVkOlELDVC7+1Tjx5WBPI5L8r0AGOPHK3+jOcRh6sKYpI+VskSPDc3vOO46INkpDgUXrKydlIw==", "cpu": [ "x64" ], @@ -9886,240 +7292,8 @@ "node": ">= 10" } }, - "node_modules/solidity-coverage": { - "version": "0.8.17", - "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.8.17.tgz", - "integrity": "sha512-5P8vnB6qVX9tt1MfuONtCTEaEGO/O4WuEidPHIAJjx4sktHHKhO3rFvnE0q8L30nWJPTrcqGQMT7jpE29B2qow==", - "dev": true, - "license": "ISC", - "dependencies": { - "@ethersproject/abi": "^5.0.9", - "@solidity-parser/parser": "^0.20.1", - "chalk": "^2.4.2", - "death": "^1.1.0", - "difflib": "^0.2.4", - "fs-extra": "^8.1.0", - "ghost-testrpc": "^0.0.2", - "global-modules": "^2.0.0", - "globby": "^10.0.1", - "jsonschema": "^1.2.4", - "lodash": "^4.17.21", - "mocha": "^10.2.0", - "node-emoji": "^1.10.0", - "pify": "^4.0.1", - "recursive-readdir": "^2.2.2", - "sc-istanbul": "^0.4.5", - "semver": "^7.3.4", - "shelljs": "^0.8.3", - "web3-utils": "^1.3.6" - }, - "bin": { - "solidity-coverage": "plugins/bin.js" - }, - "peerDependencies": { - "hardhat": "^2.11.0" - } - }, - "node_modules/solidity-coverage/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/solidity-coverage/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/solidity-coverage/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/solidity-coverage/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/solidity-coverage/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/solidity-coverage/node_modules/globby": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", - "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.0.3", - "glob": "^7.1.3", - "ignore": "^5.1.1", - "merge2": "^1.2.3", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/solidity-coverage/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-coverage/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/solidity-coverage/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/solidity-docgen": { - "version": "0.6.0-beta.36", - "resolved": "https://registry.npmjs.org/solidity-docgen/-/solidity-docgen-0.6.0-beta.36.tgz", - "integrity": "sha512-f/I5G2iJgU1h0XrrjRD0hHMr7C10u276vYvm//rw1TzFcYQ4xTOyAoi9oNAHRU0JU4mY9eTuxdVc2zahdMuhaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "handlebars": "^4.7.7", - "solidity-ast": "^0.4.38" - }, - "peerDependencies": { - "hardhat": "^2.8.0" - } - }, - "node_modules/source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==", - "dev": true, - "optional": true, - "dependencies": { - "amdefine": ">=0.0.4" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/spawndamnit": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spawndamnit/-/spawndamnit-3.0.1.tgz", - "integrity": "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg==", "dev": true, "license": "SEE LICENSE IN LICENSE", "dependencies": { @@ -10129,8 +7303,6 @@ }, "node_modules/spawndamnit/node_modules/signal-exit": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "license": "ISC", "engines": { @@ -10142,48 +7314,11 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true, "license": "BSD-3-Clause" }, - "node_modules/stacktrace-parser": { - "version": "0.1.11", - "resolved": "https://registry.npmjs.org/stacktrace-parser/-/stacktrace-parser-0.1.11.tgz", - "integrity": "sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.7.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stacktrace-parser/node_modules/type-fest": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.7.1.tgz", - "integrity": "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", "dev": true, "license": "MIT", "dependencies": { @@ -10192,8 +7327,6 @@ }, "node_modules/string-argv": { "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, "license": "MIT", "engines": { @@ -10202,8 +7335,6 @@ }, "node_modules/string-width": { "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { @@ -10218,10 +7349,9 @@ "node_modules/string-width-cjs": { "name": "string-width", "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -10233,18 +7363,15 @@ }, "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=8" } }, "node_modules/string-width/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { @@ -10253,8 +7380,6 @@ }, "node_modules/strip-ansi": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", "dependencies": { @@ -10267,10 +7392,9 @@ "node_modules/strip-ansi-cjs": { "name": "strip-ansi", "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-regex": "^5.0.1" }, @@ -10280,32 +7404,14 @@ }, "node_modules/strip-bom": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, "license": "MIT", "engines": { "node": ">=4" } }, - "node_modules/strip-hex-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-hex-prefixed": "1.0.0" - }, - "engines": { - "node": ">=6.5.0", - "npm": ">=3" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", "dev": true, "license": "MIT", "engines": { @@ -10317,8 +7423,6 @@ }, "node_modules/supports-color": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "license": "MIT", "dependencies": { @@ -10330,8 +7434,6 @@ }, "node_modules/table": { "version": "6.9.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz", - "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10347,8 +7449,6 @@ }, "node_modules/table/node_modules/is-fullwidth-code-point": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, "license": "MIT", "engines": { @@ -10357,8 +7457,6 @@ }, "node_modules/table/node_modules/slice-ansi": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10375,99 +7473,32 @@ }, "node_modules/term-size": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-2.2.1.tgz", - "integrity": "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==", "dev": true, "license": "MIT", "engines": { "node": ">=8" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/tinyexec": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", - "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/tinyglobby": { - "version": "0.2.15", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", - "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.2.tgz", + "integrity": "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA==", "dev": true, "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, "engines": { - "node": ">=0.6.0" + "node": ">=18" } }, "node_modules/to-buffer": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.2.2.tgz", - "integrity": "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==", "dev": true, "license": "MIT", "dependencies": { @@ -10481,8 +7512,6 @@ }, "node_modules/to-regex-range": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10492,41 +7521,38 @@ "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "dev": true, "license": "MIT" }, "node_modules/tslib": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", "dev": true, "license": "0BSD" }, - "node_modules/tsort": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tsort/-/tsort-0.0.1.tgz", - "integrity": "sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==", + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, - "license": "MIT" + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } }, "node_modules/type-check": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "dev": true, "license": "MIT", "dependencies": { @@ -10536,33 +7562,8 @@ "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", - "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typed-array-buffer": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", - "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", "dev": true, "license": "MIT", "dependencies": { @@ -10576,25 +7577,9 @@ }, "node_modules/typed-regex": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/typed-regex/-/typed-regex-0.0.8.tgz", - "integrity": "sha512-1XkGm1T/rUngbFROIOw9wPnMAKeMsRoc+c9O6GwOHz6aH/FrJFtcyd2sHASbT0OXeGLot5N1shPNpwHGTv9RdQ==", "dev": true, "license": "MIT" }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/undici": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/undici/-/undici-8.2.0.tgz", @@ -10607,59 +7592,32 @@ }, "node_modules/undici-types": { "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", "dev": true, "license": "MIT" }, "node_modules/universalify": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", "dev": true, "license": "MIT", "engines": { "node": ">= 4.0.0" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/uri-js": { "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } }, - "node_modules/utf8": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", - "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", - "dev": true, - "license": "MIT" - }, "node_modules/util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true, "license": "MIT" }, "node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", "dev": true, "funding": [ "https://github.com/sponsors/broofa", @@ -10670,225 +7628,13 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/viem": { - "version": "2.45.1", - "resolved": "https://registry.npmjs.org/viem/-/viem-2.45.1.tgz", - "integrity": "sha512-LN6Pp7vSfv50LgwhkfSbIXftAM5J89lP9x8TeDa8QM7o41IxlHrDh0F9X+FfnCWtsz11pEVV5sn+yBUoOHNqYA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/wevm" - } - ], - "license": "MIT", - "dependencies": { - "@noble/curves": "1.9.1", - "@noble/hashes": "1.8.0", - "@scure/bip32": "1.7.0", - "@scure/bip39": "1.6.0", - "abitype": "1.2.3", - "isows": "1.0.7", - "ox": "0.11.3", - "ws": "8.18.3" - }, - "peerDependencies": { - "typescript": ">=5.0.4" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/viem/node_modules/@noble/curves": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.1.tgz", - "integrity": "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.8.0" - }, - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/@noble/hashes": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", - "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.21.3 || >=16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/viem/node_modules/ws": { - "version": "8.18.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", - "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/web3-utils": { - "version": "1.10.4", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.10.4.tgz", - "integrity": "sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==", - "dev": true, - "license": "LGPL-3.0", - "dependencies": { - "@ethereumjs/util": "^8.1.0", - "bn.js": "^5.2.1", - "ethereum-bloom-filters": "^1.0.6", - "ethereum-cryptography": "^2.1.2", - "ethjs-unit": "0.1.6", - "number-to-bn": "1.7.0", - "randombytes": "^2.1.0", - "utf8": "3.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/web3-utils/node_modules/@ethereumjs/rlp": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@ethereumjs/rlp/-/rlp-4.0.1.tgz", - "integrity": "sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==", - "dev": true, - "license": "MPL-2.0", - "bin": { - "rlp": "bin/rlp" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/web3-utils/node_modules/@ethereumjs/util": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@ethereumjs/util/-/util-8.1.0.tgz", - "integrity": "sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==", - "dev": true, - "license": "MPL-2.0", - "dependencies": { - "@ethereumjs/rlp": "^4.0.1", - "ethereum-cryptography": "^2.0.0", - "micro-ftch": "^0.3.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/web3-utils/node_modules/@noble/curves": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.4.2.tgz", - "integrity": "sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "1.4.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/web3-utils/node_modules/@noble/hashes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz", - "integrity": "sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/web3-utils/node_modules/@scure/base": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/@scure/base/-/base-1.1.9.tgz", - "integrity": "sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/web3-utils/node_modules/@scure/bip32": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@scure/bip32/-/bip32-1.4.0.tgz", - "integrity": "sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "~1.4.0", - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/web3-utils/node_modules/@scure/bip39": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@scure/bip39/-/bip39-1.3.0.tgz", - "integrity": "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/hashes": "~1.4.0", - "@scure/base": "~1.1.6" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/web3-utils/node_modules/ethereum-cryptography": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-2.2.1.tgz", - "integrity": "sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@noble/curves": "1.4.2", - "@noble/hashes": "1.4.0", - "@scure/bip32": "1.4.0", - "@scure/bip39": "1.3.0" - } - }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "dev": true, "license": "BSD-2-Clause" }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "dev": true, "license": "MIT", "dependencies": { @@ -10898,8 +7644,6 @@ }, "node_modules/which": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "license": "ISC", "dependencies": { @@ -10914,8 +7658,6 @@ }, "node_modules/which-typed-array": { "version": "1.1.20", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.20.tgz", - "integrity": "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==", "dev": true, "license": "MIT", "dependencies": { @@ -10934,42 +7676,21 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/widest-line": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", - "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", - "dev": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/word-wrap": { "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" } }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "license": "MIT" - }, "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/wrap-ansi": { "version": "7.0.0", @@ -10977,6 +7698,7 @@ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -10992,10 +7714,9 @@ "node_modules/wrap-ansi-cjs": { "name": "wrap-ansi", "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -11010,15 +7731,11 @@ }, "node_modules/wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, "license": "ISC" }, "node_modules/ws": { "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", - "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "license": "MIT", "engines": { @@ -11039,8 +7756,6 @@ }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, "license": "ISC", "engines": { @@ -11066,8 +7781,6 @@ }, "node_modules/yargs": { "version": "18.0.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", - "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", "dev": true, "license": "MIT", "dependencies": { @@ -11083,21 +7796,21 @@ } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "license": "ISC", + "peer": true, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-unparser": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -11110,8 +7823,6 @@ }, "node_modules/yargs/node_modules/ansi-regex": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -11123,15 +7834,11 @@ }, "node_modules/yargs/node_modules/emoji-regex": { "version": "10.6.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", - "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, "license": "MIT" }, "node_modules/yargs/node_modules/string-width": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", - "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, "license": "MIT", "dependencies": { @@ -11148,8 +7855,6 @@ }, "node_modules/yargs/node_modules/strip-ansi": { "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -11164,8 +7869,6 @@ }, "node_modules/yargs/node_modules/yargs-parser": { "version": "22.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", - "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", "dev": true, "license": "ISC", "engines": { @@ -11174,8 +7877,6 @@ }, "node_modules/yocto-queue": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", - "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", "dev": true, "license": "MIT", "engines": { @@ -11185,6 +7886,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, "scripts/solhint-custom": { "name": "solhint-plugin-openzeppelin", "version": "0.0.0", diff --git a/package.json b/package.json index 001f2589c90..61db142c27f 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ "scripts": { "compile": "hardhat compile", "compile:harnesses": "env SRC=./fv/harnesses hardhat compile", - "coverage": "scripts/checks/coverage.sh", "docs": "npm run prepare-docs && oz-docs", "docs:watch": "oz-docs watch contracts docs/templates docs/config.js", "prepare": "husky", @@ -19,18 +18,19 @@ "lint:fix": "npm run lint:js:fix && npm run lint:sol:fix", "lint:js": "prettier --log-level warn --ignore-path .gitignore '**/*.{js,ts}' --check && eslint .", "lint:js:fix": "prettier --log-level warn --ignore-path .gitignore '**/*.{js,ts}' --write && eslint . --fix", - "lint:sol": "prettier --log-level warn --ignore-path .gitignore '{contracts,test}/**/*.sol' --check && solhint --config solhint.config.js --noPoster '{contracts,test}/**/*.sol'", + "lint:sol": "prettier --log-level warn --ignore-path .gitignore '{contracts,test}/**/*.sol' --check && solhint --config solhint.config.cjs --noPoster '{contracts,test}/**/*.sol'", "lint:sol:fix": "prettier --log-level warn --ignore-path .gitignore '{contracts,test}/**/*.sol' --write", "clean": "hardhat clean && rimraf build contracts/build", "prepack": "scripts/prepack.sh", "generate": "scripts/generate/run.js", "pragma": "npm run compile && scripts/minimize-pragma.js artifacts/build-info/*", "version": "scripts/release/version.sh", - "test": ". scripts/set-max-old-space-size.sh && hardhat test", + "test": "hardhat test", "test:generation": "scripts/checks/generation.sh", - "test:inheritance": "npm run compile && scripts/checks/inheritance-ordering.js artifacts/build-info/*", - "test:pragma": "npm run compile && scripts/checks/pragma-validity.js artifacts/build-info/*", - "gas-report": "env ENABLE_GAS_REPORT=true npm run test", + "test:inheritance": "npm run compile && scripts/checks/inheritance-ordering.js artifacts/build-info/*.output.json", + "test:pragma": "npm run compile && scripts/checks/pragma-validity.js artifacts/build-info/*.output.json", + "coverage": "hardhat test --coverage", + "gas-report": "hardhat test --gas-stats", "slither": "npm run clean && slither ." }, "repository": { @@ -59,25 +59,26 @@ "@eslint/compat": "^1.2.1", "@ethereumjs/mpt": "^10.1.0", "@noble/curves": "^2.0.1", - "@nomicfoundation/hardhat-chai-matchers": "^2.0.6", - "@nomicfoundation/hardhat-ethers": "^3.0.9", - "@nomicfoundation/hardhat-network-helpers": "^1.0.13", + "@nomicfoundation/hardhat-ethers": "^4.0.7", + "@nomicfoundation/hardhat-ethers-chai-matchers": "^3.0.4", + "@nomicfoundation/hardhat-mocha": "^3.0.15", + "@nomicfoundation/hardhat-network-helpers": "^3.0.4", "@openzeppelin/docs-utils": "^0.1.6", "@openzeppelin/merkle-tree": "^1.0.7", "@openzeppelin/upgrade-safe-transpiler": "^0.4.1", "@openzeppelin/upgrades-core": "^1.20.6", - "chai": "^4.2.0", + "@types/node": "^25.0.9", + "@types/yargs": "^17.0.35", + "chai": "^5.2.2", "eslint": "^9.0.0", "eslint-config-prettier": "^10.0.0", "ethers": "^6.16.0", "glob": "^13.0.0", "globals": "^17.0.0", "graphlib": "^2.1.8", - "hardhat": "^2.28.5", - "hardhat-exposed": "^0.3.15", - "hardhat-gas-reporter": "^2.1.0", - "hardhat-ignore-warnings": "^0.2.11", - "hardhat-predeploy": "^0.4.1", + "hardhat": "^3.5.0", + "hardhat-ignore-warnings": "^0.3.0", + "hardhat-predeploy": "^1.0.1", "husky": "^9.1.7", "interoperable-addresses": "^0.1.3", "lint-staged": "^17.0.0", @@ -88,11 +89,9 @@ "prettier-plugin-solidity": "^2.0.0", "rimraf": "^6.0.0", "semver": "^7.3.5", - "solhint": "^6.0.1", + "solhint": "^6.0.3", "solhint-plugin-openzeppelin": "file:scripts/solhint-custom", - "solidity-ast": "^0.4.50", - "solidity-coverage": "^0.8.14", - "solidity-docgen": "^0.6.0-beta.29", + "solidity-ast": "^0.4.61", "undici": "^8.2.0", "yargs": "^18.0.0" }, @@ -103,7 +102,8 @@ ], "{contracts,test}/**/*.sol": [ "prettier --log-level warn --ignore-path .gitignore --check", - "solhint --config solhint.config.js --noPoster" + "solhint --config solhint.config.cjs --noPoster" ] - } + }, + "type": "module" } diff --git a/remappings.txt b/remappings.txt index 304d1386a58..a6be3bfd689 100644 --- a/remappings.txt +++ b/remappings.txt @@ -1 +1,5 @@ @openzeppelin/contracts/=contracts/ + +forge-std=lib/forge-std/src +halmos-cheatcodes=lib/halmos-cheatcodes/src +erc4626-tests=lib/erc4626-tests diff --git a/scripts/checks/compareGasReports.js b/scripts/checks/compare-gas-reports.js similarity index 63% rename from scripts/checks/compareGasReports.js rename to scripts/checks/compare-gas-reports.js index 20fe969092a..42aff7abe47 100755 --- a/scripts/checks/compareGasReports.js +++ b/scripts/checks/compare-gas-reports.js @@ -1,10 +1,12 @@ #!/usr/bin/env node -const fs = require('fs'); -const chalk = require('chalk'); +import fs from 'fs'; +import chalk from 'chalk'; -const { hideBin } = require('yargs/helpers'); -const { argv } = require('yargs/yargs')(hideBin(process.argv)) +import { hideBin } from 'yargs/helpers'; +import yargs from 'yargs/yargs'; + +const { argv } = yargs(hideBin(process.argv)) .env('') .options({ style: { @@ -26,21 +28,23 @@ const { argv } = require('yargs/yargs')(hideBin(process.argv)) const BASE_TX_COST = 21000; // Utilities -function sum(...args) { - return args.reduce((a, b) => a + b, 0); -} - -function average(...args) { - return sum(...args) / args.length; -} - -function variation(current, previous, offset = 0) { - return { - value: current, - delta: current - previous, - prcnt: (100 * (current - previous)) / (previous - offset), - }; -} +const variation = (current, previous, offset = 0) => ({ + value: current - offset, + delta: current - previous, + prcnt: (100 * (current - previous)) / (previous - offset), +}); + +const variations = (current, previous, offset = 0) => + current.min == current.max && previous.min == previous.max + ? { + avg: variation(current.avg, previous.avg, offset), + } + : { + min: variation(current.min, previous.min, offset), + max: variation(current.max, previous.max, offset), + avg: variation(current.avg, previous.avg, offset), + median: variation(current.median, previous.median, offset), + }; // Report class class Report { @@ -51,54 +55,33 @@ class Report { // Compare two reports static compare(update, ref, opts = { hideEqual: true, strictTesting: false }) { - if (JSON.stringify(update.options?.solcInfo) !== JSON.stringify(ref.options?.solcInfo)) { - console.warn('WARNING: Reports produced with non matching metadata'); - } - - // gasReporter 1.0.0 uses ".info", but 2.0.0 uses ".data" - const updateInfo = update.info ?? update.data; - const refInfo = ref.info ?? ref.data; - - const deployments = updateInfo.deployments - .map(contract => - Object.assign(contract, { previousVersion: refInfo.deployments.find(({ name }) => name === contract.name) }), - ) - .filter(contract => contract.gasData?.length && contract.previousVersion?.gasData?.length) - .flatMap(contract => [ - { - contract: contract.name, - method: '[bytecode length]', - avg: variation(contract.bytecode.length / 2 - 1, contract.previousVersion.bytecode.length / 2 - 1), - }, - { - contract: contract.name, - method: '[construction cost]', - avg: variation( - ...[contract.gasData, contract.previousVersion.gasData].map(x => Math.round(average(...x))), - BASE_TX_COST, - ), - }, - ]) - .sort((a, b) => `${a.contract}:${a.method}`.localeCompare(`${b.contract}:${b.method}`)); - - const methods = Object.keys(updateInfo.methods) - .filter(key => refInfo.methods[key]) - .filter(key => updateInfo.methods[key].numberOfCalls > 0) - .filter( - key => !opts.strictTesting || updateInfo.methods[key].numberOfCalls === refInfo.methods[key].numberOfCalls, - ) - .map(key => ({ - contract: refInfo.methods[key].contract, - method: refInfo.methods[key].fnSig, - min: variation(...[updateInfo, refInfo].map(x => Math.min(...x.methods[key].gasData)), BASE_TX_COST), - max: variation(...[updateInfo, refInfo].map(x => Math.max(...x.methods[key].gasData)), BASE_TX_COST), - avg: variation(...[updateInfo, refInfo].map(x => Math.round(average(...x.methods[key].gasData))), BASE_TX_COST), - })) - .sort((a, b) => `${a.contract}:${a.method}`.localeCompare(`${b.contract}:${b.method}`)); - - return [] - .concat(deployments, methods) - .filter(row => !opts.hideEqual || row.min?.delta || row.max?.delta || row.avg?.delta); + return Object.entries(update.contracts) + .filter(([key]) => key in ref.contracts) + .flatMap(([key, contract]) => { + const refContract = ref.contracts[key]; + const refFunctions = refContract.functions ?? {}; + return [ + ...(contract.deployment && refContract.deployment + ? [ + { + contract: contract.contractName, + method: '[constructor]', + ...variations(contract.deployment, refContract.deployment, BASE_TX_COST), + }, + ] + : []), + ...Object.entries(contract.functions ?? {}) + .filter(([method]) => method in refFunctions) + .filter(([method, data]) => !opts.strictTesting || data.count === refFunctions[method].count) + .map(([method, currentData]) => ({ + contract: contract.contractName, + method, + ...variations(currentData, refFunctions[method], BASE_TX_COST), + })), + ]; + }) + .sort((a, b) => `${a.contract}:${a.method}`.localeCompare(`${b.contract}:${b.method}`)) + .filter(row => !opts.hideEqual || row.min?.delta || row.max?.delta || row.avg?.delta || row.median?.delta); } } @@ -130,6 +113,7 @@ function formatCmpShell(rows) { { txt: 'Method', length: methodLength }, { txt: 'Min', length: 30 }, { txt: 'Max', length: 30 }, + { txt: 'Median', length: 30 }, { txt: 'Avg', length: 30 }, { txt: '', length: 0 }, ]; @@ -150,6 +134,7 @@ function formatCmpShell(rows) { entry.method.padEnd(methodLength), ...formatCellShell(entry.min), ...formatCellShell(entry.max), + ...formatCellShell(entry.median), ...formatCellShell(entry.avg), '', ] diff --git a/scripts/checks/compare-layout.js b/scripts/checks/compare-layout.js index 69a1e77fd70..4d4770ddfb6 100755 --- a/scripts/checks/compare-layout.js +++ b/scripts/checks/compare-layout.js @@ -1,10 +1,12 @@ #!/usr/bin/env node -const fs = require('fs'); -const { getStorageUpgradeReport } = require('@openzeppelin/upgrades-core/dist/storage'); +import fs from 'fs'; +import { getStorageUpgradeReport } from '@openzeppelin/upgrades-core/dist/storage/index.js'; -const { hideBin } = require('yargs/helpers'); -const { argv } = require('yargs/yargs')(hideBin(process.argv)) +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; + +const { argv } = yargs(hideBin(process.argv)) .env('') .options({ ref: { type: 'string', required: true }, diff --git a/scripts/checks/coverage.sh b/scripts/checks/coverage.sh deleted file mode 100755 index fd8b9e84329..00000000000 --- a/scripts/checks/coverage.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -export COVERAGE=true -export FOUNDRY_FUZZ_RUNS=10 - -. scripts/set-max-old-space-size.sh - -# Hardhat coverage -hardhat coverage - -if [ "${CI:-"false"}" == "true" ]; then - # Foundry coverage - forge coverage --report lcov --ir-minimum - # Remove zero hits - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' '/,0/d' lcov.info - else - sed -i '/,0/d' lcov.info - fi -fi - -# Reports are then uploaded to Codecov automatically by workflow, and merged. diff --git a/scripts/checks/extract-layout.js b/scripts/checks/extract-layout.js index 1a38af19677..d83a8d634bb 100644 --- a/scripts/checks/extract-layout.js +++ b/scripts/checks/extract-layout.js @@ -1,16 +1,21 @@ -const fs = require('fs'); -const { findAll, astDereferencer, srcDecoder } = require('solidity-ast/utils'); -const { extractStorageLayout } = require('@openzeppelin/upgrades-core/dist/storage/extract'); +import fs from 'fs'; +import { findAll, astDereferencer, srcDecoder } from 'solidity-ast/utils.js'; +import { extractStorageLayout } from '@openzeppelin/upgrades-core/dist/storage/extract.js'; -const { hideBin } = require('yargs/helpers'); -const { argv } = require('yargs/yargs')(hideBin(process.argv)); +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; + +const { _: artifacts } = yargs(hideBin(process.argv)).argv; +const inputArtifacts = artifacts.filter(p => !p.endsWith('.output.json')); const skipPath = ['contracts/mocks/', 'contracts-exposed/']; const skipKind = ['interface', 'library']; function extractLayouts(path) { const layout = {}; - const { input, output } = JSON.parse(fs.readFileSync(path)); + const { input } = JSON.parse(fs.readFileSync(path)); + const outputPath = path.replace(/\.json$/, '.output.json'); + const { output } = JSON.parse(fs.readFileSync(outputPath)); const decoder = srcDecoder(input, output); const deref = astDereferencer(output); @@ -36,4 +41,4 @@ function extractLayouts(path) { return layout; } -console.log(JSON.stringify(Object.assign(...argv._.map(extractLayouts)))); +console.log(JSON.stringify(Object.assign({}, ...inputArtifacts.map(extractLayouts)))); diff --git a/scripts/checks/inheritance-ordering.js b/scripts/checks/inheritance-ordering.js index 5ae0c22dff3..7d2d887ab0c 100755 --- a/scripts/checks/inheritance-ordering.js +++ b/scripts/checks/inheritance-ordering.js @@ -1,33 +1,41 @@ #!/usr/bin/env node -const path = require('path'); -const graphlib = require('graphlib'); -const match = require('micromatch'); -const { findAll } = require('solidity-ast/utils'); -const { hideBin } = require('yargs/helpers'); -const { _: artifacts } = require('yargs/yargs')(hideBin(process.argv)).argv; +import fs from 'fs'; +import path from 'path'; +import graphlib from 'graphlib'; +import match from 'micromatch'; +import { findAll } from 'solidity-ast/utils.js'; +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; -// files to skip -const skipPatterns = ['contracts-exposed/**', 'contracts/mocks/**']; +const { _: artifacts } = yargs(hideBin(process.argv)).argv; + +// only consider files in the package: take pattern from package.json +const { files: patterns } = JSON.parse( + fs.readFileSync(path.resolve(import.meta.dirname, '../../', 'package.json'), 'utf-8'), +); for (const artifact of artifacts) { - const { output: solcOutput } = require(path.resolve(__dirname, '../..', artifact)); + const { output: solcOutput } = JSON.parse( + fs.readFileSync(path.resolve(import.meta.dirname, '../..', artifact), 'utf-8'), + ); const graph = new graphlib.Graph({ directed: true }); const names = {}; const linearized = []; - for (const source in solcOutput.contracts) { - if (match.any(source, skipPatterns)) continue; - for (const contractDef of findAll('ContractDefinition', solcOutput.sources[source].ast)) { - names[contractDef.id] = contractDef.name; - linearized.push(contractDef.linearizedBaseContracts); - - contractDef.linearizedBaseContracts.forEach((c1, i, contracts) => - contracts.slice(i + 1).forEach(c2 => { - graph.setEdge(c1, c2); - }), - ); + for (const source in solcOutput?.contracts ?? []) { + if (match.all(source.replace(/^project/, ''), patterns)) { + for (const contractDef of findAll('ContractDefinition', solcOutput.sources[source].ast)) { + names[contractDef.id] = contractDef.name; + linearized.push(contractDef.linearizedBaseContracts); + + contractDef.linearizedBaseContracts.forEach((c1, i, contracts) => + contracts.slice(i + 1).forEach(c2 => { + graph.setEdge(c1, c2); + }), + ); + } } } diff --git a/scripts/checks/pragma-validity.js b/scripts/checks/pragma-validity.js index 491f650bce2..73e66cfd596 100755 --- a/scripts/checks/pragma-validity.js +++ b/scripts/checks/pragma-validity.js @@ -1,13 +1,11 @@ #!/usr/bin/env node -const semver = require('semver'); -const pLimit = require('p-limit').default; - -const { hideBin } = require('yargs/helpers'); -const yargs = require('yargs/yargs'); - -const getContractsMetadata = require('../get-contracts-metadata'); -const { compile } = require('../solc-versions'); +import semver from 'semver'; +import pLimit from 'p-limit'; +import yargs from 'yargs'; +import { hideBin } from 'yargs/helpers'; +import { getContractsMetadata } from '../get-contracts-metadata.js'; +import { compile } from '../solc-versions.js'; const { argv: { pattern, skipPatterns, verbose, concurrency, _: artifacts }, diff --git a/scripts/fetch-common-contracts.js b/scripts/fetch-common-contracts.js deleted file mode 100755 index af904243b8f..00000000000 --- a/scripts/fetch-common-contracts.js +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/bin/env node - -// This script snapshots the bytecode and ABI for the `hardhat/common-contracts.js` script. -// - Bytecode is fetched directly from the blockchain by querying the provided client endpoint. If no endpoint is -// provided, ethers default provider is used instead. -// - ABI is fetched from etherscan's API using the provided etherscan API key. If no API key is provided, ABI will not -// be fetched and saved. -// -// The produced artifacts are stored in the `output` folder ('test/bin' by default). For each contract, two files are -// produced: -// - `.bytecode` containing the contract bytecode (in binary encoding) -// - `.abi` containing the ABI (in utf-8 encoding) - -const fs = require('fs'); -const path = require('path'); -const { ethers } = require('ethers'); -const { request } = require('undici'); -const { hideBin } = require('yargs/helpers'); -const { argv } = require('yargs/yargs')(hideBin(process.argv)) - .env('') - .options({ - output: { type: 'string', default: 'test/bin/' }, - client: { type: 'string' }, - etherscan: { type: 'string' }, - }); - -// List of contract names and addresses to fetch -const config = { - EntryPoint070: '0x0000000071727De22E5E9d8BAf0edAc6f37da032', - SenderCreator070: '0xEFC2c1444eBCC4Db75e7613d20C6a62fF67A167C', - EntryPoint080: '0x4337084D9E255Ff0702461CF8895CE9E3b5Ff108', - SenderCreator080: '0x449ED7C3e6Fee6a97311d4b55475DF59C44AdD33', -}; - -Promise.all( - Object.entries(config).flatMap(([name, addr]) => - Promise.all([ - argv.etherscan && - request(`https://api.etherscan.io/api?module=contract&action=getabi&address=${addr}&apikey=${argv.etherscan}`) - .then(({ body }) => body.json()) - .then(({ result: abi }) => fs.writeFile(path.join(argv.output, `${name}.abi`), abi, 'utf-8', () => {})), - ethers - .getDefaultProvider(argv.client) - .getCode(addr) - .then(bytecode => - fs.writeFile(path.join(argv.output, `${name}.bytecode`), ethers.getBytes(bytecode), 'binary', () => {}), - ), - ]), - ), -); diff --git a/scripts/generate/format-lines.js b/scripts/generate/format-lines.js index fa3d6b120d8..8a5516f7c6c 100644 --- a/scripts/generate/format-lines.js +++ b/scripts/generate/format-lines.js @@ -1,4 +1,4 @@ -function formatLines(...lines) { +export default function formatLines(...lines) { return [...indentEach(0, lines)].join('\n') + '\n'; } @@ -12,5 +12,3 @@ function* indentEach(indent, lines) { } } } - -module.exports = formatLines; diff --git a/scripts/generate/helpers/sanitize.js b/scripts/generate/helpers/sanitize.js index e680ec1bf46..3a337629df0 100644 --- a/scripts/generate/helpers/sanitize.js +++ b/scripts/generate/helpers/sanitize.js @@ -1,5 +1,3 @@ -module.exports = { - address: expr => `and(${expr}, shr(96, not(0)))`, - bool: expr => `iszero(iszero(${expr}))`, - bytes: (expr, size) => `and(${expr}, shl(${256 - 8 * size}, not(0)))`, -}; +export const address = expr => `and(${expr}, shr(96, not(0)))`; +export const bool = expr => `iszero(iszero(${expr}))`; +export const bytes = (expr, size) => `and(${expr}, shl(${256 - 8 * size}, not(0)))`; diff --git a/scripts/generate/run.js b/scripts/generate/run.js index 394bb39525e..0dc4b486096 100755 --- a/scripts/generate/run.js +++ b/scripts/generate/run.js @@ -1,9 +1,9 @@ #!/usr/bin/env node -const cp = require('child_process'); -const fs = require('fs'); -const path = require('path'); -const format = require('./format-lines'); +import cp from 'child_process'; +import fs from 'fs'; +import path from 'path'; +import format from './format-lines.js'; function getVersion(path) { try { @@ -13,8 +13,8 @@ function getVersion(path) { } } -function generateFromTemplate(file, template, outputPrefix = '', lint = false) { - const script = path.relative(path.join(__dirname, '../..'), __filename); +async function generateFromTemplate(file, template, outputPrefix = '', lint = false) { + const script = path.relative(path.join(import.meta.dirname, '../..'), import.meta.filename); const input = path.join(path.dirname(script), template); const output = path.join(outputPrefix, file); const version = getVersion(output); @@ -23,7 +23,7 @@ function generateFromTemplate(file, template, outputPrefix = '', lint = false) { ...(version ? [version + ` (${file})`] : []), `// This file was procedurally generated from ${input}.`, '', - require(template).trimEnd(), + (await import(template)).default.trimEnd(), ); fs.writeFileSync(output, content); @@ -48,7 +48,7 @@ for (const [file, template] of Object.entries({ 'mocks/StorageSlotMock.sol': './templates/StorageSlotMock.js', 'mocks/TransientSlotMock.sol': './templates/TransientSlotMock.js', })) { - generateFromTemplate(file, template, './contracts/', needsLinter.includes(file)); + await generateFromTemplate(file, template, './contracts/', needsLinter.includes(file)); } // Tests @@ -57,5 +57,5 @@ for (const [file, template] of Object.entries({ 'utils/Packing.t.sol': './templates/Packing.t.js', 'utils/SlotDerivation.t.sol': './templates/SlotDerivation.t.js', })) { - generateFromTemplate(file, template, './test/', needsLinter.includes(file)); + await generateFromTemplate(file, template, './test/', needsLinter.includes(file)); } diff --git a/scripts/generate/templates/Arrays.js b/scripts/generate/templates/Arrays.js index 3dd4d8c7eea..5e7ed8b2a5e 100644 --- a/scripts/generate/templates/Arrays.js +++ b/scripts/generate/templates/Arrays.js @@ -1,6 +1,6 @@ -const format = require('../format-lines'); -const { capitalize } = require('../../helpers'); -const { TYPES } = require('./Arrays.opts'); +import format from '../format-lines.js'; +import { capitalize } from '../../helpers.js'; +import { TYPES } from './Arrays.opts.js'; const header = `\ pragma solidity ^0.8.24; @@ -476,7 +476,7 @@ function replace( `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library Arrays {', format( diff --git a/scripts/generate/templates/Arrays.opts.js b/scripts/generate/templates/Arrays.opts.js index 80efc80b00b..7c76968d30b 100644 --- a/scripts/generate/templates/Arrays.opts.js +++ b/scripts/generate/templates/Arrays.opts.js @@ -1,9 +1,7 @@ -const TYPES = [ +export const TYPES = [ { name: 'address', isValueType: true }, { name: 'bytes32', isValueType: true }, { name: 'uint256', isValueType: true }, { name: 'bytes', isValueType: false }, { name: 'string', isValueType: false }, ]; - -module.exports = { TYPES }; diff --git a/scripts/generate/templates/Checkpoints.js b/scripts/generate/templates/Checkpoints.js index 1ead8df6f29..ae34ab1d8cd 100644 --- a/scripts/generate/templates/Checkpoints.js +++ b/scripts/generate/templates/Checkpoints.js @@ -1,5 +1,5 @@ -const format = require('../format-lines'); -const { OPTS } = require('./Checkpoints.opts'); +import format from '../format-lines.js'; +import { OPTS } from './Checkpoints.opts.js'; // TEMPLATE const header = `\ @@ -229,7 +229,7 @@ function _unsafeAccess( `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library Checkpoints {', format( diff --git a/scripts/generate/templates/Checkpoints.opts.js b/scripts/generate/templates/Checkpoints.opts.js index c0920290af5..578cf98e1e3 100644 --- a/scripts/generate/templates/Checkpoints.opts.js +++ b/scripts/generate/templates/Checkpoints.opts.js @@ -1,6 +1,4 @@ // OPTIONS -const VALUE_SIZES = [256, 224, 208, 160]; - const defaultOpts = size => ({ historyTypeName: `Trace${size}`, checkpointTypeName: `Checkpoint${size}`, @@ -12,7 +10,6 @@ const defaultOpts = size => ({ valueFieldName: '_value', }); -module.exports = { - VALUE_SIZES, - OPTS: VALUE_SIZES.map(size => defaultOpts(size)), -}; +export const VALUE_SIZES = [256, 224, 208, 160]; + +export const OPTS = VALUE_SIZES.map(size => defaultOpts(size)); diff --git a/scripts/generate/templates/Checkpoints.t.js b/scripts/generate/templates/Checkpoints.t.js index 23d9466d28f..6e399f1b967 100644 --- a/scripts/generate/templates/Checkpoints.t.js +++ b/scripts/generate/templates/Checkpoints.t.js @@ -1,6 +1,6 @@ -const format = require('../format-lines'); -const { capitalize } = require('../../helpers'); -const { OPTS } = require('./Checkpoints.opts.js'); +import format from '../format-lines.js'; +import { capitalize } from '../../helpers.js'; +import { OPTS } from './Checkpoints.opts.js'; // TEMPLATE const header = `\ @@ -130,7 +130,7 @@ function testLookup(${opts.keyTypeName}[] memory keys, ${opts.valueTypeName}[] m `; // GENERATE -module.exports = format( +export default format( header, ...OPTS.flatMap(opts => [ `contract Checkpoints${opts.historyTypeName}Test is Test {`, diff --git a/scripts/generate/templates/Enumerable.opts.js b/scripts/generate/templates/Enumerable.opts.js index 3551b9cda7d..fe7c0948feb 100644 --- a/scripts/generate/templates/Enumerable.opts.js +++ b/scripts/generate/templates/Enumerable.opts.js @@ -1,6 +1,6 @@ -const { capitalize, mapValues } = require('../../helpers'); +import { capitalize, mapValues } from '../../helpers.js'; -const typeDescr = ({ type, size = 0, memory = false }) => { +export const typeDescr = ({ type, size = 0, memory = false }) => { memory |= size > 0; const name = [type == 'uint256' ? 'Uint' : capitalize(type), size].filter(Boolean).join('x'); @@ -10,19 +10,19 @@ const typeDescr = ({ type, size = 0, memory = false }) => { return { name, type: typeFull, typeLoc, base, size, memory }; }; -const toSetTypeDescr = value => ({ +export const toSetTypeDescr = value => ({ name: value.name + 'Set', value, }); -const toMapTypeDescr = ({ key, value }) => ({ +export const toMapTypeDescr = ({ key, value }) => ({ name: `${key.name}To${value.name}Map`, keySet: toSetTypeDescr(key), key, value, }); -const SET_TYPES = [ +export const SET_TYPES = [ { type: 'bytes32' }, { type: 'bytes4' }, { type: 'address' }, @@ -33,7 +33,7 @@ const SET_TYPES = [ .map(typeDescr) .map(toSetTypeDescr); -const MAP_TYPES = [] +export const MAP_TYPES = [] .concat( // value type maps ['uint256', 'address', 'bytes32'] @@ -46,11 +46,3 @@ const MAP_TYPES = [] ) .map(entry => mapValues(entry, typeDescr)) .map(toMapTypeDescr); - -module.exports = { - SET_TYPES, - MAP_TYPES, - typeDescr, - toSetTypeDescr, - toMapTypeDescr, -}; diff --git a/scripts/generate/templates/EnumerableMap.js b/scripts/generate/templates/EnumerableMap.js index 107e29e8ed7..56c3fef17e9 100644 --- a/scripts/generate/templates/EnumerableMap.js +++ b/scripts/generate/templates/EnumerableMap.js @@ -1,6 +1,6 @@ -const format = require('../format-lines'); -const { fromBytes32, toBytes32 } = require('./conversion'); -const { MAP_TYPES } = require('./Enumerable.opts'); +import format from '../format-lines.js'; +import { fromBytes32, toBytes32 } from './conversion.js'; +import { MAP_TYPES } from './Enumerable.opts.js'; const header = `\ pragma solidity ^0.8.24; @@ -448,7 +448,7 @@ function keys(${name} storage map, uint256 start, uint256 end) internal view ret `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library EnumerableMap {', format( diff --git a/scripts/generate/templates/EnumerableSet.js b/scripts/generate/templates/EnumerableSet.js index 2c5a54227a8..6277b9fc7f8 100644 --- a/scripts/generate/templates/EnumerableSet.js +++ b/scripts/generate/templates/EnumerableSet.js @@ -1,6 +1,6 @@ -const format = require('../format-lines'); -const { fromBytes32, toBytes32 } = require('./conversion'); -const { SET_TYPES } = require('./Enumerable.opts'); +import format from '../format-lines.js'; +import { fromBytes32, toBytes32 } from './conversion.js'; +import { SET_TYPES } from './Enumerable.opts.js'; const header = `\ pragma solidity ^0.8.24; @@ -456,7 +456,7 @@ function values(${name} storage set, uint256 start, uint256 end) internal view r `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library EnumerableSet {', format( diff --git a/scripts/generate/templates/MerkleProof.js b/scripts/generate/templates/MerkleProof.js index f7b8a6a7ac5..13abe0b2cf1 100644 --- a/scripts/generate/templates/MerkleProof.js +++ b/scripts/generate/templates/MerkleProof.js @@ -1,5 +1,5 @@ -const format = require('../format-lines'); -const { OPTS } = require('./MerkleProof.opts'); +import format from '../format-lines.js'; +import { OPTS } from './MerkleProof.opts.js'; const DEFAULT_HASH = 'Hashes.commutativeKeccak256'; @@ -172,7 +172,7 @@ function processMultiProof${suffix}(${formatArgsMultiline( `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library MerkleProof {', format( diff --git a/scripts/generate/templates/MerkleProof.opts.js b/scripts/generate/templates/MerkleProof.opts.js index 911f2392257..8c9d3e6a143 100644 --- a/scripts/generate/templates/MerkleProof.opts.js +++ b/scripts/generate/templates/MerkleProof.opts.js @@ -1,11 +1,9 @@ -const { product } = require('../../helpers'); +import { product } from '../../helpers.js'; -const OPTS = product( +export const OPTS = product( [ { suffix: '', location: 'memory' }, { suffix: 'Calldata', location: 'calldata' }, ], [{ visibility: 'pure' }, { visibility: 'view', hash: 'hasher' }], ).map(objs => Object.assign({}, ...objs)); - -module.exports = { OPTS }; diff --git a/scripts/generate/templates/Packing.js b/scripts/generate/templates/Packing.js index 9f3b7716a6a..e74f8944193 100644 --- a/scripts/generate/templates/Packing.js +++ b/scripts/generate/templates/Packing.js @@ -1,7 +1,7 @@ -const format = require('../format-lines'); -const sanitize = require('../helpers/sanitize'); -const { product } = require('../../helpers'); -const { SIZES } = require('./Packing.opts'); +import format from '../format-lines.js'; +import * as sanitize from '../helpers/sanitize.js'; +import { product } from '../../helpers.js'; +import { SIZES } from './Packing.opts.js'; // TEMPLATE const header = `\ @@ -74,7 +74,7 @@ function replace_${outer}_${inner}(bytes${outer} self, bytes${inner} value, uint `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library Packing {', format( diff --git a/scripts/generate/templates/Packing.opts.js b/scripts/generate/templates/Packing.opts.js index 893ad6297cf..b52d8b65bb9 100644 --- a/scripts/generate/templates/Packing.opts.js +++ b/scripts/generate/templates/Packing.opts.js @@ -1,3 +1 @@ -module.exports = { - SIZES: [1, 2, 4, 6, 8, 10, 12, 16, 20, 22, 24, 28, 32], -}; +export const SIZES = [1, 2, 4, 6, 8, 10, 12, 16, 20, 22, 24, 28, 32]; diff --git a/scripts/generate/templates/Packing.t.js b/scripts/generate/templates/Packing.t.js index 3889eea06ee..44ba66b7bbd 100644 --- a/scripts/generate/templates/Packing.t.js +++ b/scripts/generate/templates/Packing.t.js @@ -1,6 +1,6 @@ -const format = require('../format-lines'); -const { product } = require('../../helpers'); -const { SIZES } = require('./Packing.opts'); +import format from '../format-lines.js'; +import { product } from '../../helpers.js'; +import { SIZES } from './Packing.opts.js'; // TEMPLATE const header = `\ @@ -29,7 +29,7 @@ function testSymbolicReplace(bytes${outer} container, bytes${inner} newValue, ui `; // GENERATE -module.exports = format( +export default format( header, 'contract PackingTest is Test {', format( diff --git a/scripts/generate/templates/SafeCast.js b/scripts/generate/templates/SafeCast.js index 16d1ee8f7f1..e482904f7f4 100644 --- a/scripts/generate/templates/SafeCast.js +++ b/scripts/generate/templates/SafeCast.js @@ -1,5 +1,5 @@ -const format = require('../format-lines'); -const { range } = require('../../helpers'); +import format from '../format-lines.js'; +import { range } from '../../helpers.js'; const LENGTHS = range(8, 256, 8).reverse(); // 248 → 8 (in steps of 8) @@ -126,7 +126,7 @@ function toUint(bool b) internal pure returns (uint256 u) { `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library SafeCast {', format( diff --git a/scripts/generate/templates/Slot.opts.js b/scripts/generate/templates/Slot.opts.js index 3eca2bcf08f..363ecda1ab8 100644 --- a/scripts/generate/templates/Slot.opts.js +++ b/scripts/generate/templates/Slot.opts.js @@ -1,4 +1,4 @@ -const { capitalize } = require('../../helpers'); +import { capitalize } from '../../helpers.js'; const TYPES = [ { type: 'address', isValueType: true }, @@ -12,4 +12,4 @@ const TYPES = [ Object.assign(TYPES, Object.fromEntries(TYPES.map(entry => [entry.type, entry]))); -module.exports = { TYPES }; +export { TYPES }; diff --git a/scripts/generate/templates/SlotDerivation.js b/scripts/generate/templates/SlotDerivation.js index 931c9fc25e8..e7a85949f0b 100644 --- a/scripts/generate/templates/SlotDerivation.js +++ b/scripts/generate/templates/SlotDerivation.js @@ -1,6 +1,6 @@ -const format = require('../format-lines'); -const sanitize = require('../helpers/sanitize'); -const { TYPES } = require('./Slot.opts'); +import format from '../format-lines.js'; +import * as sanitize from '../helpers/sanitize.js'; +import { TYPES } from './Slot.opts.js'; const header = `\ pragma solidity ^0.8.20; @@ -105,7 +105,7 @@ function deriveMapping(bytes32 slot, ${type} memory key) internal pure returns ( `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library SlotDerivation {', format( diff --git a/scripts/generate/templates/SlotDerivation.t.js b/scripts/generate/templates/SlotDerivation.t.js index 8e18ca528bb..c2149e38d3a 100644 --- a/scripts/generate/templates/SlotDerivation.t.js +++ b/scripts/generate/templates/SlotDerivation.t.js @@ -1,6 +1,6 @@ -const format = require('../format-lines'); -const { capitalize } = require('../../helpers'); -const { TYPES } = require('./Slot.opts'); +import format from '../format-lines.js'; +import { capitalize } from '../../helpers.js'; +import { TYPES } from './Slot.opts.js'; const header = `\ pragma solidity ^0.8.20; @@ -101,7 +101,7 @@ function _assertDeriveMapping${name}(${type} memory key) internal view { `; // GENERATE -module.exports = format( +export default format( header, 'contract SlotDerivationTest is Test, SymTest {', format( diff --git a/scripts/generate/templates/StorageSlot.js b/scripts/generate/templates/StorageSlot.js index 53287b81fd9..0be00caca96 100644 --- a/scripts/generate/templates/StorageSlot.js +++ b/scripts/generate/templates/StorageSlot.js @@ -1,5 +1,5 @@ -const format = require('../format-lines'); -const { TYPES } = require('./Slot.opts'); +import format from '../format-lines.js'; +import { TYPES } from './Slot.opts.js'; const header = `\ pragma solidity ^0.8.20; @@ -64,7 +64,7 @@ function get${name}Slot(${type} storage store) internal pure returns (${name}Slo `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library StorageSlot {', format( diff --git a/scripts/generate/templates/StorageSlotMock.js b/scripts/generate/templates/StorageSlotMock.js index c6d326a5e26..a6c8138c357 100644 --- a/scripts/generate/templates/StorageSlotMock.js +++ b/scripts/generate/templates/StorageSlotMock.js @@ -1,5 +1,5 @@ -const format = require('../format-lines'); -const { TYPES } = require('./Slot.opts'); +import format from '../format-lines.js'; +import { TYPES } from './Slot.opts.js'; const header = `\ pragma solidity ^0.8.20; @@ -41,7 +41,7 @@ function get${name}Storage(uint256 key) public view returns (${type} memory) { `; // GENERATE -module.exports = format( +export default format( header, 'contract StorageSlotMock is Multicall {', format( diff --git a/scripts/generate/templates/TransientSlot.js b/scripts/generate/templates/TransientSlot.js index 9ede32f85c5..ac85a7bb559 100644 --- a/scripts/generate/templates/TransientSlot.js +++ b/scripts/generate/templates/TransientSlot.js @@ -1,5 +1,5 @@ -const format = require('../format-lines'); -const { TYPES } = require('./Slot.opts'); +import format from '../format-lines.js'; +import { TYPES } from './Slot.opts.js'; const header = `\ pragma solidity ^0.8.24; @@ -67,7 +67,7 @@ function tstore(${name}Slot slot, ${type} value) internal { `; // GENERATE -module.exports = format( +export default format( header.trimEnd(), 'library TransientSlot {', format( diff --git a/scripts/generate/templates/TransientSlotMock.js b/scripts/generate/templates/TransientSlotMock.js index 4807b0cc1ff..06d8a55d8e9 100644 --- a/scripts/generate/templates/TransientSlotMock.js +++ b/scripts/generate/templates/TransientSlotMock.js @@ -1,5 +1,5 @@ -const format = require('../format-lines'); -const { TYPES } = require('./Slot.opts'); +import format from '../format-lines.js'; +import { TYPES } from './Slot.opts.js'; const header = `\ pragma solidity ^0.8.24; @@ -21,7 +21,7 @@ function tstore(bytes32 slot, ${type} value) public { `; // GENERATE -module.exports = format( +export default format( header, 'contract TransientSlotMock is Multicall {', format( diff --git a/scripts/generate/templates/conversion.js b/scripts/generate/templates/conversion.js index c0f55a982e5..5238e047a73 100644 --- a/scripts/generate/templates/conversion.js +++ b/scripts/generate/templates/conversion.js @@ -1,4 +1,4 @@ -function toBytes32(type, value) { +export function toBytes32(type, value) { switch (type) { case 'bytes32': return value; @@ -13,7 +13,7 @@ function toBytes32(type, value) { } } -function fromBytes32(type, value) { +export function fromBytes32(type, value) { switch (type) { case 'bytes32': return value; @@ -27,8 +27,3 @@ function fromBytes32(type, value) { throw new Error(`Conversion from bytes32 to ${type} not supported`); } } - -module.exports = { - toBytes32, - fromBytes32, -}; diff --git a/scripts/get-contracts-metadata.js b/scripts/get-contracts-metadata.js index 030ab5a3d94..8f77589f2b7 100644 --- a/scripts/get-contracts-metadata.js +++ b/scripts/get-contracts-metadata.js @@ -1,10 +1,10 @@ -const fs = require('fs'); -const glob = require('glob'); -const match = require('micromatch'); -const path = require('path'); -const { findAll } = require('solidity-ast/utils'); +import fs from 'fs'; +import path from 'path'; +import { glob } from 'glob'; +import match from 'micromatch'; +import { findAll } from 'solidity-ast/utils.js'; -module.exports = function ( +export function getContractsMetadata( pattern = 'contracts/**/*.sol', skipPatterns = ['contracts/mocks/**/*.sol'], artifacts = [], @@ -13,8 +13,8 @@ module.exports = function ( // definitions with minimal IO operations. const metadata = Object.fromEntries( artifacts.flatMap(artifact => { - const { output: solcOutput } = require(path.resolve(__dirname, '..', artifact)); - return Object.keys(solcOutput.contracts) + const { output: solcOutput } = JSON.parse(fs.readFileSync(path.resolve(import.meta.dirname, '..', artifact))); + return Object.keys(solcOutput?.contracts ?? {}) .filter(source => match.all(source, pattern) && !match.any(source, skipPatterns)) .map(source => [ source, @@ -52,4 +52,4 @@ module.exports = function ( }); return metadata; -}; +} diff --git a/scripts/helpers.js b/scripts/helpers.js index d28c0866d1c..b687e279dde 100644 --- a/scripts/helpers.js +++ b/scripts/helpers.js @@ -1,7 +1,2 @@ -const iterate = require('../test/helpers/iterate'); -const strings = require('../test/helpers/strings'); - -module.exports = { - ...iterate, - ...strings, -}; +export * from '../test/helpers/iterate.js'; +export * from '../test/helpers/strings.js'; diff --git a/scripts/minimize-pragma.js b/scripts/minimize-pragma.js index a4cbf03aa77..69bd47f6014 100755 --- a/scripts/minimize-pragma.js +++ b/scripts/minimize-pragma.js @@ -1,14 +1,14 @@ #!/usr/bin/env node -const fs = require('fs'); -const graphlib = require('graphlib'); -const semver = require('semver'); -const pLimit = require('p-limit').default; -const { hideBin } = require('yargs/helpers'); -const yargs = require('yargs/yargs'); - -const getContractsMetadata = require('./get-contracts-metadata'); -const { versions: allSolcVersions, compile } = require('./solc-versions'); +import fs from 'fs'; +import graphlib from 'graphlib'; +import semver from 'semver'; +import pLimit from 'p-limit'; +import { hideBin } from 'yargs/helpers'; +import yargs from 'yargs/yargs'; + +import { getContractsMetadata } from './get-contracts-metadata.js'; +import { versions as allSolcVersions, compile } from './solc-versions.js'; const { argv: { pattern, skipPatterns, minVersionForContracts, minVersionForInterfaces, concurrency, _: artifacts }, diff --git a/scripts/prepack.sh b/scripts/prepack.sh index 6af10329f66..182af4e5856 100755 --- a/scripts/prepack.sh +++ b/scripts/prepack.sh @@ -17,7 +17,6 @@ env COMPILE_MODE=production npm run compile mkdirp contracts/build/contracts cp artifacts/contracts/**/*.json contracts/build/contracts -rm contracts/build/contracts/*.dbg.json node scripts/remove-ignored-artifacts.js cp README.md contracts/ diff --git a/scripts/remove-ignored-artifacts.js b/scripts/remove-ignored-artifacts.js index e156032b17c..9dd0acfc2bf 100644 --- a/scripts/remove-ignored-artifacts.js +++ b/scripts/remove-ignored-artifacts.js @@ -2,9 +2,9 @@ // This script removes the build artifacts of ignored contracts. -const fs = require('fs'); -const path = require('path'); -const match = require('micromatch'); +import fs from 'fs'; +import path from 'path'; +import match from 'micromatch'; function readJSON(path) { return JSON.parse(fs.readFileSync(path)); @@ -25,14 +25,14 @@ const ignorePatternsSubtrees = ignorePatterns const artifactsDir = 'contracts/build/contracts'; const buildinfo = 'artifacts/build-info'; -const filenames = fs.readdirSync(buildinfo); +const filenames = fs.readdirSync(buildinfo).filter(filename => match.isMatch(filename, '*.output.json')); let n = 0; for (const filename of filenames) { const solcOutput = readJSON(path.join(buildinfo, filename)).output; for (const sourcePath in solcOutput.contracts) { - const ignore = match.any(sourcePath, ignorePatternsSubtrees); + const ignore = match.any(sourcePath.replace(/^project\//, ''), ignorePatternsSubtrees); if (ignore) { for (const contract in solcOutput.contracts[sourcePath]) { fs.unlinkSync(path.join(artifactsDir, contract + '.json')); diff --git a/scripts/solc-versions.js b/scripts/solc-versions.js index cd27a3621e7..17e3771bcb0 100644 --- a/scripts/solc-versions.js +++ b/scripts/solc-versions.js @@ -1,15 +1,14 @@ -const { exec } = require('child_process'); -const semver = require('semver'); -const { range } = require('./helpers'); +import { exec } from 'child_process'; +import semver from 'semver'; +import { range } from './helpers.js'; -module.exports = { - versions: ['0.4.26', '0.5.16', '0.6.12', '0.7.6', '0.8.30'] - .map(semver.parse) - .flatMap(({ major, minor, patch }) => range(patch + 1).map(p => `${major}.${minor}.${p}`)), - compile: (source, version) => - new Promise((resolve, reject) => - exec(`forge build ${source} --use ${version} --out out/solc-${version}`, error => - error ? reject(error) : resolve(), - ), +export const versions = ['0.4.26', '0.5.16', '0.6.12', '0.7.6', '0.8.33'] + .map(semver.parse) + .flatMap(({ major, minor, patch }) => range(patch + 1).map(p => `${major}.${minor}.${p}`)); + +export const compile = (source, version) => + new Promise((resolve, reject) => + exec(`forge build ${source} --use ${version} --out out/solc-${version}`, error => + error ? reject(error) : resolve(), ), -}; + ); diff --git a/scripts/upgradeable/transpile.config.json b/scripts/upgradeable/transpile.config.json new file mode 100644 index 00000000000..db77a1a2985 --- /dev/null +++ b/scripts/upgradeable/transpile.config.json @@ -0,0 +1,19 @@ +{ + "initializablePath": "contracts/proxy/utils/Initializable.sol", + "deleteOriginals": true, + "exclude": [ + "contracts-exposed/**/*", + "contracts/mocks/**/*Proxy*.sol", + "contracts/proxy/**/*Proxy*.sol", + "contracts/proxy/beacon/UpgradeableBeacon.sol" + ], + "publicInitializers": [ + "contracts/access/manager/AccessManager.sol", + "contracts/finance/VestingWallet.sol", + "contracts/governance/TimelockController.sol", + "contracts/metatx/ERC2771Forwarder.sol" + ], + "namespaced": true, + "namespaceExclude": ["contracts/mocks/**/*"], + "peerProject": "@openzeppelin/" +} diff --git a/scripts/upgradeable/transpile.sh b/scripts/upgradeable/transpile.sh index 5e63fc789f4..cb1799bcecc 100644 --- a/scripts/upgradeable/transpile.sh +++ b/scripts/upgradeable/transpile.sh @@ -1,47 +1,19 @@ #!/usr/bin/env bash set -euo pipefail -x +shopt -s extglob VERSION="$(jq -r .version contracts/package.json)" DIRNAME="$(dirname -- "${BASH_SOURCE[0]}")" +# apply patches to the codebase bash "$DIRNAME/patch-apply.sh" sed -i'' -e "s//$VERSION/g" "contracts/package.json" git add contracts/package.json +# run the transpiler npm run clean -npm run compile - -build_info=($(jq -r '.input.sources | keys | if any(test("^contracts/mocks/.*\\bunreachable\\b")) then empty else input_filename end' artifacts/build-info/*)) -build_info_num=${#build_info[@]} - -if [ $build_info_num -ne 1 ]; then - echo "found $build_info_num relevant build info files but expected just 1" - exit 1 -fi - -# -D: delete original and excluded files -# -b: use this build info file -# -i: use included Initializable -# -x: exclude some proxy-related contracts -# -p: emit public initializer -# -n: use namespaces -# -N: exclude from namespaces transformation -# -q: partial transpilation using @openzeppelin/contracts as peer project -npx @openzeppelin/upgrade-safe-transpiler -D \ - -b "$build_info" \ - -i contracts/proxy/utils/Initializable.sol \ - -x 'contracts-exposed/**/*' \ - -x 'contracts/mocks/**/*Proxy*.sol' \ - -x 'contracts/proxy/**/*Proxy*.sol' \ - -x 'contracts/proxy/beacon/UpgradeableBeacon.sol' \ - -p 'contracts/access/manager/AccessManager.sol' \ - -p 'contracts/finance/VestingWallet.sol' \ - -p 'contracts/governance/TimelockController.sol' \ - -p 'contracts/metatx/ERC2771Forwarder.sol' \ - -n \ - -N 'contracts/mocks/**/*' \ - -q '@openzeppelin/' +npx hardhat transpile --settings $DIRNAME/transpile.config.json # create alias to Initializable and UUPSUpgradeable cp $DIRNAME/alias/*.sol contracts/proxy/utils/. diff --git a/scripts/upgradeable/upgradeable.patch b/scripts/upgradeable/upgradeable.patch index 834d4f1ed61..5f2954bae51 100644 --- a/scripts/upgradeable/upgradeable.patch +++ b/scripts/upgradeable/upgradeable.patch @@ -305,8 +305,30 @@ index 2bc45a4b2..a5aa41d21 100644 + return keccak256(bytes(_EIP712Version())); } } +diff --git a/hardhat.config.ts b/hardhat.config.ts +index ba50439b7..6ee16de43 100644 +--- a/hardhat.config.ts ++++ b/hardhat.config.ts +@@ -41,7 +41,7 @@ export default defineConfig({ + hardhatOzContractsHelpers, + ], + paths: { +- sources: argv.src, ++ sources: [ argv.src, 'lib/openzeppelin-contracts/contracts' ], + }, + solidity: { + version: argv.compiler, +@@ -89,7 +89,7 @@ export default defineConfig({ + }, + exposed: { + initializers: true, +- include: ['contracts/**/*.sol'], ++ include: ['{,lib/openzeppelin-contracts/}contracts/**/*.sol'], + exclude: ['**/*WithInit.sol'], + }, + }); diff --git a/package.json b/package.json -index 6f2d411dd..956933f33 100644 +index 0b6f6c268..1bab4415d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ @@ -319,19 +341,22 @@ index 6f2d411dd..956933f33 100644 "keywords": [ "solidity", diff --git a/remappings.txt b/remappings.txt -index 304d1386a..a1cd63bee 100644 +index a6be3bfd6..d20f777f3 100644 --- a/remappings.txt +++ b/remappings.txt -@@ -1 +1,2 @@ +@@ -1,4 +1,5 @@ -@openzeppelin/contracts/=contracts/ +@openzeppelin/contracts-upgradeable/=contracts/ +@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/ + + forge-std=lib/forge-std/src + halmos-cheatcodes=lib/halmos-cheatcodes/src diff --git a/test/account/AccountEIP7702.test.js b/test/account/AccountEIP7702.test.js -index d832e6877..6a0ab4a53 100644 +index dcb2cc862..df4ff523a 100644 --- a/test/account/AccountEIP7702.test.js +++ b/test/account/AccountEIP7702.test.js -@@ -26,8 +26,8 @@ async function fixture() { - +@@ -28,8 +28,8 @@ async function fixture() { + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { - name: 'AccountEIP7702Mock', @@ -342,10 +367,10 @@ index d832e6877..6a0ab4a53 100644 verifyingContract: mock.address, }; diff --git a/test/account/examples/AccountEIP7702WithModulesMock.test.js b/test/account/examples/AccountEIP7702WithModulesMock.test.js -index 86816e55e..de6adc2c5 100644 +index 2369040a2..3fc0a5172 100644 --- a/test/account/examples/AccountEIP7702WithModulesMock.test.js +++ b/test/account/examples/AccountEIP7702WithModulesMock.test.js -@@ -36,8 +36,8 @@ async function fixture() { +@@ -38,8 +38,8 @@ async function fixture() { // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { @@ -357,10 +382,10 @@ index 86816e55e..de6adc2c5 100644 verifyingContract: mock.address, }; diff --git a/test/utils/cryptography/EIP712.test.js b/test/utils/cryptography/EIP712.test.js -index 2b6e7fa97..268e0d29d 100644 +index ab28c4e1b..92e0f368b 100644 --- a/test/utils/cryptography/EIP712.test.js +++ b/test/utils/cryptography/EIP712.test.js -@@ -47,27 +47,6 @@ describe('EIP712', function () { +@@ -50,27 +50,6 @@ describe('EIP712', function () { const rebuildDomain = await getDomain(this.eip712); expect(rebuildDomain).to.be.deep.equal(this.domain); }); diff --git a/solhint.config.js b/solhint.config.cjs similarity index 100% rename from solhint.config.js rename to solhint.config.cjs diff --git a/test/access/AccessControl.behavior.js b/test/access/AccessControl.behavior.js index 52f744759fc..82553942c64 100644 --- a/test/access/AccessControl.behavior.js +++ b/test/access/AccessControl.behavior.js @@ -1,15 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { shouldSupportInterfaces } from '../utils/introspection/SupportsInterface.behavior'; -const time = require('../helpers/time'); +export const DEFAULT_ADMIN_ROLE = ethers.ZeroHash; -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); - -const DEFAULT_ADMIN_ROLE = ethers.ZeroHash; const ROLE = ethers.id('ROLE'); const OTHER_ROLE = ethers.id('OTHER_ROLE'); -function shouldBehaveLikeAccessControl() { +export function shouldBehaveLikeAccessControl() { beforeEach(async function () { [this.authorized, this.other, this.otherAdmin] = this.accounts; }); @@ -224,7 +222,7 @@ function shouldBehaveLikeAccessControl() { }); } -function shouldBehaveLikeAccessControlEnumerable() { +export function shouldBehaveLikeAccessControlEnumerable() { beforeEach(async function () { [this.authorized, this.other, this.otherAdmin, this.otherAuthorized] = this.accounts; }); @@ -261,13 +259,13 @@ function shouldBehaveLikeAccessControlEnumerable() { }); } -function shouldBehaveLikeAccessControlDefaultAdminRules() { - shouldSupportInterfaces(['AccessControlDefaultAdminRules']); - +export function shouldBehaveLikeAccessControlDefaultAdminRules() { beforeEach(async function () { [this.newDefaultAdmin, this.other] = this.accounts; }); + shouldSupportInterfaces(['AccessControlDefaultAdminRules']); + for (const getter of ['owner', 'defaultAdmin']) { describe(`${getter}()`, function () { it('has a default set to the initial default admin', async function () { @@ -281,7 +279,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); // Wait for acceptance - await time.increaseBy.timestamp(this.delay + 1n, false); + await this.helpers.time.increaseBy.timestamp(this.delay + 1n, false); await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); const value = await this.mock[getter](); @@ -310,7 +308,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`returns pending admin and schedule ${tag} it passes if not accepted`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdmin(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule); + await this.helpers.time.increaseTo.timestamp(firstSchedule + fromSchedule); const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); expect(newAdmin).to.equal(this.newDefaultAdmin); @@ -321,7 +319,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it('returns 0 after schedule passes and the transfer was accepted', async function () { // Wait after schedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdmin(); - await time.increaseTo.timestamp(firstSchedule + 1n, false); + await this.helpers.time.increaseTo.timestamp(firstSchedule + 1n, false); // Accepts await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); @@ -353,7 +351,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`returns ${delayTag} delay ${tag} delay schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(schedule + fromSchedule); + await this.helpers.time.increaseTo.timestamp(schedule + fromSchedule); const currentDelay = await this.mock.defaultAdminDelay(); expect(currentDelay).to.equal(expectNew ? newDelay : this.delay); @@ -384,7 +382,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`returns ${delayTag} delay ${tag} delay schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule); + await this.helpers.time.increaseTo.timestamp(firstSchedule + fromSchedule); const { newDelay, schedule } = await this.mock.pendingDefaultAdminDelay(); expect(newDelay).to.equal(expectedDelay); @@ -396,7 +394,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('defaultAdminDelayIncreaseWait()', function () { it('should return 5 days (default)', async function () { - expect(await this.mock.defaultAdminDelayIncreaseWait()).to.equal(time.duration.days(5)); + expect(await this.mock.defaultAdminDelayIncreaseWait()).to.equal(this.helpers.time.duration.days(5)); }); }); @@ -435,10 +433,10 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('when there is no pending delay nor pending admin transfer', function () { it('should set pending default admin and schedule', async function () { - const nextBlockTimestamp = (await time.clock.timestamp()) + 1n; + const nextBlockTimestamp = (await this.helpers.time.clock.timestamp()) + 1n; const acceptSchedule = nextBlockTimestamp + this.delay; - await time.increaseTo.timestamp(nextBlockTimestamp, false); // set timestamp but don't mine the block yet + await this.helpers.time.increaseTo.timestamp(nextBlockTimestamp, false); // set timestamp but don't mine the block yet await expect(this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin)) .to.emit(this.mock, 'DefaultAdminTransferScheduled') .withArgs(this.newDefaultAdmin, acceptSchedule); @@ -452,7 +450,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('when there is a pending admin transfer', function () { beforeEach('sets a pending default admin transfer', async function () { await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); - this.acceptSchedule = (await time.clock.timestamp()) + this.delay; + this.acceptSchedule = (await this.helpers.time.clock.timestamp()) + this.delay; }); for (const [fromSchedule, tag] of [ @@ -462,14 +460,14 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { ]) { it(`should be able to begin a transfer again ${tag} acceptSchedule passes`, async function () { // Wait until schedule + fromSchedule - await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); + await this.helpers.time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); // defaultAdmin changes its mind and begins again to another address await expect(this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.other)).to.emit( this.mock, 'DefaultAdminTransferCanceled', // Cancellation is always emitted since it was never accepted ); - const newSchedule = (await time.clock.timestamp()) + this.delay; + const newSchedule = (await this.helpers.time.clock.timestamp()) + this.delay; const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); expect(newAdmin).to.equal(this.other); expect(schedule).to.equal(newSchedule); @@ -478,7 +476,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it('should not emit a cancellation event if the new default admin accepted', async function () { // Wait until the acceptSchedule has passed - await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); + await this.helpers.time.increaseTo.timestamp(this.acceptSchedule + 1n, false); // Accept and restart await this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer(); @@ -490,7 +488,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); describe('when there is a pending delay', function () { - const newDelay = time.duration.hours(3); + const newDelay = 3n * 3600n; beforeEach('schedule a delay change', async function () { await this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(newDelay); @@ -507,7 +505,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { } delay and apply it to next default admin transfer schedule ${schedulePassed} effectSchedule passed`, async function () { // Wait until the expected fromSchedule time const nextBlockTimestamp = this.effectSchedule + fromSchedule; - await time.increaseTo.timestamp(nextBlockTimestamp, false); + await this.helpers.time.increaseTo.timestamp(nextBlockTimestamp, false); // Start the new default admin transfer and get its schedule const expectedDelay = expectNewDelay ? newDelay : this.delay; @@ -528,11 +526,11 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('accepts transfer admin', function () { beforeEach(async function () { await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); - this.acceptSchedule = (await time.clock.timestamp()) + this.delay; + this.acceptSchedule = (await this.helpers.time.clock.timestamp()) + this.delay; }); it('should revert if caller is not pending default admin', async function () { - await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); + await this.helpers.time.increaseTo.timestamp(this.acceptSchedule + 1n, false); await expect(this.mock.connect(this.other).acceptDefaultAdminTransfer()) .to.be.revertedWithCustomError(this.mock, 'AccessControlInvalidDefaultAdmin') .withArgs(this.other); @@ -540,7 +538,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('when caller is pending default admin and delay has passed', function () { beforeEach(async function () { - await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); + await this.helpers.time.increaseTo.timestamp(this.acceptSchedule + 1n, false); }); it('accepts a transfer and changes default admin', async function () { @@ -569,7 +567,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { [0n, 'equal'], ]) { it(`should revert if block.timestamp is ${tag} to schedule`, async function () { - await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); + await this.helpers.time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); await expect(this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer()) .to.be.revertedWithCustomError(this.mock, 'AccessControlEnforcedDefaultAdminDelay') .withArgs(this.acceptSchedule); @@ -588,7 +586,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('when there is a pending default admin transfer', function () { beforeEach(async function () { await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(this.newDefaultAdmin); - this.acceptSchedule = (await time.clock.timestamp()) + this.delay; + this.acceptSchedule = (await this.helpers.time.clock.timestamp()) + this.delay; }); for (const [fromSchedule, tag] of [ @@ -598,7 +596,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { ]) { it(`resets pending default admin and schedule ${tag} transfer schedule passes`, async function () { // Advance until passed delay - await time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); + await this.helpers.time.increaseTo.timestamp(this.acceptSchedule + fromSchedule, false); await expect(this.mock.connect(this.defaultAdmin).cancelDefaultAdminTransfer()).to.emit( this.mock, @@ -615,7 +613,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { await this.mock.connect(this.defaultAdmin).cancelDefaultAdminTransfer(); // Advance until passed delay - await time.increaseTo.timestamp(this.acceptSchedule + 1n, false); + await this.helpers.time.increaseTo.timestamp(this.acceptSchedule + 1n, false); // Previous pending default admin should not be able to accept after cancellation. await expect(this.mock.connect(this.newDefaultAdmin).acceptDefaultAdminTransfer()) @@ -641,18 +639,18 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('renounces admin', function () { beforeEach(async function () { await this.mock.connect(this.defaultAdmin).beginDefaultAdminTransfer(ethers.ZeroAddress); - this.expectedSchedule = (await time.clock.timestamp()) + this.delay; + this.expectedSchedule = (await this.helpers.time.clock.timestamp()) + this.delay; }); it('reverts if caller is not default admin', async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); + await this.helpers.time.increaseBy.timestamp(this.delay + 1n, false); await expect( this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.other), ).to.be.revertedWithCustomError(this.mock, 'AccessControlBadConfirmation'); }); it("renouncing the admin role when not an admin doesn't affect the schedule", async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); + await this.helpers.time.increaseBy.timestamp(this.delay + 1n, false); await this.mock.connect(this.other).renounceRole(DEFAULT_ADMIN_ROLE, this.other); const { newAdmin, schedule } = await this.mock.pendingDefaultAdmin(); @@ -661,7 +659,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); it('keeps defaultAdmin consistent with hasRole if another non-defaultAdmin user renounces the DEFAULT_ADMIN_ROLE', async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); + await this.helpers.time.increaseBy.timestamp(this.delay + 1n, false); // This passes because it's a noop await this.mock.connect(this.other).renounceRole(DEFAULT_ADMIN_ROLE, this.other); @@ -671,7 +669,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); it('renounces role', async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); + await this.helpers.time.increaseBy.timestamp(this.delay + 1n, false); await expect(this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)) .to.emit(this.mock, 'RoleRevoked') .withArgs(DEFAULT_ADMIN_ROLE, this.defaultAdmin, this.defaultAdmin); @@ -686,7 +684,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); it('allows to recover access using the internal _grantRole', async function () { - await time.increaseBy.timestamp(this.delay + 1n, false); + await this.helpers.time.increaseBy.timestamp(this.delay + 1n, false); await this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin); await expect(this.mock.connect(this.defaultAdmin).$_grantRole(DEFAULT_ADMIN_ROLE, this.other)) @@ -700,7 +698,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { [0n, 'equal'], ]) { it(`reverts if block.timestamp is ${tag} to schedule`, async function () { - await time.increaseBy.timestamp(this.delay + fromSchedule, false); + await this.helpers.time.increaseBy.timestamp(this.delay + fromSchedule, false); await expect(this.mock.connect(this.defaultAdmin).renounceRole(DEFAULT_ADMIN_ROLE, this.defaultAdmin)) .to.be.revertedWithCustomError(this.mock, 'AccessControlEnforcedDefaultAdminDelay') .withArgs(this.expectedSchedule); @@ -711,15 +709,15 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('changes delay', function () { it('reverts if called by non default admin accounts', async function () { - await expect(this.mock.connect(this.other).changeDefaultAdminDelay(time.duration.hours(4))) + await expect(this.mock.connect(this.other).changeDefaultAdminDelay(this.helpers.time.duration.hours(4))) .to.be.revertedWithCustomError(this.mock, 'AccessControlUnauthorizedAccount') .withArgs(this.other, DEFAULT_ADMIN_ROLE); }); for (const [delayDifference, delayChangeType] of [ - [time.duration.hours(-1), 'decreased'], - [time.duration.hours(1), 'increased'], - [time.duration.days(5), 'increased to more than 5 days'], + [-3600n, 'decreased'], + [3600n, 'increased'], + [5n * 86400n, 'increased to more than 5 days'], ]) { describe(`when the delay is ${delayChangeType}`, function () { beforeEach(function () { @@ -732,10 +730,10 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { const minWait = capWait < this.newDefaultAdminDelay ? capWait : this.newDefaultAdminDelay; const changeDelay = this.newDefaultAdminDelay <= this.delay ? this.delay - this.newDefaultAdminDelay : minWait; - const nextBlockTimestamp = (await time.clock.timestamp()) + 1n; + const nextBlockTimestamp = (await this.helpers.time.clock.timestamp()) + 1n; const effectSchedule = nextBlockTimestamp + changeDelay; - await time.increaseTo.timestamp(nextBlockTimestamp, false); + await this.helpers.time.increaseTo.timestamp(nextBlockTimestamp, false); // Begins the change await expect(this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(this.newDefaultAdminDelay)) @@ -764,10 +762,10 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); const nextBlockTimestamp = firstSchedule + fromSchedule; - await time.increaseTo.timestamp(nextBlockTimestamp, false); + await this.helpers.time.increaseTo.timestamp(nextBlockTimestamp, false); // Calculate expected values - const anotherNewDefaultAdminDelay = this.newDefaultAdminDelay + time.duration.hours(2); + const anotherNewDefaultAdminDelay = this.newDefaultAdminDelay + this.helpers.time.duration.hours(2); const capWait = await this.mock.defaultAdminDelayIncreaseWait(); const minWait = capWait < anotherNewDefaultAdminDelay ? capWait : anotherNewDefaultAdminDelay; const effectSchedule = nextBlockTimestamp + minWait; @@ -787,10 +785,10 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`should ${emit} a cancellation event ${tag} the delay schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); + await this.helpers.time.increaseTo.timestamp(firstSchedule + fromSchedule, false); // Default admin changes its mind and begins another delay change - const anotherNewDefaultAdminDelay = this.newDefaultAdminDelay + time.duration.hours(2); + const anotherNewDefaultAdminDelay = this.newDefaultAdminDelay + this.helpers.time.duration.hours(2); const expected = expect( this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(anotherNewDefaultAdminDelay), @@ -816,7 +814,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { describe('when there is a pending delay', function () { beforeEach('set pending delay', async function () { - await this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(time.duration.hours(12)); + await this.mock.connect(this.defaultAdmin).changeDefaultAdminDelay(this.helpers.time.duration.hours(12)); }); for (const [fromSchedule, tag] of [ @@ -829,7 +827,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`resets pending delay and schedule ${tag} delay change schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); + await this.helpers.time.increaseTo.timestamp(firstSchedule + fromSchedule, false); await this.mock.connect(this.defaultAdmin).rollbackDefaultAdminDelay(); @@ -842,7 +840,7 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { it(`should ${emit} a cancellation event ${tag} the delay schedule passes`, async function () { // Wait until schedule + fromSchedule const { schedule: firstSchedule } = await this.mock.pendingDefaultAdminDelay(); - await time.increaseTo.timestamp(firstSchedule + fromSchedule, false); + await this.helpers.time.increaseTo.timestamp(firstSchedule + fromSchedule, false); const expected = expect(this.mock.connect(this.defaultAdmin).rollbackDefaultAdminDelay()); if (passed) { @@ -865,10 +863,3 @@ function shouldBehaveLikeAccessControlDefaultAdminRules() { }); }); } - -module.exports = { - DEFAULT_ADMIN_ROLE, - shouldBehaveLikeAccessControl, - shouldBehaveLikeAccessControlEnumerable, - shouldBehaveLikeAccessControlDefaultAdminRules, -}; diff --git a/test/access/AccessControl.test.js b/test/access/AccessControl.test.js index 5c70cdc6d7f..843b01658bb 100644 --- a/test/access/AccessControl.test.js +++ b/test/access/AccessControl.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { DEFAULT_ADMIN_ROLE, shouldBehaveLikeAccessControl } from './AccessControl.behavior'; -const { DEFAULT_ADMIN_ROLE, shouldBehaveLikeAccessControl } = require('./AccessControl.behavior'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { const [defaultAdmin, ...accounts] = await ethers.getSigners(); @@ -12,7 +16,8 @@ async function fixture() { describe('AccessControl', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + // write connection to this for use in fixtures + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeAccessControl(); diff --git a/test/access/Ownable.test.js b/test/access/Ownable.test.js index 2d9b561a1dc..6ce733dde59 100644 --- a/test/access/Ownable.test.js +++ b/test/access/Ownable.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [owner, other] = await ethers.getSigners(); diff --git a/test/access/Ownable2Step.test.js b/test/access/Ownable2Step.test.js index 5620a249132..ae3c37dff6c 100644 --- a/test/access/Ownable2Step.test.js +++ b/test/access/Ownable2Step.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [owner, accountA, accountB] = await ethers.getSigners(); diff --git a/test/access/extensions/AccessControlDefaultAdminRules.test.js b/test/access/extensions/AccessControlDefaultAdminRules.test.js index 48036fd9bc2..9953bed97ff 100644 --- a/test/access/extensions/AccessControlDefaultAdminRules.test.js +++ b/test/access/extensions/AccessControlDefaultAdminRules.test.js @@ -1,13 +1,16 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const time = require('../../helpers/time'); - -const { +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeAccessControl, shouldBehaveLikeAccessControlDefaultAdminRules, -} = require('../AccessControl.behavior'); +} from '../AccessControl.behavior'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { const delay = time.duration.hours(10); @@ -18,7 +21,7 @@ async function fixture() { describe('AccessControlDefaultAdminRules', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); it('initial admin not zero', async function () { diff --git a/test/access/extensions/AccessControlEnumerable.test.js b/test/access/extensions/AccessControlEnumerable.test.js index ea1a8c46f2c..1c9ec49047a 100644 --- a/test/access/extensions/AccessControlEnumerable.test.js +++ b/test/access/extensions/AccessControlEnumerable.test.js @@ -1,11 +1,15 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { +import { network } from 'hardhat'; +import { DEFAULT_ADMIN_ROLE, shouldBehaveLikeAccessControl, shouldBehaveLikeAccessControlEnumerable, -} = require('../AccessControl.behavior'); +} from '../AccessControl.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { const [defaultAdmin, ...accounts] = await ethers.getSigners(); @@ -16,7 +20,7 @@ async function fixture() { describe('AccessControlEnumerable', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeAccessControl(); diff --git a/test/access/manager/AccessManaged.test.js b/test/access/manager/AccessManaged.test.js index d666b5e6dcc..52613231aa3 100644 --- a/test/access/manager/AccessManaged.test.js +++ b/test/access/manager/AccessManaged.test.js @@ -1,9 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; -const { impersonate } = require('../../helpers/account'); -const time = require('../../helpers/time'); +const { + ethers, + helpers: { impersonate, time }, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [admin, roleMember, other] = await ethers.getSigners(); @@ -60,7 +62,7 @@ describe('AccessManaged', function () { it('panics in short calldata', async function () { // We avoid adding the `restricted` modifier to the fallback function because other tests may depend on it // being accessible without restrictions. We check for the internal `_checkCanCall` instead. - await expect(this.managed.$_checkCanCall(this.roleMember, '0x1234')).to.be.reverted; + await expect(this.managed.$_checkCanCall(this.roleMember, '0x1234')).to.be.revert(ethers); }); describe('when role is granted with execution delay', function () { diff --git a/test/access/manager/AccessManager.behavior.js b/test/access/manager/AccessManager.behavior.js index 319a8e2c05a..20bde610c93 100644 --- a/test/access/manager/AccessManager.behavior.js +++ b/test/access/manager/AccessManager.behavior.js @@ -1,6 +1,5 @@ -const { expect } = require('chai'); - -const { +import { expect } from 'chai'; +import { LIKE_COMMON_IS_EXECUTING, LIKE_COMMON_GET_ACCESS, LIKE_COMMON_SCHEDULABLE, @@ -9,14 +8,14 @@ const { testAsDelayedOperation, testAsCanCall, testAsHasRole, -} = require('./AccessManager.predicate'); +} from './AccessManager.predicate'; // ============ ADMIN OPERATION ============ /** * @requires this.{manager,roles,calldata,role} */ -function shouldBehaveLikeDelayedAdminOperation() { +export function shouldBehaveLikeDelayedAdminOperation() { const getAccessPath = LIKE_COMMON_GET_ACCESS; testAsDelayedOperation.mineDelay = true; getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasAnExecutionDelay.afterGrantDelay = @@ -55,7 +54,7 @@ function shouldBehaveLikeDelayedAdminOperation() { /** * @requires this.{manager,roles,calldata,role} */ -function shouldBehaveLikeNotDelayedAdminOperation() { +export function shouldBehaveLikeNotDelayedAdminOperation() { const getAccessPath = LIKE_COMMON_GET_ACCESS; testAsDelayedOperation.mineDelay = true; getAccessPath.requiredRoleIsGranted.roleGrantingIsDelayed.callerHasAnExecutionDelay.afterGrantDelay = @@ -94,7 +93,7 @@ function shouldBehaveLikeNotDelayedAdminOperation() { /** * @requires this.{manager,roles,calldata,role} */ -function shouldBehaveLikeRoleAdminOperation(roleAdmin) { +export function shouldBehaveLikeRoleAdminOperation(roleAdmin) { const getAccessPath = LIKE_COMMON_GET_ACCESS; function afterGrantDelay() { @@ -134,7 +133,7 @@ function shouldBehaveLikeRoleAdminOperation(roleAdmin) { /** * @requires this.{manager,roles,calldata,role} */ -function shouldBehaveLikeAManagedRestrictedOperation() { +export function shouldBehaveLikeAManagedRestrictedOperation() { function revertUnauthorized() { it('reverts as AccessManagedUnauthorized', async function () { await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) @@ -191,7 +190,7 @@ function shouldBehaveLikeAManagedRestrictedOperation() { /** * @requires this.{target,manager,roles,calldata,role} */ -function shouldBehaveLikeASelfRestrictedOperation() { +export function shouldBehaveLikeASelfRestrictedOperation() { function revertUnauthorized() { it('reverts as AccessManagerUnauthorizedAccount', async function () { await expect(this.caller.sendTransaction({ to: this.target, data: this.calldata })) @@ -242,11 +241,3 @@ function shouldBehaveLikeASelfRestrictedOperation() { }, }); } - -module.exports = { - shouldBehaveLikeDelayedAdminOperation, - shouldBehaveLikeNotDelayedAdminOperation, - shouldBehaveLikeRoleAdminOperation, - shouldBehaveLikeAManagedRestrictedOperation, - shouldBehaveLikeASelfRestrictedOperation, -}; diff --git a/test/access/manager/AccessManager.predicate.js b/test/access/manager/AccessManager.predicate.js index 2c9daf9e4f6..8b281294b3e 100644 --- a/test/access/manager/AccessManager.predicate.js +++ b/test/access/manager/AccessManager.predicate.js @@ -1,14 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { setStorageAt } = require('@nomicfoundation/hardhat-network-helpers'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; -const { EXECUTION_ID_STORAGE_SLOT, EXPIRATION, prepareOperation } = require('../../helpers/access-manager'); -const { impersonate } = require('../../helpers/account'); -const time = require('../../helpers/time'); +import { EXECUTION_ID_STORAGE_SLOT, EXPIRATION, prepareOperation } from '../../helpers/access-manager'; // ============ COMMON PREDICATES ============ -const LIKE_COMMON_IS_EXECUTING = { +export const LIKE_COMMON_IS_EXECUTING = { executing() { it('succeeds', async function () { await this.caller.sendTransaction({ to: this.target, data: this.calldata }); @@ -23,7 +20,7 @@ const LIKE_COMMON_IS_EXECUTING = { }, }; -const LIKE_COMMON_GET_ACCESS = { +export const LIKE_COMMON_GET_ACCESS = { requiredRoleIsGranted: { roleGrantingIsDelayed: { callerHasAnExecutionDelay: { @@ -77,7 +74,7 @@ const LIKE_COMMON_GET_ACCESS = { }, }; -const LIKE_COMMON_SCHEDULABLE = { +export const LIKE_COMMON_SCHEDULABLE = { scheduled: { before() { it('reverts as AccessManagerNotReady', async function () { @@ -117,7 +114,7 @@ const LIKE_COMMON_SCHEDULABLE = { /** * @requires this.{manager,target} */ -function testAsClosable({ closed, open }) { +export function testAsClosable({ closed, open }) { describe('when the manager is closed', function () { beforeEach('close', async function () { await this.manager.$_setTargetClosed(this.target, true); @@ -140,15 +137,15 @@ function testAsClosable({ closed, open }) { /** * @requires this.{delay} */ -function testAsDelay(type, { before, after }) { +export function testAsDelay(type, { before, after }) { beforeEach('define timestamp when delay takes effect', async function () { - const timestamp = await time.clock.timestamp(); + const timestamp = await this.helpers.time.clock.timestamp(); this.delayEffect = timestamp + this.delay; }); describe(`when ${type} delay has not taken effect yet`, function () { beforeEach(`set next block timestamp before ${type} takes effect`, async function () { - await time.increaseTo.timestamp(this.delayEffect - 1n, !!before.mineDelay); + await this.helpers.time.increaseTo.timestamp(this.delayEffect - 1n, !!before.mineDelay); }); before(); @@ -156,7 +153,7 @@ function testAsDelay(type, { before, after }) { describe(`when ${type} delay has taken effect`, function () { beforeEach(`set next block timestamp when ${type} takes effect`, async function () { - await time.increaseTo.timestamp(this.delayEffect, !!after.mineDelay); + await this.helpers.time.increaseTo.timestamp(this.delayEffect, !!after.mineDelay); }); after(); @@ -168,14 +165,13 @@ function testAsDelay(type, { before, after }) { /** * @requires this.{manager,scheduleIn,caller,target,calldata} */ -function testAsSchedulableOperation({ scheduled: { before, after, expired }, notScheduled }) { +export function testAsSchedulableOperation({ scheduled: { before, after, expired }, notScheduled }) { describe('when operation is scheduled', function () { beforeEach('schedule operation', async function () { if (this.caller.target) { - await impersonate(this.caller.target); - this.caller = await ethers.getSigner(this.caller.target); + this.caller = await this.helpers.impersonate(this.caller.target); } - const { operationId, schedule } = await prepareOperation(this.manager, { + const { operationId, schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -187,9 +183,9 @@ function testAsSchedulableOperation({ scheduled: { before, after, expired }, not describe('when operation is not ready for execution', function () { beforeEach('set next block time before operation is ready', async function () { - this.scheduledAt = await time.clock.timestamp(); + this.scheduledAt = await this.helpers.time.clock.timestamp(); const schedule = await this.manager.getSchedule(this.operationId); - await time.increaseTo.timestamp(schedule - 1n, !!before.mineDelay); + await this.helpers.time.increaseTo.timestamp(schedule - 1n, !!before.mineDelay); }); before(); @@ -197,9 +193,9 @@ function testAsSchedulableOperation({ scheduled: { before, after, expired }, not describe('when operation is ready for execution', function () { beforeEach('set next block time when operation is ready for execution', async function () { - this.scheduledAt = await time.clock.timestamp(); + this.scheduledAt = await this.helpers.time.clock.timestamp(); const schedule = await this.manager.getSchedule(this.operationId); - await time.increaseTo.timestamp(schedule, !!after.mineDelay); + await this.helpers.time.increaseTo.timestamp(schedule, !!after.mineDelay); }); after(); @@ -207,9 +203,9 @@ function testAsSchedulableOperation({ scheduled: { before, after, expired }, not describe('when operation has expired', function () { beforeEach('set next block time when operation expired', async function () { - this.scheduledAt = await time.clock.timestamp(); + this.scheduledAt = await this.helpers.time.clock.timestamp(); const schedule = await this.manager.getSchedule(this.operationId); - await time.increaseTo.timestamp(schedule + EXPIRATION, !!expired.mineDelay); + await this.helpers.time.increaseTo.timestamp(schedule + EXPIRATION, !!expired.mineDelay); }); expired(); @@ -231,13 +227,12 @@ function testAsSchedulableOperation({ scheduled: { before, after, expired }, not /** * @requires this.{manager,roles,target,calldata} */ -function testAsRestrictedOperation({ callerIsTheManager: { executing, notExecuting }, callerIsNotTheManager }) { +export function testAsRestrictedOperation({ callerIsTheManager: { executing, notExecuting }, callerIsNotTheManager }) { describe('when the call comes from the manager (msg.sender == manager)', function () { beforeEach('define caller as manager', async function () { this.caller = this.manager; if (this.caller.target) { - await impersonate(this.caller.target); - this.caller = await ethers.getSigner(this.caller.target); + this.caller = await this.helpers.impersonate(this.caller.target); } }); @@ -249,7 +244,7 @@ function testAsRestrictedOperation({ callerIsTheManager: { executing, notExecuti [this.target.target, this.calldata.substring(0, 10)], ), ); - await setStorageAt(this.manager.target, EXECUTION_ID_STORAGE_SLOT, executionId); + await this.networkHelpers.setStorageAt(this.manager.target, EXECUTION_ID_STORAGE_SLOT, executionId); }); executing(); @@ -270,11 +265,11 @@ function testAsRestrictedOperation({ callerIsTheManager: { executing, notExecuti /** * @requires this.{manager,scheduleIn,caller,target,calldata,executionDelay} */ -function testAsDelayedOperation() { +export function testAsDelayedOperation() { describe('with operation delay', function () { describe('when operation delay is greater than execution delay', function () { beforeEach('set operation delay', async function () { - this.operationDelay = this.executionDelay + time.duration.hours(1); + this.operationDelay = this.executionDelay + this.helpers.time.duration.hours(1); await this.manager.$_setTargetAdminDelay(this.operationDelayTarget ?? this.target, this.operationDelay); this.scheduleIn = this.operationDelay; // For testAsSchedulableOperation }); @@ -284,7 +279,7 @@ function testAsDelayedOperation() { describe('when operation delay is shorter than execution delay', function () { beforeEach('set operation delay', async function () { - this.operationDelay = this.executionDelay - time.duration.hours(1); + this.operationDelay = this.executionDelay - this.helpers.time.duration.hours(1); await this.manager.$_setTargetAdminDelay(this.operationDelayTarget ?? this.target, this.operationDelay); this.scheduleIn = this.executionDelay; // For testAsSchedulableOperation }); @@ -309,7 +304,7 @@ function testAsDelayedOperation() { /** * @requires this.{manager,roles,role,target,calldata} */ -function testAsCanCall({ +export function testAsCanCall({ closed, open: { callerIsTheManager, @@ -335,7 +330,7 @@ function testAsCanCall({ /** * @requires this.{target,calldata,roles,role} */ -function testAsHasRole({ publicRoleIsRequired, specificRoleIsRequired }) { +export function testAsHasRole({ publicRoleIsRequired, specificRoleIsRequired }) { describe('when the function requires the caller to be granted with the PUBLIC_ROLE', function () { beforeEach('set target function role as PUBLIC_ROLE', async function () { this.role = this.roles.PUBLIC; @@ -361,7 +356,7 @@ function testAsHasRole({ publicRoleIsRequired, specificRoleIsRequired }) { /** * @requires this.{manager,role,caller} */ -function testAsGetAccess({ +export function testAsGetAccess({ requiredRoleIsGranted: { roleGrantingIsDelayed: { // Because both grant and execution delay are set within the same $_grantRole call @@ -379,13 +374,13 @@ function testAsGetAccess({ describe('when the required role is granted to the caller', function () { describe('when role granting is delayed', function () { beforeEach('define delay', function () { - this.grantDelay = time.duration.minutes(3); + this.grantDelay = this.helpers.time.duration.minutes(3); this.delay = this.grantDelay; // For testAsDelay }); describe('when caller has an execution delay', function () { beforeEach('set role and delay', async function () { - this.executionDelay = time.duration.hours(10); + this.executionDelay = this.helpers.time.duration.hours(10); this.delay = this.grantDelay; await this.manager.$_grantRole(this.role.id, this.caller, this.grantDelay, this.executionDelay); }); @@ -410,7 +405,7 @@ function testAsGetAccess({ describe('when caller has an execution delay', function () { beforeEach('set role and delay', async function () { - this.executionDelay = time.duration.hours(10); + this.executionDelay = this.helpers.time.duration.hours(10); await this.manager.$_grantRole(this.role.id, this.caller, this.grantDelay, this.executionDelay); }); @@ -440,17 +435,3 @@ function testAsGetAccess({ requiredRoleIsNotGranted(); }); } - -module.exports = { - LIKE_COMMON_IS_EXECUTING, - LIKE_COMMON_GET_ACCESS, - LIKE_COMMON_SCHEDULABLE, - testAsClosable, - testAsDelay, - testAsSchedulableOperation, - testAsRestrictedOperation, - testAsDelayedOperation, - testAsCanCall, - testAsHasRole, - testAsGetAccess, -}; diff --git a/test/access/manager/AccessManager.test.js b/test/access/manager/AccessManager.test.js index 79536d69a2a..cd383277f59 100644 --- a/test/access/manager/AccessManager.test.js +++ b/test/access/manager/AccessManager.test.js @@ -1,13 +1,9 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT48 } from '../../helpers/constants'; +import { selector } from '../../helpers/methods'; -const { impersonate } = require('../../helpers/account'); -const { MAX_UINT48 } = require('../../helpers/constants'); -const { selector } = require('../../helpers/methods'); -const time = require('../../helpers/time'); - -const { +import { buildBaseRoles, formatAccess, EXPIRATION, @@ -16,17 +12,17 @@ const { CONSUMING_SCHEDULE_STORAGE_SLOT, prepareOperation, hashOperation, -} = require('../../helpers/access-manager'); +} from '../../helpers/access-manager'; -const { +import { shouldBehaveLikeDelayedAdminOperation, shouldBehaveLikeNotDelayedAdminOperation, shouldBehaveLikeRoleAdminOperation, shouldBehaveLikeAManagedRestrictedOperation, shouldBehaveLikeASelfRestrictedOperation, -} = require('./AccessManager.behavior'); +} from './AccessManager.behavior'; -const { +import { LIKE_COMMON_SCHEDULABLE, testAsClosable, testAsDelay, @@ -34,7 +30,14 @@ const { testAsCanCall, testAsHasRole, testAsGetAccess, -} = require('./AccessManager.predicate'); +} from './AccessManager.predicate'; + +const connection = await network.create(); +const { + ethers, + helpers: { impersonate, time }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { const [admin, roleAdmin, roleGuardian, member, user, other] = await ethers.getSigners(); @@ -99,7 +102,7 @@ async function fixture() { // defined as constants. describe('AccessManager', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); describe('during construction', function () { @@ -735,7 +738,7 @@ describe('AccessManager', function () { this.calldata = this.target.interface.encodeFunctionData(fnRestricted, []); this.delay = time.duration.days(10); - const { operationId, schedule } = await prepareOperation(this.manager, { + const { operationId, schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -1810,7 +1813,7 @@ describe('AccessManager', function () { testAsCanCall({ closed() { it('reverts as AccessManagerUnauthorizedCall', async function () { - const { schedule } = await prepareOperation(this.manager, { + const { schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -1828,7 +1831,7 @@ describe('AccessManager', function () { }, notExecuting() { it('reverts as AccessManagerUnauthorizedCall', async function () { - const { schedule } = await prepareOperation(this.manager, { + const { schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -1890,7 +1893,7 @@ describe('AccessManager', function () { roleGrantingIsNotDelayed: { callerHasAnExecutionDelay() { it('succeeds', async function () { - const { schedule } = await prepareOperation(this.manager, { + const { schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -1912,7 +1915,7 @@ describe('AccessManager', function () { }, requiredRoleIsNotGranted() { it('reverts as AccessManagerUnauthorizedCall', async function () { - const { schedule } = await prepareOperation(this.manager, { + const { schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -1930,7 +1933,7 @@ describe('AccessManager', function () { }); it('schedules an operation at the specified execution date if it is larger than caller execution delay', async function () { - const { operationId, scheduledAt, schedule } = await prepareOperation(this.manager, { + const { operationId, scheduledAt, schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -1966,7 +1969,7 @@ describe('AccessManager', function () { expect(await this.manager.getNonce(expectedOperationId)).to.equal('0'); // Schedule - const op1 = await prepareOperation(this.manager, { + const op1 = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -1985,7 +1988,7 @@ describe('AccessManager', function () { expect(await this.manager.getNonce(expectedOperationId)).to.equal('1'); // Schedule again - const op2 = await prepareOperation(this.manager, { + const op2 = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -2004,7 +2007,7 @@ describe('AccessManager', function () { const executionDelay = time.duration.weeks(1) + this.delay; await this.manager.$_grantRole(this.role.id, this.caller, 0, executionDelay); - const { schedule } = await prepareOperation(this.manager, { + const { schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -2017,7 +2020,7 @@ describe('AccessManager', function () { }); it('reverts if an operation is already schedule', async function () { - const op1 = await prepareOperation(this.manager, { + const op1 = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -2026,7 +2029,7 @@ describe('AccessManager', function () { await op1.schedule(); - const op2 = await prepareOperation(this.manager, { + const op2 = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -2042,28 +2045,28 @@ describe('AccessManager', function () { const calldata = '0x1234'; // 2 bytes // Managed contract - const op1 = await prepareOperation(this.manager, { + const op1 = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: calldata, delay: this.delay, }); - await expect(op1.schedule()).to.be.revertedWithoutReason(); + await expect(op1.schedule()).to.be.revertedWithoutReason(ethers); // Manager contract - const op2 = await prepareOperation(this.manager, { + const op2 = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.manager, calldata: calldata, delay: this.delay, }); - await expect(op2.schedule()).to.be.revertedWithoutReason(); + await expect(op2.schedule()).to.be.revertedWithoutReason(ethers); }); it('reverts scheduling an unknown operation to the manager', async function () { const calldata = '0x12345678'; - const { schedule } = await prepareOperation(this.manager, { + const { schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.manager, calldata, @@ -2188,7 +2191,7 @@ describe('AccessManager', function () { const delay = time.duration.hours(4); await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); // Execution delay is needed so the operation is consumed - const { operationId, schedule } = await prepareOperation(this.manager, { + const { operationId, schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -2209,7 +2212,7 @@ describe('AccessManager', function () { // give caller an execution delay await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); - const { operationId, schedule } = await prepareOperation(this.manager, { + const { operationId, schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -2239,7 +2242,7 @@ describe('AccessManager', function () { const delay = time.duration.hours(2); await this.manager.$_grantRole(this.role.id, this.caller, 0, 1); // Execution delay is needed so the operation is consumed - const { operationId, schedule } = await prepareOperation(this.manager, { + const { operationId, schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, @@ -2421,7 +2424,7 @@ describe('AccessManager', function () { }); it('cancels an operation and resets schedule', async function () { - const { operationId, schedule } = await prepareOperation(this.manager, { + const { operationId, schedule } = await prepareOperation.bind(this)(this.manager, { caller: this.caller, target: this.target, calldata: this.calldata, diff --git a/test/access/manager/AuthorityUtils.test.js b/test/access/manager/AuthorityUtils.test.js index 465f617adca..4ccd32a2bb4 100644 --- a/test/access/manager/AuthorityUtils.test.js +++ b/test/access/manager/AuthorityUtils.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT32, MAX_UINT64 } from '../../helpers/constants'; -const { MAX_UINT32, MAX_UINT64 } = require('../../helpers/constants'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [user, other] = await ethers.getSigners(); diff --git a/test/account/Account.behavior.js b/test/account/Account.behavior.js index 5e993e46a2e..317febdcc24 100644 --- a/test/account/Account.behavior.js +++ b/test/account/Account.behavior.js @@ -1,14 +1,13 @@ -const { ethers, predeploy } = require('hardhat'); -const { expect } = require('chai'); -const { impersonate } = require('../helpers/account'); -const { SIG_VALIDATION_SUCCESS, SIG_VALIDATION_FAILURE } = require('../helpers/erc4337'); -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { SIG_VALIDATION_SUCCESS, SIG_VALIDATION_FAILURE } from '../helpers/erc4337'; +import { shouldSupportInterfaces } from '../utils/introspection/SupportsInterface.behavior'; -function shouldBehaveLikeAccountCore() { +export function shouldBehaveLikeAccountCore() { describe('entryPoint', function () { it('should return the canonical entrypoint', async function () { await this.mock.deploy(); - await expect(this.mock.entryPoint()).to.eventually.equal(predeploy.entrypoint.v09); + await expect(this.mock.entryPoint()).to.eventually.equal(this.ethers.predeploy.entrypoint.v09); }); }); @@ -30,7 +29,9 @@ function shouldBehaveLikeAccountCore() { describe('when the caller is the canonical entrypoint', function () { beforeEach(async function () { - this.mockFromEntrypoint = this.mock.connect(await impersonate(predeploy.entrypoint.v09.target)); + this.mockFromEntrypoint = this.mock.connect( + await this.helpers.impersonate(this.ethers.predeploy.entrypoint.v09.target), + ); }); it('should return SIG_VALIDATION_SUCCESS if the signature is valid', async function () { @@ -57,9 +58,10 @@ function shouldBehaveLikeAccountCore() { const operation = await this.mock.createUserOp(this.userOp).then(op => this.signUserOp(op)); const value = 42n; + // Forcing the gas limit here to work around a hardhat 3 issue with gas estimation await expect( - this.mockFromEntrypoint.validateUserOp(operation.packed, operation.hash(), value), - ).to.changeEtherBalances([this.mock, predeploy.entrypoint.v09], [-value, value]); + this.mockFromEntrypoint.validateUserOp(operation.packed, operation.hash(), value, { gasLimit: 2_000_000n }), + ).to.changeEtherBalances(this.ethers, [this.mock, this.ethers.predeploy.entrypoint.v09], [-value, value]); }); }); }); @@ -70,6 +72,7 @@ function shouldBehaveLikeAccountCore() { const value = 42n; await expect(this.other.sendTransaction({ to: this.mock, value })).to.changeEtherBalances( + this.ethers, [this.other, this.mock], [-value, value], ); @@ -77,7 +80,7 @@ function shouldBehaveLikeAccountCore() { }); } -function shouldBehaveLikeAccountHolder() { +export function shouldBehaveLikeAccountHolder() { describe('onReceived', function () { beforeEach(async function () { await this.mock.deploy(); @@ -91,7 +94,7 @@ function shouldBehaveLikeAccountHolder() { const data = '0x12345678'; beforeEach(async function () { - this.token = await ethers.deployContract('$ERC1155', ['https://somedomain.com/{id}.json']); + this.token = await this.ethers.deployContract('$ERC1155', ['https://somedomain.com/{id}.json']); await this.token.$_mintBatch(this.other, ids, values, '0x'); }); @@ -128,7 +131,7 @@ function shouldBehaveLikeAccountHolder() { const tokenId = 1n; beforeEach(async function () { - this.token = await ethers.deployContract('$ERC721', ['Some NFT', 'SNFT']); + this.token = await this.ethers.deployContract('$ERC721', ['Some NFT', 'SNFT']); await this.token.$_mint(this.other, tokenId); }); @@ -140,5 +143,3 @@ function shouldBehaveLikeAccountHolder() { }); }); } - -module.exports = { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder }; diff --git a/test/account/Account.test.js b/test/account/Account.test.js index 4bd402e05b5..3d476fa486f 100644 --- a/test/account/Account.test.js +++ b/test/account/Account.test.js @@ -1,14 +1,17 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { PackedUserOperation } = require('../helpers/eip712-types'); -const { NonNativeSigner } = require('../helpers/signers'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); +import { network } from 'hardhat'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { NonNativeSigner } from '../helpers/signers'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { // EOAs and environment @@ -19,11 +22,11 @@ async function fixture() { const signer = new NonNativeSigner({ sign: hash => ({ serialized: hash }) }); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const mock = await helper.newAccount('$AccountMock', ['Account', '1']); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { name: 'Account', version: '1', chainId: entrypointDomain.chainId, verifyingContract: mock.address }; @@ -38,7 +41,7 @@ async function fixture() { describe('Account', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeAccountCore(); diff --git a/test/account/AccountECDSA.test.js b/test/account/AccountECDSA.test.js index 472c68433b3..5f9c58b7ebd 100644 --- a/test/account/AccountECDSA.test.js +++ b/test/account/AccountECDSA.test.js @@ -1,13 +1,16 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { PackedUserOperation } = require('../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); +import { network } from 'hardhat'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { // EOAs and environment @@ -18,11 +21,11 @@ async function fixture() { const signer = ethers.Wallet.createRandom(); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const mock = await helper.newAccount('$AccountECDSAMock', [signer, 'AccountECDSA', '1']); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { @@ -42,7 +45,7 @@ async function fixture() { describe('AccountECDSA', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeAccountCore(); diff --git a/test/account/AccountEIP7702.t.sol b/test/account/AccountEIP7702.t.sol deleted file mode 100644 index 88323fc7fc9..00000000000 --- a/test/account/AccountEIP7702.t.sol +++ /dev/null @@ -1,116 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.20; - -import {Test} from "forge-std/Test.sol"; -import {AccountEIP7702Mock} from "@openzeppelin/contracts/mocks/account/AccountMock.sol"; -import {CallReceiverMock} from "@openzeppelin/contracts/mocks/CallReceiverMock.sol"; -import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; -import { - ERC7579Utils, - Execution, - Mode, - ModeSelector, - ModePayload -} from "@openzeppelin/contracts/account/utils/draft-ERC7579Utils.sol"; -import {ERC4337Utils, IEntryPointExtra} from "@openzeppelin/contracts/account/utils/draft-ERC4337Utils.sol"; -import {Strings} from "@openzeppelin/contracts/utils/Strings.sol"; -import {PackedUserOperation} from "@openzeppelin/contracts/interfaces/draft-IERC4337.sol"; -import {ERC7821} from "@openzeppelin/contracts/account/extensions/draft-ERC7821.sol"; - -contract AccountEIP7702MockConstructor is AccountEIP7702Mock { - constructor() EIP712("MyAccount", "1") {} -} - -contract AccountEIP7702Test is Test { - using ERC7579Utils for *; - using ERC4337Utils for PackedUserOperation; - using Strings for *; - - uint256 private constant MAX_ETH = type(uint128).max; - - // Test accounts - CallReceiverMock private _target; - - // ERC-4337 signer - uint256 private _signerPrivateKey; - AccountEIP7702MockConstructor private _signer; - - function setUp() public { - // Deploy target contract - _target = new CallReceiverMock(); - - // Setup signer - _signerPrivateKey = 0x1234; - _signer = AccountEIP7702MockConstructor(payable(vm.addr(_signerPrivateKey))); - vm.deal(address(_signer), MAX_ETH); - - // Sign and attach delegation - vm.signAndAttachDelegation(address(new AccountEIP7702MockConstructor()), _signerPrivateKey); - - // Setup entrypoint - address entrypoint = address(ERC4337Utils.ENTRYPOINT_V09); - vm.deal(entrypoint, MAX_ETH); - vm.etch( - entrypoint, - vm.readFileBinary( - string.concat( - "node_modules/hardhat-predeploy/bin/", - Strings.toChecksumHexString(entrypoint), - ".bytecode" - ) - ) - ); - } - - function testExecuteBatch(address bundler, uint256 argA, uint256 argB) public { - vm.assume(bundler.code.length == 0); - vm.startPrank(bundler, bundler); - - // Create the mode for batch execution - Mode mode = ERC7579Utils.CALLTYPE_BATCH.encodeMode( - ERC7579Utils.EXECTYPE_DEFAULT, - ModeSelector.wrap(0x00000000), - ModePayload.wrap(0x00000000) - ); - - Execution[] memory execution = new Execution[](2); - execution[0] = Execution({ - target: address(_target), - value: 1 ether, - callData: abi.encodeCall(CallReceiverMock.mockFunctionExtra, ()) - }); - execution[1] = Execution({ - target: address(_target), - value: 0, - callData: abi.encodeCall(CallReceiverMock.mockFunctionWithArgs, (argA, argB)) - }); - - // Pack the batch within a PackedUserOperation - PackedUserOperation[] memory ops = new PackedUserOperation[](1); - ops[0] = PackedUserOperation({ - sender: address(_signer), - nonce: 0, - initCode: bytes(""), - callData: abi.encodeCall(ERC7821.execute, (Mode.unwrap(mode), execution.encodeBatch())), - preVerificationGas: 100000, - accountGasLimits: bytes32(abi.encodePacked(uint128(100000), uint128(100000))), - gasFees: bytes32(abi.encodePacked(uint128(1000000), uint128(1000000))), - paymasterAndData: bytes(""), - signature: bytes("") - }); - (uint8 v, bytes32 r, bytes32 s) = vm.sign( - _signerPrivateKey, - IEntryPointExtra(address(ERC4337Utils.ENTRYPOINT_V09)).getUserOpHash(ops[0]) - ); - ops[0].signature = abi.encodePacked(r, s, v); - - // Expect the events to be emitted - vm.expectEmit(true, true, true, true); - emit CallReceiverMock.MockFunctionCalledExtra(address(_signer), 1 ether); - vm.expectEmit(true, true, true, true); - emit CallReceiverMock.MockFunctionCalledWithArgs(argA, argB); - - // Execute the batch - _signer.entryPoint().handleOps(ops, payable(makeAddr("beneficiary"))); - } -} diff --git a/test/account/AccountEIP7702.test.js b/test/account/AccountEIP7702.test.js index d832e68771f..98aae7492b6 100644 --- a/test/account/AccountEIP7702.test.js +++ b/test/account/AccountEIP7702.test.js @@ -1,13 +1,16 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { PackedUserOperation } = require('../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); +import { network } from 'hardhat'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { // EOAs and environment @@ -18,12 +21,11 @@ async function fixture() { const signer = ethers.Wallet.createRandom(ethers.provider); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const mock = await helper.newAccount('$AccountEIP7702Mock', ['AccountEIP7702Mock', '1'], { eip7702signer: signer }); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); - + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { name: 'AccountEIP7702Mock', @@ -42,7 +44,7 @@ async function fixture() { describe('AccountEIP7702', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeAccountCore(); diff --git a/test/account/AccountERC7913.test.js b/test/account/AccountERC7913.test.js index 2807b6cd6dc..0cf880f58c8 100644 --- a/test/account/AccountERC7913.test.js +++ b/test/account/AccountERC7913.test.js @@ -1,14 +1,17 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { NonNativeSigner, P256SigningKey, RSASHA256SigningKey, WebAuthnSigningKey } = require('../helpers/signers'); -const { PackedUserOperation } = require('../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); +import { network } from 'hardhat'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { NonNativeSigner, P256SigningKey, RSASHA256SigningKey, WebAuthnSigningKey } from '../helpers/signers'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; // Prepare signer in advance (RSA are long to initialize) const signerECDSA = ethers.Wallet.createRandom(); @@ -28,9 +31,9 @@ async function fixture() { const verifierWebAuthn = await ethers.deployContract('ERC7913WebAuthnVerifier'); // ERC-4337 env - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); await helper.wait(); - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); const domain = { name: 'AccountERC7913', version: '1', chainId: entrypointDomain.chainId }; // Missing verifyingContract, const makeMock = signer => @@ -61,7 +64,7 @@ async function fixture() { describe('AccountERC7913', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); // Using ECDSA key as verifier diff --git a/test/account/AccountMultiSigner.test.js b/test/account/AccountMultiSigner.test.js index 9f4042a8eb0..aa09d95acf9 100644 --- a/test/account/AccountMultiSigner.test.js +++ b/test/account/AccountMultiSigner.test.js @@ -1,16 +1,19 @@ -const { ethers, predeploy } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { NonNativeSigner, P256SigningKey, RSASHA256SigningKey, MultiERC7913SigningKey } = require('../helpers/signers'); -const { MAX_UINT64 } = require('../helpers/constants'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); -const { PackedUserOperation } = require('../helpers/eip712-types'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT64 } from '../helpers/constants'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { NonNativeSigner, P256SigningKey, RSASHA256SigningKey, MultiERC7913SigningKey } from '../helpers/signers'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; // Prepare signers in advance (RSA are long to initialize) const signerECDSA1 = ethers.Wallet.createRandom(); @@ -31,9 +34,9 @@ async function fixture() { const verifierRSA = await ethers.deployContract('ERC7913RSAVerifier'); // ERC-4337 env - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); await helper.wait(); - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); const domain = { name: 'AccountMultiSigner', version: '1', chainId: entrypointDomain.chainId }; // Missing verifyingContract const makeMock = (signers, threshold) => @@ -69,7 +72,7 @@ async function fixture() { describe('AccountMultiSigner', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); describe('Multi ECDSA signers with threshold=1', function () { diff --git a/test/account/AccountMultiSignerWeighted.test.js b/test/account/AccountMultiSignerWeighted.test.js index c954d421a7a..ca35a669dc6 100644 --- a/test/account/AccountMultiSignerWeighted.test.js +++ b/test/account/AccountMultiSignerWeighted.test.js @@ -1,16 +1,19 @@ -const { ethers, predeploy } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { NonNativeSigner, P256SigningKey, RSASHA256SigningKey, MultiERC7913SigningKey } = require('../helpers/signers'); -const { PackedUserOperation } = require('../helpers/eip712-types'); -const { MAX_UINT64 } = require('../helpers/constants'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT64 } from '../helpers/constants'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { NonNativeSigner, P256SigningKey, RSASHA256SigningKey, MultiERC7913SigningKey } from '../helpers/signers'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; // Prepare signers in advance (RSA are long to initialize) const signerECDSA1 = ethers.Wallet.createRandom(); @@ -31,9 +34,9 @@ async function fixture() { const verifierRSA = await ethers.deployContract('ERC7913RSAVerifier'); // ERC-4337 env - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); await helper.wait(); - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); const domain = { name: 'AccountMultiSignerWeighted', version: '1', chainId: entrypointDomain.chainId }; // Missing verifyingContract const makeMock = (signers, weights, threshold) => @@ -71,7 +74,7 @@ async function fixture() { describe('AccountMultiSignerWeighted', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); describe('Weighted signers with equal weights (1, 1, 1) and threshold=2', function () { diff --git a/test/account/AccountP256.test.js b/test/account/AccountP256.test.js index cd69abcec95..c84796dc3f3 100644 --- a/test/account/AccountP256.test.js +++ b/test/account/AccountP256.test.js @@ -1,14 +1,17 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { NonNativeSigner, P256SigningKey } = require('../helpers/signers'); -const { PackedUserOperation } = require('../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); +import { network } from 'hardhat'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { NonNativeSigner, P256SigningKey } from '../helpers/signers'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { // EOAs and environment @@ -19,7 +22,7 @@ async function fixture() { const signer = new NonNativeSigner(P256SigningKey.random()); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const mock = await helper.newAccount('$AccountP256Mock', [ signer.signingKey.publicKey.qx, signer.signingKey.publicKey.qy, @@ -28,7 +31,7 @@ async function fixture() { ]); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { @@ -48,7 +51,7 @@ async function fixture() { describe('AccountP256', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeAccountCore(); diff --git a/test/account/AccountRSA.test.js b/test/account/AccountRSA.test.js index 057691719bc..ef2990ba870 100644 --- a/test/account/AccountRSA.test.js +++ b/test/account/AccountRSA.test.js @@ -1,14 +1,17 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { NonNativeSigner, RSASHA256SigningKey } = require('../helpers/signers'); -const { PackedUserOperation } = require('../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); +import { network } from 'hardhat'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { NonNativeSigner, RSASHA256SigningKey } from '../helpers/signers'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { // EOAs and environment @@ -19,7 +22,7 @@ async function fixture() { const signer = new NonNativeSigner(RSASHA256SigningKey.random()); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const mock = await helper.newAccount('$AccountRSAMock', [ signer.signingKey.publicKey.e, signer.signingKey.publicKey.n, @@ -28,7 +31,7 @@ async function fixture() { ]); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { @@ -48,7 +51,7 @@ async function fixture() { describe('AccountRSA', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeAccountCore(); diff --git a/test/account/AccountWebAuthn.test.js b/test/account/AccountWebAuthn.test.js index 2106337919a..6041cf35f14 100644 --- a/test/account/AccountWebAuthn.test.js +++ b/test/account/AccountWebAuthn.test.js @@ -1,14 +1,17 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { getDomain } from '../helpers/eip712'; +import { ERC4337Helper } from '../helpers/erc4337'; +import { PackedUserOperation } from '../helpers/eip712-types'; +import { NonNativeSigner, P256SigningKey, WebAuthnSigningKey } from '../helpers/signers'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from './Account.behavior'; +import { shouldBehaveLikeERC1271 } from '../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from './extensions/ERC7821.behavior'; -const { getDomain } = require('../helpers/eip712'); -const { ERC4337Helper } = require('../helpers/erc4337'); -const { NonNativeSigner, P256SigningKey, WebAuthnSigningKey } = require('../helpers/signers'); -const { PackedUserOperation } = require('../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('./Account.behavior'); -const { shouldBehaveLikeERC1271 } = require('../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('./extensions/ERC7821.behavior'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const webAuthnSigner = new NonNativeSigner(WebAuthnSigningKey.random()); const p256Signer = new NonNativeSigner(P256SigningKey.random()); @@ -19,7 +22,7 @@ async function fixture() { const target = await ethers.deployContract('CallReceiverMock'); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const webAuthnMock = await helper.newAccount('$AccountWebAuthnMock', [ webAuthnSigner.signingKey.publicKey.qx, @@ -36,7 +39,7 @@ async function fixture() { ]); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { @@ -57,7 +60,7 @@ async function fixture() { describe('AccountWebAuthn', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); describe('WebAuthn Assertions', function () { diff --git a/test/account/examples/AccountEIP7702WithModulesMock.test.js b/test/account/examples/AccountEIP7702WithModulesMock.test.js index 86816e55e57..bd30d77e0c4 100644 --- a/test/account/examples/AccountEIP7702WithModulesMock.test.js +++ b/test/account/examples/AccountEIP7702WithModulesMock.test.js @@ -1,16 +1,18 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture, setBalance } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../../helpers/eip712'); -const { ERC4337Helper } = require('../../helpers/erc4337'); -const { PackedUserOperation } = require('../../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } = require('../Account.behavior'); -const { shouldBehaveLikeAccountERC7579 } = require('../extensions/AccountERC7579.behavior'); -const { shouldBehaveLikeERC1271 } = require('../../utils/cryptography/ERC1271.behavior'); -const { shouldBehaveLikeERC7821 } = require('../extensions/ERC7821.behavior'); - -const { MODULE_TYPE_VALIDATOR } = require('../../helpers/erc7579'); +import { network } from 'hardhat'; +import { getDomain } from '../../helpers/eip712'; +import { ERC4337Helper } from '../../helpers/erc4337'; +import { MODULE_TYPE_VALIDATOR } from '../../helpers/erc7579'; +import { PackedUserOperation } from '../../helpers/eip712-types'; +import { shouldBehaveLikeAccountCore, shouldBehaveLikeAccountHolder } from '../Account.behavior'; +import { shouldBehaveLikeAccountERC7579 } from '../extensions/AccountERC7579.behavior'; +import { shouldBehaveLikeERC1271 } from '../../utils/cryptography/ERC1271.behavior'; +import { shouldBehaveLikeERC7821 } from '../extensions/ERC7821.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture, setBalance }, +} = connection; async function fixture() { // EOAs and environment @@ -26,13 +28,13 @@ async function fixture() { const validator = await ethers.deployContract('$ERC7579ValidatorMock'); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const mock = await helper.newAccount('$AccountEIP7702WithModulesMock', ['AccountEIP7702WithModulesMock', '1'], { eip7702signer: eoa, }); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); // domain cannot be fetched using getDomain(mock) before the mock is deployed const domain = { @@ -47,7 +49,7 @@ async function fixture() { describe('AccountEIP7702WithModules: EIP-7702 account with ERC-7579 modules supports', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); describe('using EIP-7702 signer', function () { diff --git a/test/account/extensions/AccountERC7579.behavior.js b/test/account/extensions/AccountERC7579.behavior.js index 94002158f96..a5be44f0e82 100644 --- a/test/account/extensions/AccountERC7579.behavior.js +++ b/test/account/extensions/AccountERC7579.behavior.js @@ -1,10 +1,8 @@ -const { ethers, predeploy } = require('hardhat'); -const { expect } = require('chai'); -const { setCode } = require('@nomicfoundation/hardhat-network-helpers'); -const { impersonate } = require('../../helpers/account'); -const { selector } = require('../../helpers/methods'); -const { zip } = require('../../helpers/iterate'); -const { +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { selector } from '../../helpers/methods'; +import { zip } from '../../helpers/iterate'; +import { encodeMode, encodeBatch, encodeSingle, @@ -18,28 +16,36 @@ const { CALL_TYPE_DELEGATE, EXEC_TYPE_DEFAULT, EXEC_TYPE_TRY, -} = require('../../helpers/erc7579'); +} from '../../helpers/erc7579'; const CALL_TYPE_INVALID = '0x42'; const EXEC_TYPE_INVALID = '0x17'; const MODULE_TYPE_INVALID = 999n; -const coder = ethers.AbiCoder.defaultAbiCoder(); - -function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { +export function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { describe('AccountERC7579', function () { beforeEach(async function () { await this.mock.deploy(); await this.other.sendTransaction({ to: this.mock.target, value: ethers.parseEther('1') }); this.modules = {}; - this.modules[MODULE_TYPE_VALIDATOR] = await ethers.deployContract('$ERC7579ModuleMock', [MODULE_TYPE_VALIDATOR]); - this.modules[MODULE_TYPE_EXECUTOR] = await ethers.deployContract('$ERC7579ModuleMock', [MODULE_TYPE_EXECUTOR]); - this.modules[MODULE_TYPE_FALLBACK] = await ethers.deployContract('$ERC7579ModuleMock', [MODULE_TYPE_FALLBACK]); - this.modules[MODULE_TYPE_HOOK] = await ethers.deployContract('$ERC7579HookMock'); + this.modules[MODULE_TYPE_VALIDATOR] = await this.ethers.deployContract('$ERC7579ModuleMock', [ + MODULE_TYPE_VALIDATOR, + ]); + this.modules[MODULE_TYPE_EXECUTOR] = await this.ethers.deployContract('$ERC7579ModuleMock', [ + MODULE_TYPE_EXECUTOR, + ]); + this.modules[MODULE_TYPE_FALLBACK] = await this.ethers.deployContract('$ERC7579ModuleMock', [ + MODULE_TYPE_FALLBACK, + ]); + this.modules[MODULE_TYPE_HOOK] = await this.ethers.deployContract('$ERC7579HookMock'); - this.mockFromEntrypoint = this.mock.connect(await impersonate(predeploy.entrypoint.v09.target)); - this.mockFromExecutor = this.mock.connect(await impersonate(this.modules[MODULE_TYPE_EXECUTOR].target)); + this.mockFromEntrypoint = this.mock.connect( + await this.helpers.impersonate(this.ethers.predeploy.entrypoint.v09.target), + ); + this.mockFromExecutor = this.mock.connect( + await this.helpers.impersonate(this.modules[MODULE_TYPE_EXECUTOR].target), + ); }); describe('accountId', function () { @@ -197,7 +203,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { await expect(this.mockFromEntrypoint.installModule(MODULE_TYPE_EXECUTOR, instance, initData)) .to.emit(this.modules[MODULE_TYPE_HOOK], 'PreCheck') - .withArgs(predeploy.entrypoint.v09, 0n, precheckData) + .withArgs(this.ethers.predeploy.entrypoint.v09, 0n, precheckData) .to.emit(this.modules[MODULE_TYPE_HOOK], 'PostCheck') .withArgs(precheckData); }); @@ -265,7 +271,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { it('should revert uninstalling a module of type MODULE_TYPE_FALLBACK if a different module was installed for the provided selector', async function () { const instance = this.modules[MODULE_TYPE_FALLBACK]; - const anotherInstance = await ethers.deployContract('$ERC7579ModuleMock', [MODULE_TYPE_FALLBACK]); + const anotherInstance = await this.ethers.deployContract('$ERC7579ModuleMock', [MODULE_TYPE_FALLBACK]); const initData = '0x12345678abcdef'; await this.mock.$_installModule(MODULE_TYPE_FALLBACK, instance, initData); @@ -275,7 +281,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { }); it('should uninstall a module even if its onUninstall hook reverts', async function () { - const maliciousModule = await ethers.deployContract('$ERC7579ModuleMaliciousMock', [MODULE_TYPE_EXECUTOR]); + const maliciousModule = await this.ethers.deployContract('$ERC7579ModuleMaliciousMock', [MODULE_TYPE_EXECUTOR]); // Install the malicious module await this.mock.$_installModule(MODULE_TYPE_EXECUTOR, maliciousModule, '0x'); @@ -313,7 +319,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { await expect(this.mockFromEntrypoint.uninstallModule(MODULE_TYPE_EXECUTOR, instance, initData)) .to.emit(this.modules[MODULE_TYPE_HOOK], 'PreCheck') - .withArgs(predeploy.entrypoint.v09, 0n, precheckData) + .withArgs(this.ethers.predeploy.entrypoint.v09, 0n, precheckData) .to.emit(this.modules[MODULE_TYPE_HOOK], 'PostCheck') .withArgs(precheckData); }); @@ -372,7 +378,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { .withArgs(MODULE_TYPE_HOOK, instance) .to.emit(instance, 'PreCheck') .withArgs( - predeploy.entrypoint.v09, + this.ethers.predeploy.entrypoint.v09, 0n, this.mock.interface.encodeFunctionData('uninstallModule', [ MODULE_TYPE_HOOK, @@ -408,7 +414,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { const initData = ethers.hexlify(ethers.randomBytes(256)); // Delete the code of the module to simulate a removed delegation - await setCode(instance.target, '0x'); + await this.networkHelpers.setCode(instance.target, '0x'); // Should uninstall await expect(this.mockFromEntrypoint.uninstallModule(MODULE_TYPE_HOOK, instance, initData)) @@ -465,7 +471,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { const tx = this[mock][execFn](encodeMode({ callType: CALL_TYPE_CALL }), data); await expect(tx).to.emit(this.target, 'MockFunctionCalledWithArgs').withArgs(42, '0x1234'); - await expect(tx).to.changeEtherBalances([this.mock, this.target], [-value, value]); + await expect(tx).to.changeEtherBalances(this.ethers, [this.mock, this.target], [-value, value]); }); it('reverts when target reverts in default ExecType', async function () { @@ -495,7 +501,10 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { CALL_TYPE_CALL, ethers.solidityPacked( ['bytes4', 'bytes'], - [selector('Error(string)'), coder.encode(['string'], ['CallReceiverMock: reverting'])], + [ + selector('Error(string)'), + ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['CallReceiverMock: reverting']), + ], ), ); }); @@ -519,6 +528,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { .to.emit(this.target, 'MockFunctionCalledWithArgs') .to.emit(this.anotherTarget, 'MockFunctionCalledWithArgs'); await expect(tx).to.changeEtherBalances( + this.ethers, [this.mock, this.target, this.anotherTarget], [-value1 - value2, value1, value2], ); @@ -561,11 +571,15 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { CALL_TYPE_BATCH, ethers.solidityPacked( ['bytes4', 'bytes'], - [selector('Error(string)'), coder.encode(['string'], ['CallReceiverMock: reverting'])], + [ + selector('Error(string)'), + ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['CallReceiverMock: reverting']), + ], ), ); await expect(tx).to.changeEtherBalances( + this.ethers, [this.mock, this.target, this.anotherTarget], [-value1, value1, 0], ); @@ -581,9 +595,11 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { this.target.interface.encodeFunctionData('mockFunctionWritesStorage', [slot, value]), ); - await expect(ethers.provider.getStorage(this.mock.target, slot)).to.eventually.equal(ethers.ZeroHash); + await expect(this.ethers.provider.getStorage(this.mock.target, slot)).to.eventually.equal( + ethers.ZeroHash, + ); await this[mock][execFn](encodeMode({ callType: CALL_TYPE_DELEGATE }), data); - await expect(ethers.provider.getStorage(this.mock.target, slot)).to.eventually.equal(value); + await expect(this.ethers.provider.getStorage(this.mock.target, slot)).to.eventually.equal(value); }); it('reverts when target reverts in default ExecType', async function () { @@ -609,7 +625,10 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { CALL_TYPE_CALL, ethers.solidityPacked( ['bytes4', 'bytes'], - [selector('Error(string)'), coder.encode(['string'], ['CallReceiverMock: reverting'])], + [ + selector('Error(string)'), + ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['CallReceiverMock: reverting']), + ], ), ); }); @@ -622,7 +641,8 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { }); it(`should call the hook of the installed module when executing ${execFn}`, async function () { - const caller = execFn === 'execute' ? predeploy.entrypoint.v09 : this.modules[MODULE_TYPE_EXECUTOR]; + const caller = + execFn === 'execute' ? this.ethers.predeploy.entrypoint.v09 : this.modules[MODULE_TYPE_EXECUTOR]; const value = 17; const data = this.target.interface.encodeFunctionData('mockFunctionWithArgs', [42, '0x1234']); @@ -637,7 +657,11 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { .withArgs(caller, value, precheckData) .to.emit(this.modules[MODULE_TYPE_HOOK], 'PostCheck') .withArgs(precheckData); - await expect(tx).to.changeEtherBalances([caller, this.mock, this.target], [-value, 0n, value]); + await expect(tx).to.changeEtherBalances( + this.ethers, + [caller, this.mock, this.target], + [-value, 0n, value], + ); }); }); }); @@ -646,7 +670,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { describe('fallback', function () { beforeEach(async function () { - this.fallbackHandler = await ethers.deployContract('$ERC7579FallbackHandlerMock'); + this.fallbackHandler = await this.ethers.deployContract('$ERC7579FallbackHandlerMock'); }); it('reverts if there is no fallback module installed', async function () { @@ -668,7 +692,7 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { this.mock.$_installModule( MODULE_TYPE_FALLBACK, this.fallbackHandler, - coder.encode(['bytes4', 'bytes'], [selector, '0x']), + ethers.AbiCoder.defaultAbiCoder().encode(['bytes4', 'bytes'], [selector, '0x']), ), ), ); @@ -718,7 +742,3 @@ function shouldBehaveLikeAccountERC7579({ withHooks = false } = {}) { }); }); } - -module.exports = { - shouldBehaveLikeAccountERC7579, -}; diff --git a/test/account/extensions/AccountERC7579.test.js b/test/account/extensions/AccountERC7579.test.js index 83f0224fa9e..d98c95e51a9 100644 --- a/test/account/extensions/AccountERC7579.test.js +++ b/test/account/extensions/AccountERC7579.test.js @@ -1,13 +1,16 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../../helpers/eip712'); -const { ERC4337Helper } = require('../../helpers/erc4337'); -const { PackedUserOperation } = require('../../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore } = require('../Account.behavior'); -const { shouldBehaveLikeAccountERC7579 } = require('./AccountERC7579.behavior'); -const { shouldBehaveLikeERC1271 } = require('../../utils/cryptography/ERC1271.behavior'); +import { network } from 'hardhat'; +import { getDomain } from '../../helpers/eip712'; +import { ERC4337Helper } from '../../helpers/erc4337'; +import { PackedUserOperation } from '../../helpers/eip712-types'; +import { shouldBehaveLikeAccountCore } from '../Account.behavior'; +import { shouldBehaveLikeAccountERC7579 } from './AccountERC7579.behavior'; +import { shouldBehaveLikeERC1271 } from '../../utils/cryptography/ERC1271.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { // EOAs and environment @@ -22,21 +25,21 @@ async function fixture() { const signer = ethers.Wallet.createRandom(); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const mock = await helper.newAccount('$AccountERC7579Mock', [ validator, ethers.solidityPacked(['address'], [signer.address]), ]); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); return { helper, validator, mock, entrypointDomain, signer, target, anotherTarget, other }; } describe('AccountERC7579', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); this.signer.signMessage = message => ethers.Wallet.prototype.signMessage diff --git a/test/account/extensions/AccountERC7579Hooked.test.js b/test/account/extensions/AccountERC7579Hooked.test.js index 7e973844dfd..3ba7df99e1d 100644 --- a/test/account/extensions/AccountERC7579Hooked.test.js +++ b/test/account/extensions/AccountERC7579Hooked.test.js @@ -1,13 +1,16 @@ -const { ethers, predeploy } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain } = require('../../helpers/eip712'); -const { ERC4337Helper } = require('../../helpers/erc4337'); -const { PackedUserOperation } = require('../../helpers/eip712-types'); - -const { shouldBehaveLikeAccountCore } = require('../Account.behavior'); -const { shouldBehaveLikeAccountERC7579 } = require('./AccountERC7579.behavior'); -const { shouldBehaveLikeERC1271 } = require('../../utils/cryptography/ERC1271.behavior'); +import { network } from 'hardhat'; +import { getDomain } from '../../helpers/eip712'; +import { ERC4337Helper } from '../../helpers/erc4337'; +import { PackedUserOperation } from '../../helpers/eip712-types'; +import { shouldBehaveLikeAccountCore } from '../Account.behavior'; +import { shouldBehaveLikeAccountERC7579 } from './AccountERC7579.behavior'; +import { shouldBehaveLikeERC1271 } from '../../utils/cryptography/ERC1271.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { // EOAs and environment @@ -22,21 +25,21 @@ async function fixture() { const signer = ethers.Wallet.createRandom(); // ERC-4337 account - const helper = new ERC4337Helper(); + const helper = new ERC4337Helper(connection); const mock = await helper.newAccount('$AccountERC7579HookedMock', [ validator, ethers.solidityPacked(['address'], [signer.address]), ]); // ERC-4337 Entrypoint domain - const entrypointDomain = await getDomain(predeploy.entrypoint.v09); + const entrypointDomain = await getDomain(ethers.predeploy.entrypoint.v09); return { helper, validator, mock, entrypointDomain, signer, target, anotherTarget, other }; } describe('AccountERC7579Hooked', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); this.signer.signMessage = message => ethers.Wallet.prototype.signMessage diff --git a/test/account/extensions/ERC7821.behavior.js b/test/account/extensions/ERC7821.behavior.js index bb039d52216..dc909ea1715 100644 --- a/test/account/extensions/ERC7821.behavior.js +++ b/test/account/extensions/ERC7821.behavior.js @@ -1,16 +1,16 @@ -const { ethers, predeploy } = require('hardhat'); -const { expect } = require('chai'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; -const { CALL_TYPE_BATCH, encodeMode, encodeBatch } = require('../../helpers/erc7579'); +import { CALL_TYPE_BATCH, encodeMode, encodeBatch } from '../../helpers/erc7579'; -function shouldBehaveLikeERC7821({ deployable = true } = {}) { +export function shouldBehaveLikeERC7821({ deployable = true } = {}) { describe('supports ERC-7821', function () { beforeEach(async function () { // give eth to the account (before deployment) await this.other.sendTransaction({ to: this.mock.target, value: ethers.parseEther('1') }); // account is not initially deployed - await expect(ethers.provider.getCode(this.mock)).to.eventually.equal('0x'); + await expect(this.mock.runner.provider.getCode(this.mock)).to.eventually.equal('0x'); this.encodeUserOpCalldata = (...calls) => this.mock.interface.encodeFunctionData('execute', [ @@ -50,9 +50,9 @@ function shouldBehaveLikeERC7821({ deployable = true } = {}) { .then(op => this.signUserOp(op)); // Can't call the account to get its nonce before it's deployed - await expect(predeploy.entrypoint.v09.getNonce(this.mock.target, 0)).to.eventually.equal(0); - await expect(predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary)) - .to.emit(predeploy.entrypoint.v09, 'AccountDeployed') + await expect(this.ethers.predeploy.entrypoint.v09.getNonce(this.mock.target, 0)).to.eventually.equal(0); + await expect(this.ethers.predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary)) + .to.emit(this.ethers.predeploy.entrypoint.v09, 'AccountDeployed') .withArgs(operation.hash(), this.mock, this.helper.factory, ethers.ZeroAddress) .to.emit(this.target, 'MockFunctionCalledExtra') .withArgs(this.mock, 17); @@ -72,7 +72,9 @@ function shouldBehaveLikeERC7821({ deployable = true } = {}) { operation.signature = '0x00'; - await expect(predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary)).to.be.reverted; + await expect( + this.ethers.predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary), + ).to.be.revert(this.ethers); }); }); } @@ -94,7 +96,7 @@ function shouldBehaveLikeERC7821({ deployable = true } = {}) { .then(op => this.signUserOp(op)); await expect(this.mock.getNonce()).to.eventually.equal(0); - await expect(predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary)) + await expect(this.ethers.predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary)) .to.emit(this.target, 'MockFunctionCalledExtra') .withArgs(this.mock, 42); await expect(this.mock.getNonce()).to.eventually.equal(1); @@ -106,10 +108,9 @@ function shouldBehaveLikeERC7821({ deployable = true } = {}) { .then(op => this.signUserOp(op)); await expect(this.mock.getNonce()).to.eventually.equal(0); - await expect(predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary)).to.changeEtherBalance( - this.other, - 42, - ); + await expect( + this.ethers.predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary), + ).to.changeEtherBalance(this.ethers, this.other, 42); await expect(this.mock.getNonce()).to.eventually.equal(1); }); @@ -131,15 +132,11 @@ function shouldBehaveLikeERC7821({ deployable = true } = {}) { .then(op => this.signUserOp(op)); await expect(this.mock.getNonce()).to.eventually.equal(0); - const tx = predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary); - await expect(tx).to.changeEtherBalances([this.other, this.target], [value1, value2]); + const tx = this.ethers.predeploy.entrypoint.v09.handleOps([operation.packed], this.beneficiary); + await expect(tx).to.changeEtherBalances(this.ethers, [this.other, this.target], [value1, value2]); await expect(tx).to.emit(this.target, 'MockFunctionCalledExtra').withArgs(this.mock, value2); await expect(this.mock.getNonce()).to.eventually.equal(1); }); }); }); } - -module.exports = { - shouldBehaveLikeERC7821, -}; diff --git a/test/account/utils/EIP7702Utils.test.js b/test/account/utils/EIP7702Utils.test.js index fb045f75325..8f042820b73 100644 --- a/test/account/utils/EIP7702Utils.test.js +++ b/test/account/utils/EIP7702Utils.test.js @@ -1,6 +1,10 @@ -const { ethers, config } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network, config } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); // [NOTE] // @@ -8,11 +12,13 @@ const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); // we have to instantiate the eoa AND the relayer manually using ethers 6.14.0 wallets. This can be improved when // @nomicfoundation/hardhat-ethers starts instantiating signers with 7702 support. const relayAuthorization = authorization => - ethers.Wallet.fromPhrase(config.networks.hardhat.accounts.mnemonic, ethers.provider).sendTransaction({ - to: ethers.ZeroAddress, - authorizationList: [authorization], - gasLimit: 46_000n, - }); + config.networks.default.accounts.mnemonic.get().then(mnemonic => + ethers.Wallet.fromPhrase(mnemonic, ethers.provider).sendTransaction({ + to: ethers.ZeroAddress, + authorizationList: [authorization], + gasLimit: 46_000n, + }), + ); const fixture = async () => { const eoa = ethers.Wallet.createRandom(ethers.provider); diff --git a/test/account/utils/draft-ERC4337Utils.test.js b/test/account/utils/draft-ERC4337Utils.test.js index e8cae5a621d..6022c3a3ddd 100644 --- a/test/account/utils/draft-ERC4337Utils.test.js +++ b/test/account/utils/draft-ERC4337Utils.test.js @@ -1,21 +1,25 @@ -const { ethers, predeploy } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { MAX_UINT48 } = require('../../helpers/constants'); -const { packValidationData, UserOperation } = require('../../helpers/erc4337'); -const { ValidationRange } = require('../../helpers/enums'); -const { clock, increaseTo } = require('../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT48 } from '../../helpers/constants'; +import { packValidationData, UserOperation } from '../../helpers/erc4337'; +import { ValidationRange } from '../../helpers/enums'; + +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = await network.create(); + const ADDRESS_ONE = '0x0000000000000000000000000000000000000001'; -const fixture = async () => { +async function fixture() { const [authorizer, sender, factory, paymaster] = await ethers.getSigners(); const utils = await ethers.deployContract('$ERC4337Utils'); const SIG_VALIDATION_SUCCESS = await utils.$SIG_VALIDATION_SUCCESS(); const SIG_VALIDATION_FAILED = await utils.$SIG_VALIDATION_FAILED(); return { utils, authorizer, sender, factory, paymaster, SIG_VALIDATION_SUCCESS, SIG_VALIDATION_FAILED }; -}; +} describe('ERC4337Utils', function () { beforeEach(async function () { @@ -24,15 +28,15 @@ describe('ERC4337Utils', function () { describe('entrypoint', function () { it('v0.7.0', async function () { - await expect(this.utils.$ENTRYPOINT_V07()).to.eventually.equal(predeploy.entrypoint.v07); + await expect(this.utils.$ENTRYPOINT_V07()).to.eventually.equal(ethers.predeploy.entrypoint.v07); }); it('v0.8.0', async function () { - await expect(this.utils.$ENTRYPOINT_V08()).to.eventually.equal(predeploy.entrypoint.v08); + await expect(this.utils.$ENTRYPOINT_V08()).to.eventually.equal(ethers.predeploy.entrypoint.v08); }); it('v0.9.0', async function () { - await expect(this.utils.$ENTRYPOINT_V09()).to.eventually.equal(predeploy.entrypoint.v09); + await expect(this.utils.$ENTRYPOINT_V09()).to.eventually.equal(ethers.predeploy.entrypoint.v09); }); }); @@ -385,11 +389,11 @@ describe('ERC4337Utils', function () { it('returns the validation data with invalid validity range (expired)', async function () { const aggregator = this.authorizer; - const validAfter = await clock[name](); + const validAfter = await time.clock[name](); const validUntil = validAfter + 10n; const validationData = packValidationData(validAfter, validUntil, aggregator, range); - await increaseTo[name](validUntil + 1n); + await time.increaseTo[name](validUntil + 1n); await expect(this.utils.$getValidationData(validationData)).to.eventually.deep.equal([ aggregator.address, true, @@ -398,7 +402,7 @@ describe('ERC4337Utils', function () { it('returns the validation data with invalid validity range (not yet valid)', async function () { const aggregator = this.authorizer; - const validAfter = (await clock[name]()) + 1n; + const validAfter = (await time.clock[name]()) + 1n; const validUntil = validAfter + 10n; const validationData = packValidationData(validAfter, validUntil, aggregator, range); @@ -410,7 +414,7 @@ describe('ERC4337Utils', function () { it('returns the validation data with invalid validity range (current == validAfter)', async function () { const aggregator = this.authorizer; - const validAfter = await clock[name](); + const validAfter = await time.clock[name](); const validUntil = validAfter + 10n; const validationData = packValidationData(validAfter, validUntil, aggregator, range); @@ -422,11 +426,11 @@ describe('ERC4337Utils', function () { it('returns the validation data with valid validity range (current == validUntil)', async function () { const aggregator = this.authorizer; - const validAfter = await clock[name](); + const validAfter = await time.clock[name](); const validUntil = validAfter + 10n; const validationData = packValidationData(validAfter, validUntil, aggregator, range); - await increaseTo[name](validUntil); + await time.increaseTo[name](validUntil); await expect(this.utils.$getValidationData(validationData)).to.eventually.deep.equal([ aggregator.address, false, @@ -440,8 +444,8 @@ describe('ERC4337Utils', function () { }); }); - describe('hash', function () { - for (const [version, instance] of Object.entries(predeploy.entrypoint)) { + describe('hash', async function () { + for (const [version, instance] of Object.entries(ethers.predeploy.entrypoint)) { it(`returns the operation hash for entrypoint ${version}`, async function () { const userOp = new UserOperation({ sender: this.sender, nonce: 1 }); const expected = await userOp.hash(instance); diff --git a/test/account/utils/draft-ERC7579Utils.t.sol b/test/account/utils/draft-ERC7579Utils.t.sol index bd7b9ad826e..b4a4e62c39a 100644 --- a/test/account/utils/draft-ERC7579Utils.t.sol +++ b/test/account/utils/draft-ERC7579Utils.t.sol @@ -394,7 +394,7 @@ contract ERC7579UtilsTest is Test { return useroperation.hash(address(ERC4337Utils.ENTRYPOINT_V07)); } - function _collectAndPrintLogs(bool includeTotalValue) internal { + function _collectAndPrintLogs(bool includeTotalValue) internal view { Vm.Log[] memory logs = vm.getRecordedLogs(); for (uint256 i = 0; i < logs.length; i++) { if (logs[i].emitter == _account) { diff --git a/test/account/utils/draft-ERC7579Utils.test.js b/test/account/utils/draft-ERC7579Utils.test.js index b0ca86c46fa..d485ccc90b7 100644 --- a/test/account/utils/draft-ERC7579Utils.test.js +++ b/test/account/utils/draft-ERC7579Utils.test.js @@ -1,7 +1,6 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { CALL_TYPE_CALL, CALL_TYPE_BATCH, CALL_TYPE_DELEGATE, @@ -11,10 +10,13 @@ const { encodeBatch, encodeDelegate, encodeMode, -} = require('../../helpers/erc7579'); -const { selector } = require('../../helpers/methods'); +} from '../../helpers/erc7579'; +import { selector } from '../../helpers/methods'; -const coder = ethers.AbiCoder.defaultAbiCoder(); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const fixture = async () => { const [sender] = await ethers.getSigners(); @@ -100,7 +102,10 @@ describe('ERC7579Utils', function () { CALL_TYPE_CALL, ethers.solidityPacked( ['bytes4', 'bytes'], - [selector('Error(string)'), coder.encode(['string'], ['CallReceiverMock: reverting'])], + [ + selector('Error(string)'), + ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['CallReceiverMock: reverting']), + ], ), ); }); @@ -188,7 +193,10 @@ describe('ERC7579Utils', function () { CALL_TYPE_BATCH, ethers.solidityPacked( ['bytes4', 'bytes'], - [selector('Error(string)'), coder.encode(['string'], ['CallReceiverMock: reverting'])], + [ + selector('Error(string)'), + ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['CallReceiverMock: reverting']), + ], ), ); @@ -251,7 +259,10 @@ describe('ERC7579Utils', function () { CALL_TYPE_CALL, ethers.solidityPacked( ['bytes4', 'bytes'], - [selector('Error(string)'), coder.encode(['string'], ['CallReceiverMock: reverting'])], + [ + selector('Error(string)'), + ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['CallReceiverMock: reverting']), + ], ), ); }); diff --git a/test/crosschain/BridgeERC1155.behavior.js b/test/crosschain/BridgeERC1155.behavior.js index a36d6a38ab2..0b664676333 100644 --- a/test/crosschain/BridgeERC1155.behavior.js +++ b/test/crosschain/BridgeERC1155.behavior.js @@ -1,29 +1,29 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; const ids = [17n, 42n]; const values = [100n, 320n]; -function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCustodial = false } = {}) { +export function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCustodial = false } = {}) { describe('bridge ERC1155 like', function () { beforeEach(function () { // helper this.encodePayload = (from, to, ids, values) => ethers.AbiCoder.defaultAbiCoder().encode( ['bytes', 'bytes', 'uint256[]', 'uint256[]'], - [this.chain.toErc7930(from), to.target ?? to.address ?? to, ids, values], + [this.helpers.chain.toErc7930(from), to.target ?? to.address ?? to, ids, values], ); }); it('bridge setup', async function () { - await expect(this.bridgeA.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeA.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ this.gateway.target, - this.chain.toErc7930(this.bridgeB), + this.helpers.chain.toErc7930(this.bridgeB), ]); - await expect(this.bridgeB.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeB.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ this.gateway.target, - this.chain.toErc7930(this.bridgeA), + this.helpers.chain.toErc7930(this.bridgeA), ]); }); @@ -38,7 +38,7 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.bridgeA.connect(alice).getFunction('crosschainTransferFrom(address,bytes,uint256,uint256)')( alice, - this.chain.toErc7930(bruce), + this.helpers.chain.toErc7930(bruce), ids[0], values[0], ), @@ -54,12 +54,12 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust ) // crosschain transfer sent .to.emit(this.bridgeA, 'CrosschainMultiTokenTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), ids.slice(0, 1), values.slice(0, 1)) + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), ids.slice(0, 1), values.slice(0, 1)) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeB, 'CrosschainMultiTokenTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(alice), bruce, ids.slice(0, 1), values.slice(0, 1)) + .withArgs(anyValue, this.helpers.chain.toErc7930(alice), bruce, ids.slice(0, 1), values.slice(0, 1)) // tokens are minted on chain B .to.emit(this.tokenB, 'TransferSingle') .withArgs( @@ -74,7 +74,7 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.bridgeB.connect(bruce).getFunction('crosschainTransferFrom(address,bytes,uint256,uint256)')( bruce, - this.chain.toErc7930(chris), + this.helpers.chain.toErc7930(chris), ids[0], values[0], ), @@ -90,12 +90,12 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust ) // crosschain transfer sent .to.emit(this.bridgeB, 'CrosschainMultiTokenTransferSent') - .withArgs(anyValue, bruce, this.chain.toErc7930(chris), ids.slice(0, 1), values.slice(0, 1)) + .withArgs(anyValue, bruce, this.helpers.chain.toErc7930(chris), ids.slice(0, 1), values.slice(0, 1)) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeA, 'CrosschainMultiTokenTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(bruce), chris, ids.slice(0, 1), values.slice(0, 1)) + .withArgs(anyValue, this.helpers.chain.toErc7930(bruce), chris, ids.slice(0, 1), values.slice(0, 1)) // bridge on chain A releases custody of the token .to.emit(this.tokenA, 'TransferSingle') .withArgs( @@ -117,7 +117,7 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.bridgeA.connect(alice).getFunction('crosschainTransferFrom(address,bytes,uint256[],uint256[])')( alice, - this.chain.toErc7930(bruce), + this.helpers.chain.toErc7930(bruce), ids, values, ), @@ -133,12 +133,12 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust ) // crosschain transfer sent .to.emit(this.bridgeA, 'CrosschainMultiTokenTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), ids, values) + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), ids, values) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeB, 'CrosschainMultiTokenTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(alice), bruce, ids, values) + .withArgs(anyValue, this.helpers.chain.toErc7930(alice), bruce, ids, values) // tokens are minted on chain B .to.emit(this.tokenB, 'TransferBatch') .withArgs( @@ -153,7 +153,7 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.bridgeB.connect(bruce).getFunction('crosschainTransferFrom(address,bytes,uint256[],uint256[])')( bruce, - this.chain.toErc7930(chris), + this.helpers.chain.toErc7930(chris), ids, values, ), @@ -169,12 +169,12 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust ) // crosschain transfer sent .to.emit(this.bridgeB, 'CrosschainMultiTokenTransferSent') - .withArgs(anyValue, bruce, this.chain.toErc7930(chris), ids, values) + .withArgs(anyValue, bruce, this.helpers.chain.toErc7930(chris), ids, values) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeA, 'CrosschainMultiTokenTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(bruce), chris, ids, values) + .withArgs(anyValue, this.helpers.chain.toErc7930(bruce), chris, ids, values) // bridge on chain A releases custody of the token .to.emit(this.tokenA, 'TransferBatch') .withArgs( @@ -197,13 +197,13 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.bridgeA.connect(alice).getFunction('crosschainTransferFrom(address,bytes,uint256[],uint256[])')( alice, - this.chain.toErc7930(bruce), + this.helpers.chain.toErc7930(bruce), ids, values, ), ) .to.emit(this.bridgeA, 'CrosschainMultiTokenTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), ids, values); + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), ids, values); }); it('spender is allowed for all', async function () { @@ -216,13 +216,13 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.bridgeA.connect(chris).getFunction('crosschainTransferFrom(address,bytes,uint256[],uint256[])')( alice, - this.chain.toErc7930(bruce), + this.helpers.chain.toErc7930(bruce), ids, values, ), ) .to.emit(this.bridgeA, 'CrosschainMultiTokenTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), ids, values); + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), ids, values); }); }); @@ -237,7 +237,7 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.bridgeA.connect(chris).getFunction('crosschainTransferFrom(address,bytes,uint256[],uint256[])')( alice, - this.chain.toErc7930(bruce), + this.helpers.chain.toErc7930(bruce), ids, values, ), @@ -254,7 +254,7 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.bridgeA.connect(alice).getFunction('crosschainTransferFrom(address,bytes,uint256[],uint256[])')( alice, - this.chain.toErc7930(bruce), + this.helpers.chain.toErc7930(bruce), ids, values, ), @@ -273,12 +273,12 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust .connect(notGateway) .receiveMessage( ethers.ZeroHash, - this.chain.toErc7930(this.tokenB), + this.helpers.chain.toErc7930(this.tokenB), this.encodePayload(notGateway, notGateway, ids, values), ), ) .to.be.revertedWithCustomError(this.bridgeA, 'ERC7786RecipientUnauthorizedGateway') - .withArgs(notGateway, this.chain.toErc7930(this.tokenB)); + .withArgs(notGateway, this.helpers.chain.toErc7930(this.tokenB)); }); it('only counterpart can send a crosschain message', async function () { @@ -287,47 +287,47 @@ function shouldBehaveLikeBridgeERC1155({ chainAIsCustodial = false, chainBIsCust await expect( this.gateway .connect(invalid) - .sendMessage(this.chain.toErc7930(this.bridgeA), this.encodePayload(invalid, invalid, ids, values), []), + .sendMessage( + this.helpers.chain.toErc7930(this.bridgeA), + this.encodePayload(invalid, invalid, ids, values), + [], + ), ) .to.be.revertedWithCustomError(this.bridgeA, 'ERC7786RecipientUnauthorizedGateway') - .withArgs(this.gateway, this.chain.toErc7930(invalid)); + .withArgs(this.gateway, this.helpers.chain.toErc7930(invalid)); }); }); describe('reconfiguration', function () { it('updating a link emits an event', async function () { - const newGateway = await ethers.deployContract('$ERC7786GatewayMock'); - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newGateway = await this.ethers.deployContract('$ERC7786GatewayMock'); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); await expect(this.bridgeA.$_setLink(newGateway, newCounterpart, true)) .to.emit(this.bridgeA, 'LinkRegistered') .withArgs(newGateway, newCounterpart); - await expect(this.bridgeA.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeA.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ newGateway.target, newCounterpart, ]); }); it('cannot override configuration if "allowOverride" is false', async function () { - const newGateway = await ethers.deployContract('$ERC7786GatewayMock'); - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newGateway = await this.ethers.deployContract('$ERC7786GatewayMock'); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); await expect(this.bridgeA.$_setLink(newGateway, newCounterpart, false)) .to.be.revertedWithCustomError(this.bridgeA, 'LinkAlreadyRegistered') - .withArgs(this.chain.erc7930); + .withArgs(this.helpers.chain.erc7930); }); it('reject invalid gateway', async function () { const notAGateway = this.accounts[0]; - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); await expect(this.bridgeA.$_setLink(notAGateway, newCounterpart, false)).to.be.revertedWithoutReason(); }); }); }); } - -module.exports = { - shouldBehaveLikeBridgeERC1155, -}; diff --git a/test/crosschain/BridgeERC1155.test.js b/test/crosschain/BridgeERC1155.test.js index eccabb07747..8ef9f0e29b6 100644 --- a/test/crosschain/BridgeERC1155.test.js +++ b/test/crosschain/BridgeERC1155.test.js @@ -1,14 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeBridgeERC1155 } from './BridgeERC1155.behavior'; -const { impersonate } = require('../helpers/account'); -const { getLocalChain } = require('../helpers/chains'); - -const { shouldBehaveLikeBridgeERC1155 } = require('./BridgeERC1155.behavior'); +const connection = await network.create(); +const { + ethers, + helpers: { chain, impersonate }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { - const chain = await getLocalChain(); const accounts = await ethers.getSigners(); // Mock gateway @@ -31,12 +32,12 @@ async function fixture() { .to.emit(bridgeA, 'LinkRegistered') .withArgs(gateway, chain.toErc7930(bridgeB)); - return { chain, accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; + return { accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; } describe('CrosschainBridgeERC1155', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); it('token getters', async function () { diff --git a/test/crosschain/BridgeERC20.behavior.js b/test/crosschain/BridgeERC20.behavior.js index 3e54114bee2..bc652a6e93b 100644 --- a/test/crosschain/BridgeERC20.behavior.js +++ b/test/crosschain/BridgeERC20.behavior.js @@ -1,28 +1,28 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; const amount = 100n; -function shouldBehaveLikeBridgeERC20({ chainAIsCustodial = false, chainBIsCustodial = false } = {}) { +export function shouldBehaveLikeBridgeERC20({ chainAIsCustodial = false, chainBIsCustodial = false } = {}) { describe('bridge ERC20 like', function () { beforeEach(function () { // helper this.encodePayload = (from, to, amount) => ethers.AbiCoder.defaultAbiCoder().encode( ['bytes', 'bytes', 'uint256'], - [this.chain.toErc7930(from), to.target ?? to.address ?? to, amount], + [this.helpers.chain.toErc7930(from), to.target ?? to.address ?? to, amount], ); }); it('bridge setup', async function () { - await expect(this.bridgeA.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeA.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ this.gateway.target, - this.chain.toErc7930(this.bridgeB), + this.helpers.chain.toErc7930(this.bridgeB), ]); - await expect(this.bridgeB.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeB.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ this.gateway.target, - this.chain.toErc7930(this.bridgeA), + this.helpers.chain.toErc7930(this.bridgeA), ]); }); @@ -33,18 +33,18 @@ function shouldBehaveLikeBridgeERC20({ chainAIsCustodial = false, chainBIsCustod await this.tokenA.connect(alice).approve(this.bridgeA, ethers.MaxUint256); // Alice sends tokens from chain A to Bruce on chain B. - await expect(this.bridgeA.connect(alice).crosschainTransfer(this.chain.toErc7930(bruce), amount)) + await expect(this.bridgeA.connect(alice).crosschainTransfer(this.helpers.chain.toErc7930(bruce), amount)) // bridge on chain A takes custody of the funds .to.emit(this.tokenA, 'Transfer') .withArgs(alice, chainAIsCustodial ? this.bridgeA : ethers.ZeroAddress, amount) // crosschain transfer sent .to.emit(this.bridgeA, 'CrosschainFungibleTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), amount) + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), amount) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeB, 'CrosschainFungibleTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(alice), bruce, amount) + .withArgs(anyValue, this.helpers.chain.toErc7930(alice), bruce, amount) // crosschain mint event .to.emit(this.tokenB, 'CrosschainMint') .withArgs(bruce, amount, this.bridgeB) @@ -53,7 +53,7 @@ function shouldBehaveLikeBridgeERC20({ chainAIsCustodial = false, chainBIsCustod .withArgs(chainBIsCustodial ? this.bridgeB : ethers.ZeroAddress, bruce, amount); // Bruce sends tokens from chain B to Chris on chain A. - await expect(this.bridgeB.connect(bruce).crosschainTransfer(this.chain.toErc7930(chris), amount)) + await expect(this.bridgeB.connect(bruce).crosschainTransfer(this.helpers.chain.toErc7930(chris), amount)) // tokens are burned on chain B .to.emit(this.tokenB, 'Transfer') .withArgs(bruce, chainBIsCustodial ? this.bridgeB : ethers.ZeroAddress, amount) @@ -62,12 +62,12 @@ function shouldBehaveLikeBridgeERC20({ chainAIsCustodial = false, chainBIsCustod .withArgs(bruce, amount, this.bridgeB) // crosschain transfer sent .to.emit(this.bridgeB, 'CrosschainFungibleTransferSent') - .withArgs(anyValue, bruce, this.chain.toErc7930(chris), amount) + .withArgs(anyValue, bruce, this.helpers.chain.toErc7930(chris), amount) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeA, 'CrosschainFungibleTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(bruce), chris, amount) + .withArgs(anyValue, this.helpers.chain.toErc7930(bruce), chris, amount) // bridge on chain A releases custody of the funds .to.emit(this.tokenA, 'Transfer') .withArgs(chainAIsCustodial ? this.bridgeA : ethers.ZeroAddress, chris, amount); @@ -86,12 +86,12 @@ function shouldBehaveLikeBridgeERC20({ chainAIsCustodial = false, chainBIsCustod .connect(notGateway) .receiveMessage( ethers.ZeroHash, - this.chain.toErc7930(this.tokenB), + this.helpers.chain.toErc7930(this.tokenB), this.encodePayload(notGateway, notGateway, amount), ), ) .to.be.revertedWithCustomError(this.bridgeA, 'ERC7786RecipientUnauthorizedGateway') - .withArgs(notGateway, this.chain.toErc7930(this.tokenB)); + .withArgs(notGateway, this.helpers.chain.toErc7930(this.tokenB)); }); it('only counterpart can send a crosschain message', async function () { @@ -100,47 +100,43 @@ function shouldBehaveLikeBridgeERC20({ chainAIsCustodial = false, chainBIsCustod await expect( this.gateway .connect(invalid) - .sendMessage(this.chain.toErc7930(this.bridgeA), this.encodePayload(invalid, invalid, amount), []), + .sendMessage(this.helpers.chain.toErc7930(this.bridgeA), this.encodePayload(invalid, invalid, amount), []), ) .to.be.revertedWithCustomError(this.bridgeA, 'ERC7786RecipientUnauthorizedGateway') - .withArgs(this.gateway, this.chain.toErc7930(invalid)); + .withArgs(this.gateway, this.helpers.chain.toErc7930(invalid)); }); }); describe('reconfiguration', function () { it('updating a link emits an event', async function () { - const newGateway = await ethers.deployContract('$ERC7786GatewayMock'); - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newGateway = await this.ethers.deployContract('$ERC7786GatewayMock'); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); await expect(this.bridgeA.$_setLink(newGateway, newCounterpart, true)) .to.emit(this.bridgeA, 'LinkRegistered') .withArgs(newGateway, newCounterpart); - await expect(this.bridgeA.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeA.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ newGateway.target, newCounterpart, ]); }); it('cannot override configuration is "allowOverride" is false', async function () { - const newGateway = await ethers.deployContract('$ERC7786GatewayMock'); - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newGateway = await this.ethers.deployContract('$ERC7786GatewayMock'); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); await expect(this.bridgeA.$_setLink(newGateway, newCounterpart, false)) .to.be.revertedWithCustomError(this.bridgeA, 'LinkAlreadyRegistered') - .withArgs(this.chain.erc7930); + .withArgs(this.helpers.chain.erc7930); }); it('reject invalid gateway', async function () { const notAGateway = this.accounts[0]; - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); - await expect(this.bridgeA.$_setLink(notAGateway, newCounterpart, false)).to.be.revertedWithoutReason(); + await expect(this.bridgeA.$_setLink(notAGateway, newCounterpart, false)).to.be.revertedWithoutReason(ethers); }); }); }); } - -module.exports = { - shouldBehaveLikeBridgeERC20, -}; diff --git a/test/crosschain/BridgeERC20.test.js b/test/crosschain/BridgeERC20.test.js index 1e20d491cfd..e9e3e8b1bfc 100644 --- a/test/crosschain/BridgeERC20.test.js +++ b/test/crosschain/BridgeERC20.test.js @@ -1,14 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeBridgeERC20 } from './BridgeERC20.behavior'; -const { impersonate } = require('../helpers/account'); -const { getLocalChain } = require('../helpers/chains'); - -const { shouldBehaveLikeBridgeERC20 } = require('./BridgeERC20.behavior'); +const connection = await network.create(); +const { + ethers, + helpers: { chain, impersonate }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { - const chain = await getLocalChain(); const accounts = await ethers.getSigners(); // Mock gateway @@ -29,12 +30,12 @@ async function fixture() { .withArgs(gateway, chain.toErc7930(bridgeB)); await tokenB.$_setBridge(bridgeB); - return { chain, accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; + return { accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; } describe('CrosschainBridgeERC20', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); it('token getters', async function () { diff --git a/test/crosschain/BridgeERC721.behavior.js b/test/crosschain/BridgeERC721.behavior.js index 41cbdab7f9c..3bb0927cecd 100644 --- a/test/crosschain/BridgeERC721.behavior.js +++ b/test/crosschain/BridgeERC721.behavior.js @@ -1,28 +1,28 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; const tokenId = 42n; -function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCustodial = false } = {}) { +export function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCustodial = false } = {}) { describe('bridge ERC721 like', function () { beforeEach(function () { // helper this.encodePayload = (from, to, tokenId) => ethers.AbiCoder.defaultAbiCoder().encode( ['bytes', 'bytes', 'uint256'], - [this.chain.toErc7930(from), to.target ?? to.address ?? to, tokenId], + [this.helpers.chain.toErc7930(from), to.target ?? to.address ?? to, tokenId], ); }); it('bridge setup', async function () { - await expect(this.bridgeA.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeA.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ this.gateway.target, - this.chain.toErc7930(this.bridgeB), + this.helpers.chain.toErc7930(this.bridgeB), ]); - await expect(this.bridgeB.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeB.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ this.gateway.target, - this.chain.toErc7930(this.bridgeA), + this.helpers.chain.toErc7930(this.bridgeA), ]); }); @@ -33,35 +33,39 @@ function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCusto await this.tokenA.connect(alice).setApprovalForAll(this.bridgeA, true); // Alice sends tokens from chain A to Bruce on chain B. - await expect(this.bridgeA.connect(alice).crosschainTransferFrom(alice, this.chain.toErc7930(bruce), tokenId)) + await expect( + this.bridgeA.connect(alice).crosschainTransferFrom(alice, this.helpers.chain.toErc7930(bruce), tokenId), + ) // bridge on chain A takes custody of the token .to.emit(this.tokenA, 'Transfer') .withArgs(alice, chainAIsCustodial ? this.bridgeA : ethers.ZeroAddress, tokenId) // crosschain transfer sent .to.emit(this.bridgeA, 'CrosschainNonFungibleTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), tokenId) + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), tokenId) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeB, 'CrosschainNonFungibleTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(alice), bruce, tokenId) + .withArgs(anyValue, this.helpers.chain.toErc7930(alice), bruce, tokenId) // tokens are minted on chain B .to.emit(this.tokenB, 'Transfer') .withArgs(chainBIsCustodial ? this.bridgeB : ethers.ZeroAddress, bruce, tokenId); // Bruce sends tokens from chain B to Chris on chain A. - await expect(this.bridgeB.connect(bruce).crosschainTransferFrom(bruce, this.chain.toErc7930(chris), tokenId)) + await expect( + this.bridgeB.connect(bruce).crosschainTransferFrom(bruce, this.helpers.chain.toErc7930(chris), tokenId), + ) // tokens are burned on chain B .to.emit(this.tokenB, 'Transfer') .withArgs(bruce, chainBIsCustodial ? this.bridgeB : ethers.ZeroAddress, tokenId) // crosschain transfer sent .to.emit(this.bridgeB, 'CrosschainNonFungibleTransferSent') - .withArgs(anyValue, bruce, this.chain.toErc7930(chris), tokenId) + .withArgs(anyValue, bruce, this.helpers.chain.toErc7930(chris), tokenId) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeA, 'CrosschainNonFungibleTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(bruce), chris, tokenId) + .withArgs(anyValue, this.helpers.chain.toErc7930(bruce), chris, tokenId) // bridge on chain A releases custody of the token .to.emit(this.tokenA, 'Transfer') .withArgs(chainAIsCustodial ? this.bridgeA : ethers.ZeroAddress, chris, tokenId); @@ -75,9 +79,11 @@ function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCusto await this.tokenA.$_mint(alice, tokenId); await this.tokenA.connect(alice).setApprovalForAll(this.bridgeA, true); - await expect(this.bridgeA.connect(alice).crosschainTransferFrom(alice, this.chain.toErc7930(bruce), tokenId)) + await expect( + this.bridgeA.connect(alice).crosschainTransferFrom(alice, this.helpers.chain.toErc7930(bruce), tokenId), + ) .to.emit(this.bridgeA, 'CrosschainNonFungibleTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), tokenId); + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), tokenId); }); it('spender is allowed for all', async function () { @@ -89,14 +95,18 @@ function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCusto await this.tokenA.connect(alice).setApprovalForAll(chris, true); // david is not allowed - await expect(this.bridgeA.connect(david).crosschainTransferFrom(alice, this.chain.toErc7930(bruce), tokenId)) + await expect( + this.bridgeA.connect(david).crosschainTransferFrom(alice, this.helpers.chain.toErc7930(bruce), tokenId), + ) .to.be.revertedWithCustomError(this.tokenA, 'ERC721InsufficientApproval') .withArgs(david, tokenId); // chris is allowed - await expect(this.bridgeA.connect(chris).crosschainTransferFrom(alice, this.chain.toErc7930(bruce), tokenId)) + await expect( + this.bridgeA.connect(chris).crosschainTransferFrom(alice, this.helpers.chain.toErc7930(bruce), tokenId), + ) .to.emit(this.bridgeA, 'CrosschainNonFungibleTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), tokenId); + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), tokenId); }); it('spender is allowed for specific token', async function () { @@ -111,15 +121,17 @@ function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCusto // chris is not allowed to transfer otherTokenId await expect( - this.bridgeA.connect(chris).crosschainTransferFrom(alice, this.chain.toErc7930(bruce), otherTokenId), + this.bridgeA.connect(chris).crosschainTransferFrom(alice, this.helpers.chain.toErc7930(bruce), otherTokenId), ) .to.be.revertedWithCustomError(this.tokenA, 'ERC721InsufficientApproval') .withArgs(chris, otherTokenId); // chris is allowed to transfer tokenId - await expect(this.bridgeA.connect(chris).crosschainTransferFrom(alice, this.chain.toErc7930(bruce), tokenId)) + await expect( + this.bridgeA.connect(chris).crosschainTransferFrom(alice, this.helpers.chain.toErc7930(bruce), tokenId), + ) .to.emit(this.bridgeA, 'CrosschainNonFungibleTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), tokenId); + .withArgs(anyValue, alice, this.helpers.chain.toErc7930(bruce), tokenId); }); }); @@ -129,7 +141,9 @@ function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCusto const tokenId = 17n; await expect( - this.bridgeA.connect(alice).crosschainTransferFrom(ethers.ZeroAddress, this.chain.toErc7930(bruce), tokenId), + this.bridgeA + .connect(alice) + .crosschainTransferFrom(ethers.ZeroAddress, this.helpers.chain.toErc7930(bruce), tokenId), ) .to.be.revertedWithCustomError(this.tokenA, 'ERC721NonexistentToken') .withArgs(tokenId); @@ -143,7 +157,9 @@ function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCusto await this.tokenA.connect(alice).setApprovalForAll(this.bridgeA, true); await this.tokenA.connect(alice).setApprovalForAll(bruce, true); - await expect(this.bridgeA.connect(bruce).crosschainTransferFrom(bruce, this.chain.toErc7930(bruce), tokenId)) + await expect( + this.bridgeA.connect(bruce).crosschainTransferFrom(bruce, this.helpers.chain.toErc7930(bruce), tokenId), + ) .to.be.revertedWithCustomError(this.tokenA, 'ERC721IncorrectOwner') .withArgs(bruce, tokenId, alice); }); @@ -158,12 +174,12 @@ function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCusto .connect(notGateway) .receiveMessage( ethers.ZeroHash, - this.chain.toErc7930(this.tokenB), + this.helpers.chain.toErc7930(this.tokenB), this.encodePayload(notGateway, notGateway, tokenId), ), ) .to.be.revertedWithCustomError(this.bridgeA, 'ERC7786RecipientUnauthorizedGateway') - .withArgs(notGateway, this.chain.toErc7930(this.tokenB)); + .withArgs(notGateway, this.helpers.chain.toErc7930(this.tokenB)); }); it('only counterpart can send a crosschain message', async function () { @@ -172,47 +188,43 @@ function shouldBehaveLikeBridgeERC721({ chainAIsCustodial = false, chainBIsCusto await expect( this.gateway .connect(invalid) - .sendMessage(this.chain.toErc7930(this.bridgeA), this.encodePayload(invalid, invalid, tokenId), []), + .sendMessage(this.helpers.chain.toErc7930(this.bridgeA), this.encodePayload(invalid, invalid, tokenId), []), ) .to.be.revertedWithCustomError(this.bridgeA, 'ERC7786RecipientUnauthorizedGateway') - .withArgs(this.gateway, this.chain.toErc7930(invalid)); + .withArgs(this.gateway, this.helpers.chain.toErc7930(invalid)); }); }); describe('reconfiguration', function () { it('updating a link emits an event', async function () { - const newGateway = await ethers.deployContract('$ERC7786GatewayMock'); - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newGateway = await this.ethers.deployContract('$ERC7786GatewayMock'); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); await expect(this.bridgeA.$_setLink(newGateway, newCounterpart, true)) .to.emit(this.bridgeA, 'LinkRegistered') .withArgs(newGateway, newCounterpart); - await expect(this.bridgeA.getLink(this.chain.erc7930)).to.eventually.deep.equal([ + await expect(this.bridgeA.getLink(this.helpers.chain.erc7930)).to.eventually.deep.equal([ newGateway.target, newCounterpart, ]); }); it('cannot override configuration if "allowOverride" is false', async function () { - const newGateway = await ethers.deployContract('$ERC7786GatewayMock'); - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newGateway = await this.ethers.deployContract('$ERC7786GatewayMock'); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); await expect(this.bridgeA.$_setLink(newGateway, newCounterpart, false)) .to.be.revertedWithCustomError(this.bridgeA, 'LinkAlreadyRegistered') - .withArgs(this.chain.erc7930); + .withArgs(this.helpers.chain.erc7930); }); it('reject invalid gateway', async function () { const notAGateway = this.accounts[0]; - const newCounterpart = this.chain.toErc7930(this.accounts[0]); + const newCounterpart = this.helpers.chain.toErc7930(this.accounts[0]); await expect(this.bridgeA.$_setLink(notAGateway, newCounterpart, false)).to.be.revertedWithoutReason(); }); }); }); } - -module.exports = { - shouldBehaveLikeBridgeERC721, -}; diff --git a/test/crosschain/BridgeERC721.test.js b/test/crosschain/BridgeERC721.test.js index fa4c6939cec..cc4d21ab6f3 100644 --- a/test/crosschain/BridgeERC721.test.js +++ b/test/crosschain/BridgeERC721.test.js @@ -1,14 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeBridgeERC721 } from './BridgeERC721.behavior'; -const { impersonate } = require('../helpers/account'); -const { getLocalChain } = require('../helpers/chains'); - -const { shouldBehaveLikeBridgeERC721 } = require('./BridgeERC721.behavior'); +const connection = await network.create(); +const { + ethers, + helpers: { chain, impersonate }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { - const chain = await getLocalChain(); const accounts = await ethers.getSigners(); // Mock gateway @@ -32,12 +33,12 @@ async function fixture() { .to.emit(bridgeA, 'LinkRegistered') .withArgs(gateway, chain.toErc7930(bridgeB)); - return { chain, accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; + return { accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; } describe('CrosschainBridgeERC721', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); it('token getters', async function () { diff --git a/test/crosschain/CrosschainExecutor.test.js b/test/crosschain/CrosschainExecutor.test.js index f957d5eee86..342e91575c6 100644 --- a/test/crosschain/CrosschainExecutor.test.js +++ b/test/crosschain/CrosschainExecutor.test.js @@ -1,20 +1,24 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; -const { getLocalChain } = require('../helpers/chains'); -const { - CALL_TYPE_SINGLE, +import { + CALL_TYPE_CALL, CALL_TYPE_BATCH, CALL_TYPE_DELEGATE, encodeMode, encodeSingle, encodeBatch, encodeDelegate, -} = require('../helpers/erc7579'); +} from '../helpers/erc7579'; + +const connection = await network.create(); +const { + ethers, + helpers: { chain }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { - const chain = await getLocalChain(); const [admin, other] = await ethers.getSigners(); const gateway = await ethers.deployContract('$ERC7786GatewayMock'); @@ -26,7 +30,7 @@ async function fixture() { const remoteExecute = (from, target, mode, data) => gateway.connect(from).sendMessage(target, ethers.concat([mode, data]), []); - return { chain, gateway, target, executor, admin, other, remoteExecute }; + return { gateway, target, executor, admin, other, remoteExecute }; } describe('CrosschainRemoteController & CrosschainRemoteExecutor', function () { @@ -36,15 +40,15 @@ describe('CrosschainRemoteController & CrosschainRemoteExecutor', function () { it('setup', async function () { await expect(this.executor.gateway()).to.eventually.equal(this.gateway); - await expect(this.executor.controller()).to.eventually.equal(this.chain.toErc7930(this.admin)); + await expect(this.executor.controller()).to.eventually.equal(chain.toErc7930(this.admin)); }); describe('crosschain operation', function () { it('support single mode', async function () { - const mode = encodeMode({ callType: CALL_TYPE_SINGLE }); + const mode = encodeMode({ callType: CALL_TYPE_CALL }); const data = encodeSingle(this.target, 0n, this.target.interface.encodeFunctionData('mockFunctionExtra')); - await expect(this.remoteExecute(this.admin, this.chain.toErc7930(this.executor), mode, data)) + await expect(this.remoteExecute(this.admin, chain.toErc7930(this.executor), mode, data)) .to.emit(this.target, 'MockFunctionCalledExtra') .withArgs(this.executor, 0n); }); @@ -56,7 +60,7 @@ describe('CrosschainRemoteController & CrosschainRemoteExecutor', function () { [this.target, 0n, this.target.interface.encodeFunctionData('mockFunctionExtra')], ); - await expect(this.remoteExecute(this.admin, this.chain.toErc7930(this.executor), mode, data)) + await expect(this.remoteExecute(this.admin, chain.toErc7930(this.executor), mode, data)) .to.emit(this.target, 'MockFunctionCalledWithArgs') .withArgs(42, '0x1234') .to.emit(this.target, 'MockFunctionCalledExtra') @@ -67,7 +71,7 @@ describe('CrosschainRemoteController & CrosschainRemoteExecutor', function () { const mode = encodeMode({ callType: CALL_TYPE_DELEGATE }); const data = encodeDelegate(this.target, this.target.interface.encodeFunctionData('mockFunctionExtra')); - await expect(this.remoteExecute(this.admin, this.chain.toErc7930(this.executor), mode, data)) + await expect(this.remoteExecute(this.admin, chain.toErc7930(this.executor), mode, data)) .to.emit(this.target.attach(this.executor.target), 'MockFunctionCalledExtra') .withArgs(this.gateway, 0n); }); @@ -76,7 +80,7 @@ describe('CrosschainRemoteController & CrosschainRemoteExecutor', function () { const mode = encodeMode({ callType: '0x42' }); const data = '0x'; - await expect(this.remoteExecute(this.admin, this.chain.toErc7930(this.executor), mode, data)) + await expect(this.remoteExecute(this.admin, chain.toErc7930(this.executor), mode, data)) .to.be.revertedWithCustomError(this.executor, 'ERC7579UnsupportedCallType') .withArgs('0x42'); }); @@ -88,56 +92,53 @@ describe('CrosschainRemoteController & CrosschainRemoteExecutor', function () { }); it('through a crosschain call: success', async function () { - const mode = encodeMode({ callType: CALL_TYPE_SINGLE }); + const mode = encodeMode({ callType: CALL_TYPE_CALL }); const data = encodeSingle( this.executor, 0n, this.executor.interface.encodeFunctionData('reconfigure', [ this.newGateway.target, - this.chain.toErc7930(this.other), + chain.toErc7930(this.other), ]), ); - await expect(this.remoteExecute(this.admin, this.chain.toErc7930(this.executor), mode, data)) + await expect(this.remoteExecute(this.admin, chain.toErc7930(this.executor), mode, data)) .to.emit(this.executor, 'CrosschainControllerSet') - .withArgs(this.newGateway, this.chain.toErc7930(this.other)); + .withArgs(this.newGateway, chain.toErc7930(this.other)); await expect(this.executor.gateway()).to.eventually.equal(this.newGateway); - await expect(this.executor.controller()).to.eventually.equal(this.chain.toErc7930(this.other)); + await expect(this.executor.controller()).to.eventually.equal(chain.toErc7930(this.other)); }); it('through the internal setter: success', async function () { - await expect(this.executor.$_setup(this.newGateway, this.chain.toErc7930(this.other))) + await expect(this.executor.$_setup(this.newGateway, chain.toErc7930(this.other))) .to.emit(this.executor, 'CrosschainControllerSet') - .withArgs(this.newGateway, this.chain.toErc7930(this.other)); + .withArgs(this.newGateway, chain.toErc7930(this.other)); await expect(this.executor.gateway()).to.eventually.equal(this.newGateway); - await expect(this.executor.controller()).to.eventually.equal(this.chain.toErc7930(this.other)); + await expect(this.executor.controller()).to.eventually.equal(chain.toErc7930(this.other)); }); it('with an invalid new gateway: revert', async function () { // directly using the internal setter - await expect(this.executor.$_setup(this.other, this.chain.toErc7930(this.other))).to.be.reverted; + await expect(this.executor.$_setup(this.other, chain.toErc7930(this.other))).to.be.revert(ethers); // through a crosschain call - const mode = encodeMode({ callType: CALL_TYPE_SINGLE }); + const mode = encodeMode({ callType: CALL_TYPE_CALL }); const data = encodeSingle( this.executor, 0n, - this.executor.interface.encodeFunctionData('reconfigure', [ - this.other.address, - this.chain.toErc7930(this.other), - ]), + this.executor.interface.encodeFunctionData('reconfigure', [this.other.address, chain.toErc7930(this.other)]), ); await expect( - this.remoteExecute(this.admin, this.chain.toErc7930(this.executor), mode, data), + this.remoteExecute(this.admin, chain.toErc7930(this.executor), mode, data), ).to.be.revertedWithCustomError(this.executor, 'FailedCall'); }); it('is access controlled', async function () { await expect( - this.executor.reconfigure(this.newGateway, this.chain.toErc7930(this.other)), + this.executor.reconfigure(this.newGateway, chain.toErc7930(this.other)), ).to.be.revertedWithCustomError(this.executor, 'AccessRestricted'); }); }); diff --git a/test/crosschain/ERC7786Recipient.test.js b/test/crosschain/ERC7786Recipient.test.js index 3af65b1ffbd..e9da9939ba1 100644 --- a/test/crosschain/ERC7786Recipient.test.js +++ b/test/crosschain/ERC7786Recipient.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { generators } from '../helpers/random'; -const { getLocalChain } = require('../helpers/chains'); -const { generators } = require('../helpers/random'); +const { + ethers, + helpers: { chain }, + networkHelpers: { loadFixture }, +} = await network.create(); const value = 42n; const payload = generators.hexBytes(128); @@ -11,12 +14,11 @@ const attributes = []; async function fixture() { const [sender, notAGateway] = await ethers.getSigners(); - const { toErc7930 } = await getLocalChain(); const gateway = await ethers.deployContract('$ERC7786GatewayMock'); const receiver = await ethers.deployContract('$ERC7786RecipientMock', [gateway]); - return { sender, notAGateway, gateway, receiver, toErc7930 }; + return { sender, notAGateway, gateway, receiver }; } // NOTE: here we are only testing the receiver. Failures of the gateway itself (invalid attributes, ...) are out of scope. @@ -27,29 +29,36 @@ describe('ERC7786Recipient', function () { it('receives gateway relayed messages', async function () { await expect( - this.gateway.connect(this.sender).sendMessage(this.toErc7930(this.receiver), payload, attributes, { value }), + this.gateway.connect(this.sender).sendMessage(chain.toErc7930(this.receiver), payload, attributes, { value }), ) .to.emit(this.gateway, 'MessageSent') - .withArgs(ethers.ZeroHash, this.toErc7930(this.sender), this.toErc7930(this.receiver), payload, value, attributes) + .withArgs( + ethers.ZeroHash, + chain.toErc7930(this.sender), + chain.toErc7930(this.receiver), + payload, + value, + attributes, + ) .to.emit(this.receiver, 'MessageReceived') - .withArgs(this.gateway, ethers.toBeHex(1n, 32n), this.toErc7930(this.sender), payload, value); + .withArgs(this.gateway, ethers.toBeHex(1n, 32n), chain.toErc7930(this.sender), payload, value); }); it('receive multiple similar messages', async function () { for (let i = 1n; i < 5n; ++i) { await expect( - this.gateway.connect(this.sender).sendMessage(this.toErc7930(this.receiver), payload, attributes, { value }), + this.gateway.connect(this.sender).sendMessage(chain.toErc7930(this.receiver), payload, attributes, { value }), ) .to.emit(this.receiver, 'MessageReceived') - .withArgs(this.gateway, ethers.toBeHex(i, 32n), this.toErc7930(this.sender), payload, value); + .withArgs(this.gateway, ethers.toBeHex(i, 32n), chain.toErc7930(this.sender), payload, value); } }); it('unauthorized call', async function () { await expect( - this.receiver.connect(this.notAGateway).receiveMessage(ethers.ZeroHash, this.toErc7930(this.sender), payload), + this.receiver.connect(this.notAGateway).receiveMessage(ethers.ZeroHash, chain.toErc7930(this.sender), payload), ) .to.be.revertedWithCustomError(this.receiver, 'ERC7786RecipientUnauthorizedGateway') - .withArgs(this.notAGateway, this.toErc7930(this.sender)); + .withArgs(this.notAGateway, chain.toErc7930(this.sender)); }); }); diff --git a/test/finance/VestingWallet.behavior.js b/test/finance/VestingWallet.behavior.js index b45ffeecfd3..b6b9940646a 100644 --- a/test/finance/VestingWallet.behavior.js +++ b/test/finance/VestingWallet.behavior.js @@ -1,15 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const time = require('../helpers/time'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; -async function envSetup(mock, beneficiary, token) { +export async function envSetup(connection, mock, beneficiary, token) { return { eth: { checkRelease: async (tx, amount) => { - await expect(tx).to.changeEtherBalances([mock, beneficiary], [-amount, amount]); + await expect(tx).to.changeEtherBalances(connection.ethers, [mock, beneficiary], [-amount, amount]); }, setupFailure: async () => { - const beneficiaryMock = await ethers.deployContract('EtherReceiverMock'); + const beneficiaryMock = await connection.ethers.deployContract('EtherReceiverMock'); await beneficiaryMock.setAcceptEther(false); await mock.connect(beneficiary).transferOwnership(beneficiaryMock); return { args: [], error: [mock, 'FailedCall'] }; @@ -20,10 +19,10 @@ async function envSetup(mock, beneficiary, token) { token: { checkRelease: async (tx, amount) => { await expect(tx).to.emit(token, 'Transfer').withArgs(mock, beneficiary, amount); - await expect(tx).to.changeTokenBalances(token, [mock, beneficiary], [-amount, amount]); + await expect(tx).to.changeTokenBalances(connection.ethers, token, [mock, beneficiary], [-amount, amount]); }, setupFailure: async () => { - const pausableToken = await ethers.deployContract('$ERC20Pausable', ['Name', 'Symbol']); + const pausableToken = await connection.ethers.deployContract('$ERC20Pausable', ['Name', 'Symbol']); await pausableToken.$_pause(); return { args: [ethers.Typed.address(pausableToken)], @@ -36,10 +35,10 @@ async function envSetup(mock, beneficiary, token) { }; } -function shouldBehaveLikeVesting() { +export function shouldBehaveLikeVesting() { it('check vesting schedule', async function () { for (const timestamp of this.schedule) { - await time.increaseTo.timestamp(timestamp); + await this.helpers.time.increaseTo.timestamp(timestamp); const vesting = this.vestingFn(timestamp); expect(await this.mock.vestedAmount(...this.args, timestamp)).to.equal(vesting); @@ -59,7 +58,7 @@ function shouldBehaveLikeVesting() { } for (const timestamp of this.schedule) { - await time.increaseTo.timestamp(timestamp, false); + await this.helpers.time.increaseTo.timestamp(timestamp, false); const vested = this.vestingFn(timestamp); const tx = await this.mock.release(...this.args); @@ -74,14 +73,9 @@ function shouldBehaveLikeVesting() { const { args, error } = await this.setupFailure(); for (const timestamp of this.schedule) { - await time.increaseTo.timestamp(timestamp); + await this.helpers.time.increaseTo.timestamp(timestamp); await expect(this.mock.release(...args)).to.be.revertedWithCustomError(...error); } }); } - -module.exports = { - envSetup, - shouldBehaveLikeVesting, -}; diff --git a/test/finance/VestingWallet.test.js b/test/finance/VestingWallet.test.js index b89258d65b8..297967ae7fe 100644 --- a/test/finance/VestingWallet.test.js +++ b/test/finance/VestingWallet.test.js @@ -1,11 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { min } from '../helpers/math'; +import { envSetup, shouldBehaveLikeVesting } from './VestingWallet.behavior'; -const { min } = require('../helpers/math'); -const time = require('../helpers/time'); - -const { envSetup, shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { const amount = ethers.parseEther('100'); @@ -19,7 +22,7 @@ async function fixture() { await token.$_mint(mock, amount); await sender.sendTransaction({ to: mock, value: amount }); - const env = await envSetup(mock, beneficiary, token); + const env = await envSetup(connection, mock, beneficiary, token); const schedule = Array.from({ length: 64 }, (_, i) => (BigInt(i) * duration) / 60n + start); const vestingFn = timestamp => min(amount, (amount * (timestamp - start)) / duration); @@ -29,7 +32,7 @@ async function fixture() { describe('VestingWallet', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); it('rejects zero address for beneficiary', async function () { diff --git a/test/finance/VestingWalletCliff.test.js b/test/finance/VestingWalletCliff.test.js index 799b24c4b2e..9c0aa693e4d 100644 --- a/test/finance/VestingWalletCliff.test.js +++ b/test/finance/VestingWalletCliff.test.js @@ -1,11 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { min } from '../helpers/math'; +import { envSetup, shouldBehaveLikeVesting } from './VestingWallet.behavior'; -const { min } = require('../helpers/math'); -const time = require('../helpers/time'); - -const { envSetup, shouldBehaveLikeVesting } = require('./VestingWallet.behavior'); +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { const amount = ethers.parseEther('100'); @@ -21,7 +24,7 @@ async function fixture() { await token.$_mint(mock, amount); await sender.sendTransaction({ to: mock, value: amount }); - const env = await envSetup(mock, beneficiary, token); + const env = await envSetup(connection, mock, beneficiary, token); const schedule = Array.from({ length: 64 }, (_, i) => (BigInt(i) * duration) / 60n + start); const vestingFn = timestamp => min(amount, timestamp < cliff ? 0n : (amount * (timestamp - start)) / duration); @@ -31,7 +34,7 @@ async function fixture() { describe('VestingWalletCliff', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); it('rejects a larger cliff than vesting duration', async function () { diff --git a/test/governance/Governor.test.js b/test/governance/Governor.test.js index 0974cf48fe6..58c0a76c1e5 100644 --- a/test/governance/Governor.test.js +++ b/test/governance/Governor.test.js @@ -1,14 +1,17 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../helpers/governance'); -const { getDomain, Ballot } = require('../helpers/eip712'); -const { ProposalState, VoteType } = require('../helpers/enums'); -const time = require('../helpers/time'); - -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); -const { shouldBehaveLikeERC6372 } = require('./utils/ERC6372.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { Ballot, getDomain } from '../helpers/eip712'; +import { ProposalState, VoteType } from '../helpers/enums'; +import { GovernorHelper } from '../helpers/governance'; +import { shouldSupportInterfaces } from '../utils/introspection/SupportsInterface.behavior'; +import { shouldBehaveLikeERC6372 } from './utils/ERC6372.behavior'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -59,7 +62,7 @@ describe('Governor', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token: token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token: token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token: token, to: voter3, value: ethers.parseEther('5') }); @@ -82,7 +85,7 @@ describe('Governor', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // initiate fresh proposal this.proposal = this.helper.setProposal( [ @@ -194,7 +197,7 @@ describe('Governor', function () { await this.helper.connect(this.voter1).vote({ support: VoteType.For }); await this.helper.waitForDeadline(); return this.helper.execute(); - }).to.changeEtherBalances([this.mock, this.userEOA], [-value, value]); + }).to.changeEtherBalances(ethers, [this.mock, this.userEOA], [-value, value]); }); describe('vote with signature', function () { diff --git a/test/governance/TimelockController.test.js b/test/governance/TimelockController.test.js index 11a4c7a00c5..dd4d6d13a3f 100644 --- a/test/governance/TimelockController.test.js +++ b/test/governance/TimelockController.test.js @@ -1,13 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { GovernorHelper } = require('../helpers/governance'); -const { OperationState } = require('../helpers/enums'); -const time = require('../helpers/time'); - -const { shouldSupportInterfaces } = require('../utils/introspection/SupportsInterface.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { GovernorHelper } from '../helpers/governance'; +import { OperationState } from '../helpers/enums'; +import { shouldSupportInterfaces } from '../utils/introspection/SupportsInterface.behavior'; + +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = await network.create(); const salt = '0x025e7b0be353a74631ad648c667493c0e1cd31caa4cc2d3520fdc171ea0cc726'; // a random value @@ -1140,11 +1142,14 @@ describe('TimelockController', function () { await this.mock.getTimestamp(operation.id).then(time.increaseTo.timestamp); + // Outer gas budget must leave enough for the FailedCall revert site after the inner OOGs. + // Instrumented bytecode under `--coverage` adds per-statement probes, so 100k is too tight; + // 500k gives headroom while still well below the EIP-7825 (Osaka) per-tx cap of 2^24. await expect( this.mock .connect(this.executor) .execute(operation.target, operation.value, operation.data, operation.predecessor, operation.salt, { - gasLimit: '100000', + gasLimit: 500_000n, }), ).to.be.revertedWithCustomError(this.mock, 'FailedCall'); }); diff --git a/test/governance/extensions/GovernorCountingFractional.test.js b/test/governance/extensions/GovernorCountingFractional.test.js index be4860bb977..3c678c24b5f 100644 --- a/test/governance/extensions/GovernorCountingFractional.test.js +++ b/test/governance/extensions/GovernorCountingFractional.test.js @@ -1,11 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); -const { zip } = require('../../helpers/iterate'); -const { sum } = require('../../helpers/math'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; +import { zip } from '../../helpers/iterate'; +import { sum } from '../../helpers/math'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -40,7 +44,7 @@ describe('GovernorCountingFractional', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); diff --git a/test/governance/extensions/GovernorCountingOverridable.test.js b/test/governance/extensions/GovernorCountingOverridable.test.js index 4f6b30e41ac..f25f5b213ec 100644 --- a/test/governance/extensions/GovernorCountingOverridable.test.js +++ b/test/governance/extensions/GovernorCountingOverridable.test.js @@ -1,10 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { getDomain, OverrideBallot } = require('../../helpers/eip712'); -const { VoteType } = require('../../helpers/enums'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { VoteType } from '../../helpers/enums'; +import { getDomain, OverrideBallot } from '../../helpers/eip712'; +import { GovernorHelper } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture, mine }, +} = connection; const TOKENS = [ { Token: '$ERC20VotesExtendedMock', mode: 'blockNumber' }, @@ -42,7 +46,7 @@ describe('GovernorCountingOverridable', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -53,7 +57,7 @@ describe('GovernorCountingOverridable', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( diff --git a/test/governance/extensions/GovernorCrosschain.test.js b/test/governance/extensions/GovernorCrosschain.test.js index 3d0458d7558..2dd61c28083 100644 --- a/test/governance/extensions/GovernorCrosschain.test.js +++ b/test/governance/extensions/GovernorCrosschain.test.js @@ -1,11 +1,16 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; -const { getLocalChain } = require('../../helpers/chains'); -const { CALL_TYPE_SINGLE, encodeMode, encodeSingle } = require('../../helpers/erc7579'); -const { GovernorHelper } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); +import { CALL_TYPE_CALL, encodeMode, encodeSingle } from '../../helpers/erc7579'; +import { GovernorHelper } from '../../helpers/governance'; +import { VoteType } from '../../helpers/enums'; + +const connection = await network.create(); +const { + ethers, + helpers: { chain }, + networkHelpers: { loadFixture }, +} = connection; const name = 'OZ-Governor'; const version = '1'; @@ -17,7 +22,6 @@ const votingPeriod = 16n; const value = ethers.parseEther('1'); async function fixture() { - const chain = await getLocalChain(); const [owner, proposer, voter1, voter2, voter3, voter4] = await ethers.getSigners(); const gateway = await ethers.deployContract('$ERC7786GatewayMock'); @@ -40,14 +44,13 @@ async function fixture() { await owner.sendTransaction({ to: governor, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(governor, 'blockNumber'); + const helper = new GovernorHelper(connection, governor, 'blockNumber'); await helper.connect(owner).delegate({ token: token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token: token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token: token, to: voter3, value: ethers.parseEther('5') }); await helper.connect(owner).delegate({ token: token, to: voter4, value: ethers.parseEther('2') }); return { - chain, owner, proposer, voter1, @@ -75,8 +78,8 @@ describe('GovernorCrosschain', function () { target: this.governor.target, data: this.governor.interface.encodeFunctionData('relayCrosschain(address,bytes,bytes32,bytes)', [ this.gateway.target, - this.chain.toErc7930(this.executor), - encodeMode({ callType: CALL_TYPE_SINGLE }), + chain.toErc7930(this.executor), + encodeMode({ callType: CALL_TYPE_CALL }), encodeSingle(this.receiver, 0n, this.receiver.interface.encodeFunctionData('mockFunctionExtra')), ]), }, @@ -97,8 +100,8 @@ describe('GovernorCrosschain', function () { await expect( this.governor.getFunction('relayCrosschain(address,bytes,bytes32,bytes)')( this.gateway, - this.chain.toErc7930(this.executor), - encodeMode({ callType: CALL_TYPE_SINGLE }), + chain.toErc7930(this.executor), + encodeMode({ callType: CALL_TYPE_CALL }), encodeSingle(this.receiver, 0n, this.receiver.interface.encodeFunctionData('mockFunctionExtra')), ), ).to.be.revertedWithCustomError(this.governor, 'GovernorOnlyExecutor'); @@ -116,7 +119,7 @@ describe('GovernorCrosschain', function () { // Before reconfiguration await expect(this.executor.gateway()).to.eventually.equal(this.gateway); - await expect(this.executor.controller()).to.eventually.equal(this.chain.toErc7930(this.governor)); + await expect(this.executor.controller()).to.eventually.equal(chain.toErc7930(this.governor)); // Propose reconfiguration this.helper.setProposal( @@ -125,14 +128,14 @@ describe('GovernorCrosschain', function () { target: this.governor.target, data: this.governor.interface.encodeFunctionData('relayCrosschain(address,bytes,bytes32,bytes)', [ this.gateway.target, - this.chain.toErc7930(this.executor), - encodeMode({ callType: CALL_TYPE_SINGLE }), + chain.toErc7930(this.executor), + encodeMode({ callType: CALL_TYPE_CALL }), encodeSingle( this.executor, 0n, this.executor.interface.encodeFunctionData('reconfigure', [ this.gateway.target, - this.chain.toErc7930(newGovernor), + chain.toErc7930(newGovernor), ]), ), ]), @@ -149,10 +152,10 @@ describe('GovernorCrosschain', function () { await expect(this.helper.execute()) .to.emit(this.executor, 'CrosschainControllerSet') - .withArgs(this.gateway, this.chain.toErc7930(newGovernor)); + .withArgs(this.gateway, chain.toErc7930(newGovernor)); // After reconfiguration await expect(this.executor.gateway()).to.eventually.equal(this.gateway); - await expect(this.executor.controller()).to.eventually.equal(this.chain.toErc7930(newGovernor)); + await expect(this.executor.controller()).to.eventually.equal(chain.toErc7930(newGovernor)); }); }); diff --git a/test/governance/extensions/GovernorERC721.test.js b/test/governance/extensions/GovernorERC721.test.js index 746ec2cea61..fc67041e06a 100644 --- a/test/governance/extensions/GovernorERC721.test.js +++ b/test/governance/extensions/GovernorERC721.test.js @@ -1,9 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; -const { GovernorHelper } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC721Votes', mode: 'blockNumber' }, @@ -42,7 +46,7 @@ describe('GovernorERC721', function () { await owner.sendTransaction({ to: mock, value }); await Promise.all([NFT0, NFT1, NFT2, NFT3, NFT4].map(tokenId => token.$_mint(owner, tokenId))); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, tokenId: NFT0 }); await helper.connect(owner).delegate({ token, to: voter2, tokenId: NFT1 }); await helper.connect(owner).delegate({ token, to: voter2, tokenId: NFT2 }); @@ -64,7 +68,7 @@ describe('GovernorERC721', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // initiate fresh proposal this.proposal = this.helper.setProposal( [ diff --git a/test/governance/extensions/GovernorNoncesKeyed.test.js b/test/governance/extensions/GovernorNoncesKeyed.test.js index 75d035d6940..c4715556c76 100644 --- a/test/governance/extensions/GovernorNoncesKeyed.test.js +++ b/test/governance/extensions/GovernorNoncesKeyed.test.js @@ -1,11 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { getDomain, Ballot, ExtendedBallot } = require('../../helpers/eip712'); -const { VoteType } = require('../../helpers/enums'); -const { shouldBehaveLikeNoncesKeyed } = require('../../utils/Nonces.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { getDomain, Ballot, ExtendedBallot } from '../../helpers/eip712'; +import { VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; +import { shouldBehaveLikeNoncesKeyed } from '../../utils/Nonces.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const name = 'OZ-Governor'; const version = '1'; @@ -39,7 +43,7 @@ describe('GovernorNoncesKeyed', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, 'blockNumber'); + const helper = new GovernorHelper(connection, mock, 'blockNumber'); await helper.connect(owner).delegate({ token: token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token: token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token: token, to: voter3, value: ethers.parseEther('5') }); @@ -61,7 +65,7 @@ describe('GovernorNoncesKeyed', function () { }; beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( diff --git a/test/governance/extensions/GovernorPreventLateQuorum.test.js b/test/governance/extensions/GovernorPreventLateQuorum.test.js index 3e1a96c9d61..148e1031657 100644 --- a/test/governance/extensions/GovernorPreventLateQuorum.test.js +++ b/test/governance/extensions/GovernorPreventLateQuorum.test.js @@ -1,10 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ProposalState, VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -42,7 +46,7 @@ describe('GovernorPreventLateQuorum', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -53,7 +57,7 @@ describe('GovernorPreventLateQuorum', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // initiate fresh proposal this.proposal = this.helper.setProposal( [ diff --git a/test/governance/extensions/GovernorProposalGuardian.test.js b/test/governance/extensions/GovernorProposalGuardian.test.js index a3eb4b80bdd..6d3460e87ea 100644 --- a/test/governance/extensions/GovernorProposalGuardian.test.js +++ b/test/governance/extensions/GovernorProposalGuardian.test.js @@ -1,10 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { impersonate } = require('../../helpers/account'); -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState } = require('../../helpers/enums'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ProposalState } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + helpers: { impersonate }, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -35,11 +39,10 @@ describe('GovernorProposalGuardian', function () { 10n, // quorumNumeratorValue ]); - await impersonate(mock.target); await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -50,7 +53,7 @@ describe('GovernorProposalGuardian', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( @@ -74,8 +77,8 @@ describe('GovernorProposalGuardian', function () { describe('set proposal guardian', function () { it('from governance', async function () { - const governorSigner = await ethers.getSigner(this.mock.target); - await expect(this.mock.connect(governorSigner).setProposalGuardian(this.guardian)) + const governorAsSigner = await impersonate(this.mock); + await expect(this.mock.connect(governorAsSigner).setProposalGuardian(this.guardian)) .to.emit(this.mock, 'ProposalGuardianSet') .withArgs(ethers.ZeroAddress, this.guardian); await expect(this.mock.proposalGuardian()).to.eventually.equal(this.guardian); diff --git a/test/governance/extensions/GovernorSequentialProposalId.test.js b/test/governance/extensions/GovernorSequentialProposalId.test.js index 71ea94c7bcc..5fdba3cfcf3 100644 --- a/test/governance/extensions/GovernorSequentialProposalId.test.js +++ b/test/governance/extensions/GovernorSequentialProposalId.test.js @@ -1,11 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); -const iterate = require('../../helpers/iterate'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; +import { VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; +import { range } from '../../helpers/iterate'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -52,7 +56,7 @@ describe('GovernorSequentialProposalId', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token: token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token: token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token: token, to: voter3, value: ethers.parseEther('5') }); @@ -75,7 +79,7 @@ describe('GovernorSequentialProposalId', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); this.proposal = this.helper.setProposal( [ @@ -90,7 +94,7 @@ describe('GovernorSequentialProposalId', function () { }); it('sequential proposal ids', async function () { - for (const i of iterate.range(1, 10)) { + for (const i of range(1, 10)) { this.proposal.description = ``; await expect(this.mock.hashProposal(...this.proposal.shortProposal)).to.eventually.equal(this.proposal.hash); @@ -124,7 +128,7 @@ describe('GovernorSequentialProposalId', function () { const offset = 69420; await this.mock.$_initializeLatestProposalId(offset); - for (const i of iterate.range(offset + 1, offset + 10)) { + for (const i of range(offset + 1, offset + 10)) { this.proposal.description = ``; await expect(this.mock.hashProposal(...this.proposal.shortProposal)).to.eventually.equal(this.proposal.hash); diff --git a/test/governance/extensions/GovernorStorage.test.js b/test/governance/extensions/GovernorStorage.test.js index 3aa95fd74e7..edaa05158f5 100644 --- a/test/governance/extensions/GovernorStorage.test.js +++ b/test/governance/extensions/GovernorStorage.test.js @@ -1,11 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { GovernorHelper, timelockSalt } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { VoteType } from '../../helpers/enums'; +import { GovernorHelper, timelockSalt } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -54,7 +58,7 @@ describe('GovernorStorage', function () { await timelock.grantRole(EXECUTOR_ROLE, ethers.ZeroAddress); await timelock.revokeRole(DEFAULT_ADMIN_ROLE, deployer); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -65,7 +69,7 @@ describe('GovernorStorage', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // initiate fresh proposal this.proposal = this.helper.setProposal( [ diff --git a/test/governance/extensions/GovernorSuperQuorum.test.js b/test/governance/extensions/GovernorSuperQuorum.test.js index 8a4cae93020..d8f228b83cc 100644 --- a/test/governance/extensions/GovernorSuperQuorum.test.js +++ b/test/governance/extensions/GovernorSuperQuorum.test.js @@ -1,10 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ProposalState, VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -56,7 +60,7 @@ describe('GovernorSuperQuorum', function () { await timelock.grantRole(EXECUTOR_ROLE, ethers.ZeroAddress); await timelock.revokeRole(DEFAULT_ADMIN_ROLE, proposer); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(proposer).delegate({ token, to: voter1, value: 40 }); await helper.connect(proposer).delegate({ token, to: voter2, value: 30 }); await helper.connect(proposer).delegate({ token, to: voter3, value: 20 }); @@ -68,7 +72,7 @@ describe('GovernorSuperQuorum', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( diff --git a/test/governance/extensions/GovernorSuperQuorumGreaterThanQuorum.t.sol b/test/governance/extensions/GovernorSuperQuorumGreaterThanQuorum.t.sol index eb0409c8e3a..964c7724865 100644 --- a/test/governance/extensions/GovernorSuperQuorumGreaterThanQuorum.t.sol +++ b/test/governance/extensions/GovernorSuperQuorumGreaterThanQuorum.t.sol @@ -3,16 +3,16 @@ pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; -import {GovernorVotesSuperQuorumFractionMock} from "../../../contracts/mocks/governance/GovernorVotesSuperQuorumFractionMock.sol"; -import {GovernorVotesQuorumFraction} from "../../../contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; -import {GovernorVotesSuperQuorumFraction} from "../../../contracts/governance/extensions/GovernorVotesSuperQuorumFraction.sol"; -import {GovernorSettings} from "../../../contracts/governance/extensions/GovernorSettings.sol"; -import {GovernorVotes} from "../../../contracts/governance/extensions/GovernorVotes.sol"; -import {Governor} from "../../../contracts/governance/Governor.sol"; -import {IVotes} from "../../../contracts/governance/utils/IVotes.sol"; -import {ERC20VotesExtendedTimestampMock} from "../../../contracts/mocks/token/ERC20VotesAdditionalCheckpointsMock.sol"; -import {EIP712} from "../../../contracts/utils/cryptography/EIP712.sol"; -import {ERC20} from "../../../contracts/token/ERC20/ERC20.sol"; +import {GovernorVotesSuperQuorumFractionMock} from "@openzeppelin/contracts/mocks/governance/GovernorVotesSuperQuorumFractionMock.sol"; +import {GovernorVotesQuorumFraction} from "@openzeppelin/contracts/governance/extensions/GovernorVotesQuorumFraction.sol"; +import {GovernorVotesSuperQuorumFraction} from "@openzeppelin/contracts/governance/extensions/GovernorVotesSuperQuorumFraction.sol"; +import {GovernorSettings} from "@openzeppelin/contracts/governance/extensions/GovernorSettings.sol"; +import {GovernorVotes} from "@openzeppelin/contracts/governance/extensions/GovernorVotes.sol"; +import {Governor} from "@openzeppelin/contracts/governance/Governor.sol"; +import {IVotes} from "@openzeppelin/contracts/governance/utils/IVotes.sol"; +import {ERC20VotesExtendedTimestampMock} from "@openzeppelin/contracts/mocks/token/ERC20VotesAdditionalCheckpointsMock.sol"; +import {EIP712} from "@openzeppelin/contracts/utils/cryptography/EIP712.sol"; +import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; contract TokenMock is ERC20VotesExtendedTimestampMock { constructor() ERC20("Mock Token", "MTK") EIP712("Mock Token", "1") {} diff --git a/test/governance/extensions/GovernorTimelockAccess.test.js b/test/governance/extensions/GovernorTimelockAccess.test.js index 131fa6817f3..5c6d348f5a2 100644 --- a/test/governance/extensions/GovernorTimelockAccess.test.js +++ b/test/governance/extensions/GovernorTimelockAccess.test.js @@ -1,14 +1,18 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { hashOperation } = require('../../helpers/access-manager'); -const { max } = require('../../helpers/math'); -const { selector } = require('../../helpers/methods'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; +import { hashOperation } from '../../helpers/access-manager'; +import { ProposalState, VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; +import { max } from '../../helpers/math'; +import { selector } from '../../helpers/methods'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; function prepareOperation({ sender, target, value = 0n, data = '0x' }) { return { @@ -55,7 +59,7 @@ describe('GovernorTimelockAccess', function () { await admin.sendTransaction({ to: mock, value }); await token.$_mint(admin, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(admin).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(admin).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(admin).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -66,7 +70,7 @@ describe('GovernorTimelockAccess', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // restricted proposal this.restricted = prepareOperation({ @@ -244,7 +248,7 @@ describe('GovernorTimelockAccess', function () { await this.helper.waitForDeadline(); // No need for queuing, so it should not revert - await expect(this.helper.execute()).to.not.be.reverted; + await expect(this.helper.execute()).to.not.be.revert(ethers); }); it('does need to queue proposals with base delay', async function () { @@ -449,7 +453,7 @@ describe('GovernorTimelockAccess', function () { await this.manager.connect(this.admin).grantRole(roleId, this.mock, delay); // Set proposals - const original = new GovernorHelper(this.mock, mode); + const original = new GovernorHelper(connection, this.mock, mode); await original.setProposal([this.restricted.operation, this.unrestricted.operation], 'descr'); // Go through all the governance process @@ -466,7 +470,7 @@ describe('GovernorTimelockAccess', function () { .cancel(this.mock, this.restricted.operation.target, this.restricted.operation.data); // Reschedule the same operation in a different proposal to avoid "AccessManagerNotScheduled" error - const rescheduled = new GovernorHelper(this.mock, mode); + const rescheduled = new GovernorHelper(connection, this.mock, mode); await rescheduled.setProposal([this.restricted.operation], 'descr'); await rescheduled.propose(); await rescheduled.waitForSnapshot(); @@ -604,7 +608,7 @@ describe('GovernorTimelockAccess', function () { it('cancels restricted with queueing if the same operation is part of a more recent proposal (internal)', async function () { // Set proposals - const original = new GovernorHelper(this.mock, mode); + const original = new GovernorHelper(connection, this.mock, mode); await original.setProposal([this.restricted.operation], 'descr'); // Go through all the governance process @@ -620,7 +624,7 @@ describe('GovernorTimelockAccess', function () { .cancel(this.mock, this.restricted.operation.target, this.restricted.operation.data); // Another proposal is added with the same operation - const rescheduled = new GovernorHelper(this.mock, mode); + const rescheduled = new GovernorHelper(connection, this.mock, mode); await rescheduled.setProposal([this.restricted.operation], 'another descr'); // Queue the new proposal @@ -702,8 +706,8 @@ describe('GovernorTimelockAccess', function () { const operationAId = hashOperation(this.mock.target, operationA.target, operationA.data); const operationBId = hashOperation(this.mock.target, operationB.target, operationB.data); - const proposal1 = new GovernorHelper(this.mock, mode); - const proposal2 = new GovernorHelper(this.mock, mode); + const proposal1 = new GovernorHelper(connection, this.mock, mode); + const proposal2 = new GovernorHelper(connection, this.mock, mode); proposal1.setProposal([operationA, operationB], 'proposal A+B'); proposal2.setProposal([operationA, operationC], 'proposal A+C'); diff --git a/test/governance/extensions/GovernorTimelockCompound.test.js b/test/governance/extensions/GovernorTimelockCompound.test.js index 3912eefb8a7..51ecbe4ce30 100644 --- a/test/governance/extensions/GovernorTimelockCompound.test.js +++ b/test/governance/extensions/GovernorTimelockCompound.test.js @@ -1,11 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; +import { ProposalState, VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -46,7 +50,7 @@ describe('GovernorTimelockCompound', function () { await owner.sendTransaction({ to: timelock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -57,7 +61,7 @@ describe('GovernorTimelockCompound', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( @@ -364,7 +368,7 @@ describe('GovernorTimelockCompound', function () { const txExecute = this.helper.execute(); - await expect(txExecute).to.changeTokenBalances(this.token, [this.mock, this.other], [-1n, 1n]); + await expect(txExecute).to.changeTokenBalances(ethers, this.token, [this.mock, this.other], [-1n, 1n]); await expect(txExecute).to.emit(this.token, 'Transfer').withArgs(this.mock, this.other, 1n); }); diff --git a/test/governance/extensions/GovernorTimelockControl.test.js b/test/governance/extensions/GovernorTimelockControl.test.js index b4beceba1e0..b452a65516d 100644 --- a/test/governance/extensions/GovernorTimelockControl.test.js +++ b/test/governance/extensions/GovernorTimelockControl.test.js @@ -1,12 +1,16 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { GovernorHelper, timelockSalt } = require('../../helpers/governance'); -const { OperationState, ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { OperationState, ProposalState, VoteType } from '../../helpers/enums'; +import { GovernorHelper, timelockSalt } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -55,7 +59,7 @@ describe('GovernorTimelockControl', function () { await timelock.grantRole(EXECUTOR_ROLE, ethers.ZeroAddress); await timelock.revokeRole(DEFAULT_ADMIN_ROLE, deployer); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -66,7 +70,7 @@ describe('GovernorTimelockControl', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( @@ -333,7 +337,7 @@ describe('GovernorTimelockControl', function () { const txExecute = await this.helper.execute(); - await expect(txExecute).to.changeTokenBalances(this.token, [this.mock, this.other], [-1n, 1n]); + await expect(txExecute).to.changeTokenBalances(ethers, this.token, [this.mock, this.other], [-1n, 1n]); await expect(txExecute).to.emit(this.token, 'Transfer').withArgs(this.mock, this.other, 1n); }); @@ -361,6 +365,7 @@ describe('GovernorTimelockControl', function () { await this.helper.waitForEta(); await expect(this.helper.execute()).to.changeEtherBalances( + ethers, [this.timelock, this.mock, this.other], [-t2g, t2g - g2o, g2o], ); diff --git a/test/governance/extensions/GovernorVotesQuorumFraction.test.js b/test/governance/extensions/GovernorVotesQuorumFraction.test.js index 62bcea8104b..d42abfc4337 100644 --- a/test/governance/extensions/GovernorVotesQuorumFraction.test.js +++ b/test/governance/extensions/GovernorVotesQuorumFraction.test.js @@ -1,10 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ProposalState, VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture, mine }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -35,7 +39,7 @@ describe('GovernorVotesQuorumFraction', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -46,7 +50,7 @@ describe('GovernorVotesQuorumFraction', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( diff --git a/test/governance/extensions/GovernorVotesSuperQuorumFraction.test.js b/test/governance/extensions/GovernorVotesSuperQuorumFraction.test.js index d004aa37397..a46ca93af04 100644 --- a/test/governance/extensions/GovernorVotesSuperQuorumFraction.test.js +++ b/test/governance/extensions/GovernorVotesSuperQuorumFraction.test.js @@ -1,10 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { ProposalState, VoteType } = require('../../helpers/enums'); -const time = require('../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ProposalState, VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -43,7 +47,7 @@ describe('GovernorVotesSuperQuorumFraction', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('30') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('20') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('15') }); @@ -54,7 +58,7 @@ describe('GovernorVotesSuperQuorumFraction', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( diff --git a/test/governance/extensions/GovernorWithParams.test.js b/test/governance/extensions/GovernorWithParams.test.js index b893651ae79..b93f8247f89 100644 --- a/test/governance/extensions/GovernorWithParams.test.js +++ b/test/governance/extensions/GovernorWithParams.test.js @@ -1,10 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { GovernorHelper } = require('../../helpers/governance'); -const { VoteType } = require('../../helpers/enums'); -const { getDomain, ExtendedBallot } = require('../../helpers/eip712'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { getDomain, ExtendedBallot } from '../../helpers/eip712'; +import { VoteType } from '../../helpers/enums'; +import { GovernorHelper } from '../../helpers/governance'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -37,7 +41,7 @@ describe('GovernorWithParams', function () { await owner.sendTransaction({ to: mock, value }); await token.$_mint(owner, tokenSupply); - const helper = new GovernorHelper(mock, mode); + const helper = new GovernorHelper(connection, mock, mode); await helper.connect(owner).delegate({ token, to: voter1, value: ethers.parseEther('10') }); await helper.connect(owner).delegate({ token, to: voter2, value: ethers.parseEther('7') }); await helper.connect(owner).delegate({ token, to: voter3, value: ethers.parseEther('5') }); @@ -48,7 +52,7 @@ describe('GovernorWithParams', function () { describe(`using ${Token}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); // default proposal this.proposal = this.helper.setProposal( diff --git a/test/governance/utils/ERC6372.behavior.js b/test/governance/utils/ERC6372.behavior.js index f42109a356e..d183efc330a 100644 --- a/test/governance/utils/ERC6372.behavior.js +++ b/test/governance/utils/ERC6372.behavior.js @@ -1,7 +1,6 @@ -const { expect } = require('chai'); -const time = require('../../helpers/time'); +import { expect } from 'chai'; -function shouldBehaveLikeERC6372(mode = 'blockNumber') { +export function shouldBehaveLikeERC6372(mode = 'blockNumber') { describe(`ERC-6372 behavior in ${mode} mode`, function () { beforeEach(async function () { this.mock = this.mock ?? this.token ?? this.votes; @@ -9,7 +8,7 @@ function shouldBehaveLikeERC6372(mode = 'blockNumber') { it('should have a correct clock value', async function () { const currentClock = await this.mock.clock(); - const expectedClock = await time.clock[mode](); + const expectedClock = await this.helpers.time.clock[mode](); expect(currentClock).to.equal(expectedClock, `Clock mismatch in ${mode} mode`); }); @@ -23,7 +22,3 @@ function shouldBehaveLikeERC6372(mode = 'blockNumber') { }); }); } - -module.exports = { - shouldBehaveLikeERC6372, -}; diff --git a/test/governance/utils/Votes.behavior.js b/test/governance/utils/Votes.behavior.js index ffe5e7b42c6..43ebae7f6ec 100644 --- a/test/governance/utils/Votes.behavior.js +++ b/test/governance/utils/Votes.behavior.js @@ -1,13 +1,9 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { mine } = require('@nomicfoundation/hardhat-network-helpers'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { Delegation, getDomain } from '../../helpers/eip712'; +import { shouldBehaveLikeERC6372 } from './ERC6372.behavior'; -const { getDomain, Delegation } = require('../../helpers/eip712'); -const time = require('../../helpers/time'); - -const { shouldBehaveLikeERC6372 } = require('./ERC6372.behavior'); - -function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true }) { +export function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true }) { beforeEach(async function () { [this.delegator, this.delegatee, this.alice, this.bob, this.other] = this.accounts; this.domain = await getDomain(this.votes); @@ -43,7 +39,7 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } expect(await this.votes.delegates(this.alice)).to.equal(ethers.ZeroAddress); const tx = await this.votes.connect(this.alice).delegate(this.alice); - const timepoint = await time.clockFromReceipt[mode](tx); + const timepoint = await this.helpers.time.clockFromReceipt[mode](tx); await expect(tx) .to.emit(this.votes, 'DelegateChanged') @@ -54,7 +50,7 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } expect(await this.votes.delegates(this.alice)).to.equal(this.alice); expect(await this.votes.getVotes(this.alice)).to.equal(weight); expect(await this.votes.getPastVotes(this.alice, timepoint - 1n)).to.equal(0n); - await mine(); + await this.networkHelpers.mine(); expect(await this.votes.getPastVotes(this.alice, timepoint)).to.equal(weight); }); @@ -68,7 +64,7 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } expect(await this.votes.getVotes(this.bob)).to.equal(0n); const tx = await this.votes.connect(this.alice).delegate(this.bob); - const timepoint = await time.clockFromReceipt[mode](tx); + const timepoint = await this.helpers.time.clockFromReceipt[mode](tx); await expect(tx) .to.emit(this.votes, 'DelegateChanged') @@ -84,7 +80,7 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } expect(await this.votes.getPastVotes(this.alice, timepoint - 1n)).to.equal(weight); expect(await this.votes.getPastVotes(this.bob, timepoint - 1n)).to.equal(0n); - await mine(); + await this.networkHelpers.mine(); expect(await this.votes.getPastVotes(this.alice, timepoint)).to.equal(0n); expect(await this.votes.getPastVotes(this.bob, timepoint)).to.equal(weight); }); @@ -111,7 +107,7 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } expect(await this.votes.delegates(this.delegator)).to.equal(ethers.ZeroAddress); const tx = await this.votes.delegateBySig(this.delegatee, nonce, ethers.MaxUint256, v, r, s); - const timepoint = await time.clockFromReceipt[mode](tx); + const timepoint = await this.helpers.time.clockFromReceipt[mode](tx); await expect(tx) .to.emit(this.votes, 'DelegateChanged') @@ -123,7 +119,7 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } expect(await this.votes.getVotes(this.delegator.address)).to.equal(0n); expect(await this.votes.getVotes(this.delegatee)).to.equal(weight); expect(await this.votes.getPastVotes(this.delegatee, timepoint - 1n)).to.equal(0n); - await mine(); + await this.networkHelpers.mine(); expect(await this.votes.getPastVotes(this.delegatee, timepoint)).to.equal(weight); }); @@ -191,7 +187,7 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } }); it('rejects expired permit', async function () { - const expiry = (await time.clock.timestamp()) - 1n; + const expiry = (await this.helpers.time.clock.timestamp()) - 1n; const { r, s, v } = await this.delegator .signTypedData( this.domain, @@ -233,29 +229,29 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } // t0 = mint #0 const t0 = await this.votes.$_mint(this.alice, tokens[0]); - await mine(); + await this.networkHelpers.mine(); // t1 = mint #1 const t1 = await this.votes.$_mint(this.alice, tokens[1]); - await mine(); + await this.networkHelpers.mine(); // t2 = burn #1 const t2 = await this.votes.$_burn(...(fungible ? [this.alice] : []), tokens[1]); - await mine(); + await this.networkHelpers.mine(); // t3 = mint #2 const t3 = await this.votes.$_mint(this.alice, tokens[2]); - await mine(); + await this.networkHelpers.mine(); // t4 = burn #0 const t4 = await this.votes.$_burn(...(fungible ? [this.alice] : []), tokens[0]); - await mine(); + await this.networkHelpers.mine(); // t5 = burn #2 const t5 = await this.votes.$_burn(...(fungible ? [this.alice] : []), tokens[2]); - await mine(); + await this.networkHelpers.mine(); - t0.timepoint = await time.clockFromReceipt[mode](t0); - t1.timepoint = await time.clockFromReceipt[mode](t1); - t2.timepoint = await time.clockFromReceipt[mode](t2); - t3.timepoint = await time.clockFromReceipt[mode](t3); - t4.timepoint = await time.clockFromReceipt[mode](t4); - t5.timepoint = await time.clockFromReceipt[mode](t5); + t0.timepoint = await this.helpers.time.clockFromReceipt[mode](t0); + t1.timepoint = await this.helpers.time.clockFromReceipt[mode](t1); + t2.timepoint = await this.helpers.time.clockFromReceipt[mode](t2); + t3.timepoint = await this.helpers.time.clockFromReceipt[mode](t3); + t4.timepoint = await this.helpers.time.clockFromReceipt[mode](t4); + t5.timepoint = await this.helpers.time.clockFromReceipt[mode](t5); expect(await this.votes.getPastTotalSupply(t0.timepoint - 1n)).to.equal(0n); expect(await this.votes.getPastTotalSupply(t0.timepoint)).to.equal(weight[0]); @@ -299,8 +295,8 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } it('returns the latest block if >= last checkpoint block', async function () { const delegate = await this.votes.connect(this.alice).delegate(this.bob); - const timepoint = await time.clockFromReceipt[mode](delegate); - await mine(2); + const timepoint = await this.helpers.time.clockFromReceipt[mode](delegate); + await this.networkHelpers.mine(2); const latest = await this.votes.getVotes(this.bob); expect(await this.votes.getPastVotes(this.bob, timepoint)).to.equal(latest); @@ -308,10 +304,10 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } }); it('returns zero if < first checkpoint block', async function () { - await mine(); + await this.networkHelpers.mine(); const delegate = await this.votes.connect(this.alice).delegate(this.bob); - const timepoint = await time.clockFromReceipt[mode](delegate); - await mine(2); + const timepoint = await this.helpers.time.clockFromReceipt[mode](delegate); + await this.networkHelpers.mine(2); expect(await this.votes.getPastVotes(this.bob, timepoint - 1n)).to.equal(0n); }); @@ -319,7 +315,3 @@ function shouldBehaveLikeVotes(tokens, { mode = 'blockNumber', fungible = true } }); }); } - -module.exports = { - shouldBehaveLikeVotes, -}; diff --git a/test/governance/utils/Votes.test.js b/test/governance/utils/Votes.test.js index fa92627f2df..a65bbe5a5b8 100644 --- a/test/governance/utils/Votes.test.js +++ b/test/governance/utils/Votes.test.js @@ -1,12 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { sum } = require('../../helpers/math'); -const { zip } = require('../../helpers/iterate'); -const time = require('../../helpers/time'); - -const { shouldBehaveLikeVotes } = require('./Votes.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { zip } from '../../helpers/iterate'; +import { sum } from '../../helpers/math'; +import { shouldBehaveLikeVotes } from './Votes.behavior'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = connection; const MODES = { blockNumber: '$VotesMock', @@ -36,7 +39,7 @@ describe('Votes', function () { describe(`vote with ${mode}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeVotes(AMOUNTS, { mode, fungible: true }); diff --git a/test/governance/utils/VotesExtended.test.js b/test/governance/utils/VotesExtended.test.js index 7b90ef4e20d..07fcb17348f 100644 --- a/test/governance/utils/VotesExtended.test.js +++ b/test/governance/utils/VotesExtended.test.js @@ -1,12 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const { sum } = require('../../helpers/math'); -const { zip } = require('../../helpers/iterate'); -const time = require('../../helpers/time'); - -const { shouldBehaveLikeVotes } = require('./Votes.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { zip } from '../../helpers/iterate'; +import { sum } from '../../helpers/math'; +import { shouldBehaveLikeVotes } from './Votes.behavior'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture, mine }, +} = connection; const MODES = { blockNumber: '$VotesExtendedMock', @@ -36,7 +39,7 @@ describe('VotesExtended', function () { describe(`vote with ${mode}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeVotes(AMOUNTS, { mode, fungible: true }); diff --git a/test/helpers/access-manager.js b/test/helpers/access-manager.js index 3b8343059c0..9e4d13f0a1f 100644 --- a/test/helpers/access-manager.js +++ b/test/helpers/access-manager.js @@ -1,10 +1,8 @@ -const { ethers } = require('hardhat'); +import { ethers } from 'ethers'; +import { MAX_UINT64 } from './constants'; +import { upgradeableSlot } from './storage'; -const { MAX_UINT64 } = require('./constants'); -const time = require('./time'); -const { upgradeableSlot } = require('./storage'); - -function buildBaseRoles() { +export function buildBaseRoles() { const roles = { ADMIN: { id: 0n, @@ -41,20 +39,20 @@ function buildBaseRoles() { return roles; } -const formatAccess = access => [access[0], access[1].toString()]; +export const formatAccess = access => [access[0], access[1].toString()]; -const MINSETBACK = time.duration.days(5); -const EXPIRATION = time.duration.weeks(1); +export const MINSETBACK = 432000n; // time.duration.days(5); +export const EXPIRATION = 604800n; // time.duration.weeks(1); -const EXECUTION_ID_STORAGE_SLOT = upgradeableSlot('AccessManager', 3n); -const CONSUMING_SCHEDULE_STORAGE_SLOT = upgradeableSlot('AccessManaged', 0n); +export const EXECUTION_ID_STORAGE_SLOT = await upgradeableSlot('AccessManager', 3n); +export const CONSUMING_SCHEDULE_STORAGE_SLOT = await upgradeableSlot('AccessManaged', 0n); /** * @requires this.{manager, caller, target, calldata} */ -async function prepareOperation(manager, { caller, target, calldata, delay }) { - const scheduledAt = (await time.clock.timestamp()) + 1n; - await time.increaseTo.timestamp(scheduledAt, false); // Fix next block timestamp for predictability +export async function prepareOperation(manager, { caller, target, calldata, delay }) { + const scheduledAt = (await this.helpers.time.clock.timestamp()) + 1n; + await this.helpers.time.increaseTo.timestamp(scheduledAt, false); // Fix next block timestamp for predictability return { schedule: () => manager.connect(caller).schedule(target, calldata, scheduledAt + delay), @@ -65,21 +63,10 @@ async function prepareOperation(manager, { caller, target, calldata, delay }) { const lazyGetAddress = addressable => addressable.address ?? addressable.target ?? addressable; -const hashOperation = (caller, target, data) => +export const hashOperation = (caller, target, data) => ethers.keccak256( ethers.AbiCoder.defaultAbiCoder().encode( ['address', 'address', 'bytes'], [lazyGetAddress(caller), lazyGetAddress(target), data], ), ); - -module.exports = { - buildBaseRoles, - formatAccess, - MINSETBACK, - EXPIRATION, - EXECUTION_ID_STORAGE_SLOT, - CONSUMING_SCHEDULE_STORAGE_SLOT, - prepareOperation, - hashOperation, -}; diff --git a/test/helpers/account.js b/test/helpers/account.js index f3753098586..03a20e5e239 100644 --- a/test/helpers/account.js +++ b/test/helpers/account.js @@ -1,16 +1,14 @@ -const { ethers } = require('hardhat'); -const { impersonateAccount, setBalance } = require('@nomicfoundation/hardhat-network-helpers'); +import { ethers } from 'ethers'; // Hardhat default balance const DEFAULT_BALANCE = 10000n * ethers.WeiPerEther; -const impersonate = (account, balance = DEFAULT_BALANCE) => { - const address = account.target ?? account.address ?? account; - return impersonateAccount(address) - .then(() => setBalance(address, balance)) - .then(() => ethers.getSigner(address)); -}; - -module.exports = { - impersonate, -}; +export const impersonate = + ({ ethers, networkHelpers }) => + (account, balance = DEFAULT_BALANCE) => { + const address = account.target ?? account.address ?? account; + return networkHelpers + .impersonateAccount(address) + .then(() => networkHelpers.setBalance(address, balance)) + .then(() => ethers.getSigner(address)); + }; diff --git a/test/helpers/chains.js b/test/helpers/chains.js index b0cbf35a0d9..2771cd640a4 100644 --- a/test/helpers/chains.js +++ b/test/helpers/chains.js @@ -1,9 +1,8 @@ // The following listing does not pretend to be exhaustive or even accurate. It SHOULD NOT be used in production. -const { ethers } = require('hardhat'); -const { mapValues } = require('./iterate'); - -const { addressCoder } = require('interoperable-addresses'); +import { ethers } from 'ethers'; +import { addressCoder } from 'interoperable-addresses'; +import { mapValues } from './iterate'; // EVM (https://axelarscan.io/resources/chains?type=evm) const ethereum = { @@ -43,14 +42,15 @@ const format = ({ namespace, reference }) => ({ addressCoder.encode({ chainType: namespace, reference, address: other.target ?? other.address ?? other }), }); -module.exports = { - CHAINS: mapValues( - Object.assign( - mapValues(ethereum, reference => ({ namespace: 'eip155', reference })), - mapValues(solana, reference => ({ namespace: 'solana', reference })), - ), - format, +export const CHAINS = mapValues( + Object.assign( + mapValues(ethereum, reference => ({ namespace: 'eip155', reference })), + mapValues(solana, reference => ({ namespace: 'solana', reference })), ), - getLocalChain: () => - ethers.provider.getNetwork().then(({ chainId }) => format({ namespace: 'eip155', reference: chainId })), -}; + format, +); + +export const getLocalChain = provider => + provider + .send('eth_chainId', []) + .then(chainId => format({ namespace: 'eip155', reference: ethers.toBigInt(chainId) })); diff --git a/test/helpers/constants.js b/test/helpers/constants.js index d08c3ec0455..8b648148ffd 100644 --- a/test/helpers/constants.js +++ b/test/helpers/constants.js @@ -1,7 +1,5 @@ -module.exports = { - MAX_UINT16: 2n ** 16n - 1n, - MAX_UINT32: 2n ** 32n - 1n, - MAX_UINT48: 2n ** 48n - 1n, - MAX_UINT64: 2n ** 64n - 1n, - MAX_UINT128: 2n ** 128n - 1n, -}; +export const MAX_UINT16 = 2n ** 16n - 1n; +export const MAX_UINT32 = 2n ** 32n - 1n; +export const MAX_UINT48 = 2n ** 48n - 1n; +export const MAX_UINT64 = 2n ** 64n - 1n; +export const MAX_UINT128 = 2n ** 128n - 1n; diff --git a/test/helpers/deploy.js b/test/helpers/deploy.js deleted file mode 100644 index 0d4b9563bc9..00000000000 --- a/test/helpers/deploy.js +++ /dev/null @@ -1,14 +0,0 @@ -const { artifacts, ethers } = require('hardhat'); -const { setCode } = require('@nomicfoundation/hardhat-network-helpers'); -const { generators } = require('./random'); - -const forceDeployCode = (name, address = generators.address(), runner = ethers.provider) => - artifacts - .readArtifact(name) - .then(({ abi, deployedBytecode }) => - setCode(address, deployedBytecode).then(() => new ethers.Contract(address, abi, runner)), - ); - -module.exports = { - forceDeployCode, -}; diff --git a/test/helpers/eip712-types.js b/test/helpers/eip712-types.js index fb6fe3aebaf..35020785e35 100644 --- a/test/helpers/eip712-types.js +++ b/test/helpers/eip712-types.js @@ -1,61 +1,74 @@ -const { mapValues } = require('./iterate'); +export const formatType = schema => Object.entries(schema).map(([name, type]) => ({ name, type })); -const formatType = schema => Object.entries(schema).map(([name, type]) => ({ name, type })); - -module.exports = mapValues( - { - EIP712Domain: { - name: 'string', - version: 'string', - chainId: 'uint256', - verifyingContract: 'address', - salt: 'bytes32', - }, - Permit: { owner: 'address', spender: 'address', value: 'uint256', nonce: 'uint256', deadline: 'uint256' }, - Ballot: { proposalId: 'uint256', support: 'uint8', voter: 'address', nonce: 'uint256' }, - ExtendedBallot: { - proposalId: 'uint256', - support: 'uint8', - voter: 'address', - nonce: 'uint256', - reason: 'string', - params: 'bytes', - }, - OverrideBallot: { proposalId: 'uint256', support: 'uint8', voter: 'address', nonce: 'uint256', reason: 'string' }, - Delegation: { delegatee: 'address', nonce: 'uint256', expiry: 'uint256' }, - ForwardRequest: { - from: 'address', - to: 'address', - value: 'uint256', - gas: 'uint256', - nonce: 'uint256', - deadline: 'uint48', - data: 'bytes', - }, - PackedUserOperation: { - sender: 'address', - nonce: 'uint256', - initCode: 'bytes', - callData: 'bytes', - accountGasLimits: 'bytes32', - preVerificationGas: 'uint256', - gasFees: 'bytes32', - paymasterAndData: 'bytes', - }, - UserOperationRequest: { - sender: 'address', - nonce: 'uint256', - initCode: 'bytes', - callData: 'bytes', - accountGasLimits: 'bytes32', - preVerificationGas: 'uint256', - gasFees: 'bytes32', - paymasterVerificationGasLimit: 'uint256', - paymasterPostOpGasLimit: 'uint256', - validAfter: 'uint48', - validUntil: 'uint48', - }, - }, - formatType, -); -module.exports.formatType = formatType; +export const EIP712Domain = formatType({ + name: 'string', + version: 'string', + chainId: 'uint256', + verifyingContract: 'address', + salt: 'bytes32', +}); +export const Permit = formatType({ + owner: 'address', + spender: 'address', + value: 'uint256', + nonce: 'uint256', + deadline: 'uint256', +}); +export const Ballot = formatType({ + proposalId: 'uint256', + support: 'uint8', + voter: 'address', + nonce: 'uint256', +}); +export const ExtendedBallot = formatType({ + proposalId: 'uint256', + support: 'uint8', + voter: 'address', + nonce: 'uint256', + reason: 'string', + params: 'bytes', +}); +export const OverrideBallot = formatType({ + proposalId: 'uint256', + support: 'uint8', + voter: 'address', + nonce: 'uint256', + reason: 'string', +}); +export const Delegation = formatType({ + delegatee: 'address', + nonce: 'uint256', + expiry: 'uint256', +}); +export const ForwardRequest = formatType({ + from: 'address', + to: 'address', + value: 'uint256', + gas: 'uint256', + nonce: 'uint256', + deadline: 'uint48', + data: 'bytes', +}); +export const PackedUserOperation = formatType({ + sender: 'address', + nonce: 'uint256', + initCode: 'bytes', + callData: 'bytes', + accountGasLimits: 'bytes32', + preVerificationGas: 'uint256', + gasFees: 'bytes32', + paymasterAndData: 'bytes', +}); +export const UserOperationRequest = formatType({ + sender: 'address', + nonce: 'uint256', + initCode: 'bytes', + callData: 'bytes', + accountGasLimits: 'bytes32', + preVerificationGas: 'uint256', + gasFees: 'bytes32', + paymasterVerificationGasLimit: 'uint256', + paymasterPostOpGasLimit: 'uint256', + validAfter: 'uint48', + validUntil: 'uint48', +}); diff --git a/test/helpers/eip712.js b/test/helpers/eip712.js index 3843ac02690..a2d754686d0 100644 --- a/test/helpers/eip712.js +++ b/test/helpers/eip712.js @@ -1,7 +1,9 @@ -const { ethers } = require('hardhat'); -const types = require('./eip712-types'); +import { ethers } from 'ethers'; +import { EIP712Domain } from './eip712-types'; -async function getDomain(contract) { +export * from './eip712-types'; + +export async function getDomain(contract) { const { fields, name, version, chainId, verifyingContract, salt, extensions } = await contract.eip712Domain(); if (extensions.length > 0) { @@ -16,7 +18,7 @@ async function getDomain(contract) { salt, }; - for (const [i, { name }] of types.EIP712Domain.entries()) { + for (const [i, { name }] of EIP712Domain.entries()) { if (!(fields & (1 << i))) { delete domain[name]; } @@ -25,21 +27,15 @@ async function getDomain(contract) { return domain; } -function domainType(domain) { - return types.EIP712Domain.filter(({ name }) => domain[name] !== undefined); +export function domainType(domain) { + return EIP712Domain.filter(({ name }) => domain[name] !== undefined); } -function hashTypedData(domain, structHash) { +export const domainSeparator = ethers.TypedDataEncoder.hashDomain; + +export function hashTypedData(domain, structHash) { return ethers.solidityPackedKeccak256( ['bytes', 'bytes32', 'bytes32'], ['0x1901', ethers.TypedDataEncoder.hashDomain(domain), structHash], ); } - -module.exports = { - getDomain, - domainType, - domainSeparator: ethers.TypedDataEncoder.hashDomain, - hashTypedData, - ...types, -}; diff --git a/test/helpers/enums.js b/test/helpers/enums.js index 1e2428bfc0d..f790e04a56a 100644 --- a/test/helpers/enums.js +++ b/test/helpers/enums.js @@ -1,15 +1,26 @@ -const { ethers } = require('ethers'); +import { ethers } from 'ethers'; -const Enum = (...options) => Object.fromEntries(options.map((key, i) => [key, BigInt(i)])); -const EnumTyped = (...options) => Object.fromEntries(options.map((key, i) => [key, ethers.Typed.uint8(i)])); +export const Enum = (...options) => Object.fromEntries(options.map((key, i) => [key, BigInt(i)])); +export const EnumTyped = (...options) => Object.fromEntries(options.map((key, i) => [key, ethers.Typed.uint8(i)])); -module.exports = { - Enum, - EnumTyped, - ProposalState: Enum('Pending', 'Active', 'Canceled', 'Defeated', 'Succeeded', 'Queued', 'Expired', 'Executed'), - VoteType: Object.assign(Enum('Against', 'For', 'Abstain'), { Parameters: 255n }), - Rounding: EnumTyped('Floor', 'Ceil', 'Trunc', 'Expand'), - OperationState: Enum('Unset', 'Waiting', 'Ready', 'Done'), - RevertType: EnumTyped('None', 'RevertWithoutMessage', 'RevertWithMessage', 'RevertWithCustomError', 'Panic'), - ValidationRange: Enum('Timestamp', 'Block'), -}; +export const ProposalState = Enum( + 'Pending', + 'Active', + 'Canceled', + 'Defeated', + 'Succeeded', + 'Queued', + 'Expired', + 'Executed', +); +export const VoteType = Object.assign(Enum('Against', 'For', 'Abstain'), { Parameters: 255n }); +export const Rounding = EnumTyped('Floor', 'Ceil', 'Trunc', 'Expand'); +export const OperationState = Enum('Unset', 'Waiting', 'Ready', 'Done'); +export const RevertType = EnumTyped( + 'None', + 'RevertWithoutMessage', + 'RevertWithMessage', + 'RevertWithCustomError', + 'Panic', +); +export const ValidationRange = Enum('Timestamp', 'Block'); diff --git a/test/helpers/erc4337.js b/test/helpers/erc4337.js index ebde76c4c74..984f528a8dd 100644 --- a/test/helpers/erc4337.js +++ b/test/helpers/erc4337.js @@ -1,8 +1,9 @@ -const { ethers, config, predeploy } = require('hardhat'); -const { ValidationRange } = require('./enums'); +import { config } from 'hardhat'; +import { ethers } from 'ethers'; +import { ValidationRange } from './enums'; -const SIG_VALIDATION_SUCCESS = '0x0000000000000000000000000000000000000000'; -const SIG_VALIDATION_FAILURE = '0x0000000000000000000000000000000000000001'; +export const SIG_VALIDATION_SUCCESS = '0x0000000000000000000000000000000000000000'; +export const SIG_VALIDATION_FAILURE = '0x0000000000000000000000000000000000000001'; const PAYMASTER_SIG_MAGIC = '0x22e325a297439656'; const BLOCK_RANGE_FLAG = 0x800000000000n; @@ -16,7 +17,7 @@ function pack(left, right) { return ethers.solidityPacked(['uint128', 'uint128'], [left, right]); } -function packValidationData(validAfter, validUntil, authorizer, range = undefined) { +export function packValidationData(validAfter, validUntil, authorizer, range = undefined) { // if range is not specified, use the value as provided, // otherwise, clean the values (& BLOCK_RANGE_MASK) and set the flag if corresponding to the range. return ethers.solidityPacked( @@ -37,11 +38,11 @@ function packValidationData(validAfter, validUntil, authorizer, range = undefine ); } -function packInitCode(factory, factoryData) { +export function packInitCode(factory, factoryData) { return ethers.solidityPacked(['address', 'bytes'], [getAddress(factory), factoryData]); } -function packPaymasterAndData( +export function packPaymasterAndData( paymaster, paymasterVerificationGasLimit, paymasterPostOpGasLimit, @@ -63,7 +64,7 @@ function packPaymasterAndData( } /// Represent one user operation -class UserOperation { +export class UserOperation { constructor(params) { this.sender = getAddress(params.sender); this.nonce = params.nonce; @@ -116,9 +117,10 @@ const parseInitCode = initCode => ({ }); /// Global ERC-4337 environment helper. -class ERC4337Helper { - constructor() { - this.factoryAsPromise = ethers.deployContract('$Create2'); +export class ERC4337Helper { + constructor(connection) { + this.connection = connection; + this.factoryAsPromise = connection.ethers.deployContract('$Create2'); } async wait() { @@ -128,13 +130,13 @@ class ERC4337Helper { async newAccount(name, extraArgs = [], params = {}) { const env = { - entrypoint: params.entrypoint ?? predeploy.entrypoint.v09, - senderCreator: params.senderCreator ?? predeploy.senderCreator.v09, + entrypoint: params.entrypoint ?? this.connection.ethers.predeploy.entrypoint.v09, + senderCreator: params.senderCreator ?? this.connection.ethers.predeploy.senderCreator.v09, }; const { factory } = await this.wait(); - const accountFactory = await ethers.getContractFactory(name); + const accountFactory = await this.connection.ethers.getContractFactory(name); if (params.eip7702signer) { const delegate = await accountFactory.deploy(...extraArgs); @@ -149,7 +151,7 @@ class ERC4337Helper { ) .then(deployCode => ethers.concat([factory.target, deployCode])); - const instance = await ethers.provider + const instance = await this.connection.ethers.provider .call({ from: env.entrypoint, to: env.senderCreator, @@ -199,11 +201,13 @@ class EIP7702SmartAccount extends SmartAccount { async deploy() { // hardhat signers from @nomicfoundation/hardhat-ethers do not support type 4 txs. // so we rebuild it using "native" ethers - await ethers.Wallet.fromPhrase(config.networks.hardhat.accounts.mnemonic, ethers.provider).sendTransaction({ - to: ethers.ZeroAddress, - authorizationList: [this.authorization], - gasLimit: 46_000n, // 21,000 base + PER_EMPTY_ACCOUNT_COST - }); + await config.networks.default.accounts.mnemonic.get().then(mnemonic => + ethers.Wallet.fromPhrase(mnemonic, this.runner.provider).sendTransaction({ + to: ethers.ZeroAddress, + authorizationList: [this.authorization], + gasLimit: 46_000n, // 21,000 base + PER_EMPTY_ACCOUNT_COST + }), + ); return this; } @@ -232,13 +236,3 @@ class UserOperationWithContext extends UserOperation { return super.hash(this._env.entrypoint); } } - -module.exports = { - SIG_VALIDATION_SUCCESS, - SIG_VALIDATION_FAILURE, - packValidationData, - packInitCode, - packPaymasterAndData, - UserOperation, - ERC4337Helper, -}; diff --git a/test/helpers/erc7579.js b/test/helpers/erc7579.js index 6c3b4759b73..20c54a6fdc0 100644 --- a/test/helpers/erc7579.js +++ b/test/helpers/erc7579.js @@ -1,18 +1,18 @@ -const { ethers } = require('hardhat'); +import { ethers } from 'ethers'; -const MODULE_TYPE_VALIDATOR = 1; -const MODULE_TYPE_EXECUTOR = 2; -const MODULE_TYPE_FALLBACK = 3; -const MODULE_TYPE_HOOK = 4; +export const MODULE_TYPE_VALIDATOR = 1; +export const MODULE_TYPE_EXECUTOR = 2; +export const MODULE_TYPE_FALLBACK = 3; +export const MODULE_TYPE_HOOK = 4; -const EXEC_TYPE_DEFAULT = '0x00'; -const EXEC_TYPE_TRY = '0x01'; +export const EXEC_TYPE_DEFAULT = '0x00'; +export const EXEC_TYPE_TRY = '0x01'; -const CALL_TYPE_CALL = '0x00'; -const CALL_TYPE_BATCH = '0x01'; -const CALL_TYPE_DELEGATE = '0xff'; +export const CALL_TYPE_CALL = '0x00'; +export const CALL_TYPE_BATCH = '0x01'; +export const CALL_TYPE_DELEGATE = '0xff'; -const encodeMode = ({ +export const encodeMode = ({ callType = '0x00', execType = '0x00', selector = '0x00000000', @@ -23,10 +23,10 @@ const encodeMode = ({ [callType, execType, '0x00000000', selector, payload], ); -const encodeSingle = (target, value = 0n, data = '0x') => +export const encodeSingle = (target, value = 0n, data = '0x') => ethers.solidityPacked(['address', 'uint256', 'bytes'], [target.target ?? target.address ?? target, value, data]); -const encodeBatch = (...entries) => +export const encodeBatch = (...entries) => ethers.AbiCoder.defaultAbiCoder().encode( ['(address,uint256,bytes)[]'], [ @@ -38,21 +38,5 @@ const encodeBatch = (...entries) => ], ); -const encodeDelegate = (target, data = '0x') => +export const encodeDelegate = (target, data = '0x') => ethers.solidityPacked(['address', 'bytes'], [target.target ?? target.address ?? target, data]); - -module.exports = { - MODULE_TYPE_VALIDATOR, - MODULE_TYPE_EXECUTOR, - MODULE_TYPE_FALLBACK, - MODULE_TYPE_HOOK, - EXEC_TYPE_DEFAULT, - EXEC_TYPE_TRY, - CALL_TYPE_CALL, - CALL_TYPE_BATCH, - CALL_TYPE_DELEGATE, - encodeMode, - encodeSingle, - encodeBatch, - encodeDelegate, -}; diff --git a/test/helpers/erc7739.js b/test/helpers/erc7739.js index 5a489de71e9..38fa3881188 100644 --- a/test/helpers/erc7739.js +++ b/test/helpers/erc7739.js @@ -1,8 +1,9 @@ -const { ethers } = require('hardhat'); -const { formatType } = require('./eip712'); +import { ethers } from 'ethers'; +import { formatType } from './eip712'; -const PersonalSign = formatType({ prefixed: 'bytes' }); -const TypedDataSign = contentsTypeName => +export const PersonalSign = formatType({ prefixed: 'bytes' }); + +export const TypedDataSign = contentsTypeName => formatType({ contents: contentsTypeName, name: 'string', @@ -12,7 +13,7 @@ const TypedDataSign = contentsTypeName => salt: 'bytes32', }); -class ERC7739Signer extends ethers.AbstractSigner { +export class ERC7739Signer extends ethers.AbstractSigner { #signer; #domain; @@ -67,7 +68,7 @@ class ERC7739Signer extends ethers.AbstractSigner { } } -class ERC4337Utils { +export class ERC4337Utils { static preparePersonalSign(message) { return { prefixed: ethers.concat([ @@ -109,10 +110,3 @@ class ERC4337Utils { }; } } - -module.exports = { - ERC7739Signer, - ERC4337Utils, - PersonalSign, - TypedDataSign, -}; diff --git a/test/helpers/governance.js b/test/helpers/governance.js index 46d9f85c0ed..e7a4cba6c28 100644 --- a/test/helpers/governance.js +++ b/test/helpers/governance.js @@ -1,14 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { ProposalState } = require('./enums'); -const { unique } = require('./iterate'); -const time = require('./time'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { ProposalState } from './enums'; +import { unique } from './iterate'; -const timelockSalt = (address, descriptionHash) => +export const timelockSalt = (address, descriptionHash) => ethers.toBeHex((ethers.toBigInt(address) << 96n) ^ ethers.toBigInt(descriptionHash), 32); -class GovernorHelper { - constructor(governor, mode = 'blockNumber') { +export class GovernorHelper { + constructor(connection, governor, mode = 'blockNumber') { + this.connection = connection; this.governor = governor; this.mode = mode; } @@ -71,17 +71,23 @@ class GovernorHelper { /// Proposal lifecycle delegate(delegation) { - return Promise.all([ - delegation.token.connect(delegation.to).delegate(delegation.to), - delegation.value === undefined || - delegation.token.connect(this.governor.runner).transfer(delegation.to, delegation.value), - delegation.tokenId === undefined || - delegation.token - .ownerOf(delegation.tokenId) - .then(owner => - delegation.token.connect(this.governor.runner).transferFrom(owner, delegation.to, delegation.tokenId), - ), - ]); + return delegation.token + .connect(delegation.to) + .delegate(delegation.to) + .then( + () => + delegation.value === undefined || + delegation.token.connect(this.governor.runner).transfer(delegation.to, delegation.value), + ) + .then( + () => + delegation.tokenId === undefined || + delegation.token + .ownerOf(delegation.tokenId) + .then(owner => + delegation.token.connect(this.governor.runner).transferFrom(owner, delegation.to, delegation.tokenId), + ), + ); } propose() { @@ -151,17 +157,17 @@ class GovernorHelper { /// Clock helpers async waitForSnapshot(offset = 0n) { const timepoint = await this.governor.proposalSnapshot(await this.id); - return time.increaseTo[this.mode](timepoint + offset); + return this.connection.helpers.time.increaseTo[this.mode](timepoint + offset); } async waitForDeadline(offset = 0n) { const timepoint = await this.governor.proposalDeadline(await this.id); - return time.increaseTo[this.mode](timepoint + offset); + return this.connection.helpers.time.increaseTo[this.mode](timepoint + offset); } async waitForEta(offset = 0n) { const timestamp = await this.governor.proposalEta(await this.id); - return time.increaseTo.timestamp(timestamp + offset); + return this.connection.helpers.time.increaseTo.timestamp(timestamp + offset); } /// Other helpers @@ -211,8 +217,3 @@ class GovernorHelper { return ethers.toBeHex(result, 32); } } - -module.exports = { - GovernorHelper, - timelockSalt, -}; diff --git a/test/helpers/iterate.js b/test/helpers/iterate.js index 8c8e9649dea..4fd09008030 100644 --- a/test/helpers/iterate.js +++ b/test/helpers/iterate.js @@ -1,41 +1,41 @@ -module.exports = { - // ================================================= Array helpers ================================================= +// ================================================= Array helpers ================================================= - // Cut an array into an array of sized-length arrays - // Example: chunk([1,2,3,4,5,6,7,8], 3) → [[1,2,3],[4,5,6],[7,8]] - chunk: (array, size = 1) => - Array.from({ length: Math.ceil(array.length / size) }, (_, i) => array.slice(i * size, i * size + size)), +// Cut an array into an array of sized-length arrays +// Example: chunk([1,2,3,4,5,6,7,8], 3) → [[1,2,3],[4,5,6],[7,8]] +export const chunk = (array, size = 1) => + Array.from({ length: Math.ceil(array.length / size) }, (_, i) => array.slice(i * size, i * size + size)); - // Cartesian cross product of an array of arrays - // Example: product([1,2],[a,b,c],[true]) → [[1,a,true],[1,b,true],[1,c,true],[2,a,true],[2,b,true],[2,c,true]] - product: (...arrays) => arrays.reduce((a, b) => a.flatMap(ai => b.map(bi => [...ai, bi])), [[]]), +// Cartesian cross product of an array of arrays +// Example: product([1,2],[a,b,c],[true]) → [[1,a,true],[1,b,true],[1,c,true],[2,a,true],[2,b,true],[2,c,true]] +export const product = (...arrays) => arrays.reduce((a, b) => a.flatMap(ai => b.map(bi => [...ai, bi])), [[]]); - // Range from start to end in increment - // Example: range(17,42,7) → [17,24,31,38] - range: (start, stop = undefined, step = 1) => { - if (stop == undefined) { - stop = start; - start = 0; - } - return start < stop ? Array.from({ length: (stop - start + step - 1) / step }, (_, i) => start + i * step) : []; - }, +// Range from start to end in increment +// Example: range(17,42,7) → [17,24,31,38] +export const range = (start, stop = undefined, step = 1) => { + if (stop == undefined) { + stop = start; + start = 0; + } + return start < stop ? Array.from({ length: (stop - start + step - 1) / step }, (_, i) => start + i * step) : []; +}; - // Unique elements, with an optional getter function - // Example: unique([1,1,2,3,4,8,1,3,8,13,42]) → [1,2,3,4,8,13,42] - unique: (array, op = x => x) => array.filter((obj, i) => array.findIndex(entry => op(obj) === op(entry)) === i), +// Unique elements, with an optional getter function +// Example: unique([1,1,2,3,4,8,1,3,8,13,42]) → [1,2,3,4,8,13,42] +export const unique = (array, op = x => x) => + array.filter((obj, i) => array.findIndex(entry => op(obj) === op(entry)) === i); - // Zip arrays together. If some arrays are smaller, undefined is used as a filler. - // Example: zip([1,2],[a,b,c],[true]) → [[1,a,true],[2,b,undefined],[undefined,c,undefined]] - zip: (...args) => Array.from({ length: Math.max(...args.map(arg => arg.length)) }, (_, i) => args.map(arg => arg[i])), +// Zip arrays together. If some arrays are smaller, undefined is used as a filler. +// Example: zip([1,2],[a,b,c],[true]) → [[1,a,true],[2,b,undefined],[undefined,c,undefined]] +export const zip = (...args) => + Array.from({ length: Math.max(...args.map(arg => arg.length)) }, (_, i) => args.map(arg => arg[i])); - // ================================================ Object helpers ================================================= +// ================================================ Object helpers ================================================= - // Create a new object by mapping the values through a function, keeping the keys. Second function can be used to pre-filter entries - // Example: mapValues({a:1,b:2,c:3}, x => x**2) → {a:1,b:4,c:9} - mapValues: (obj, fn, fn2 = () => true) => - Object.fromEntries( - Object.entries(obj) - .filter(fn2) - .map(([k, v]) => [k, fn(v)]), - ), -}; +// Create a new object by mapping the values through a function, keeping the keys. Second function can be used to pre-filter entries +// Example: mapValues({a:1,b:2,c:3}, x => x**2) → {a:1,b:4,c:9} +export const mapValues = (obj, fn, fn2 = () => true) => + Object.fromEntries( + Object.entries(obj) + .filter(fn2) + .map(([k, v]) => [k, fn(v)]), + ); diff --git a/test/helpers/math.js b/test/helpers/math.js index 133254aecc2..8b621b75d4f 100644 --- a/test/helpers/math.js +++ b/test/helpers/math.js @@ -1,10 +1,10 @@ // Array of number or bigint -const max = (...values) => values.slice(1).reduce((x, y) => (x > y ? x : y), values.at(0)); -const min = (...values) => values.slice(1).reduce((x, y) => (x < y ? x : y), values.at(0)); -const sum = (...values) => values.slice(1).reduce((x, y) => x + y, values.at(0)); +export const max = (...values) => values.slice(1).reduce((x, y) => (x > y ? x : y), values.at(0)); +export const min = (...values) => values.slice(1).reduce((x, y) => (x < y ? x : y), values.at(0)); +export const sum = (...values) => values.slice(1).reduce((x, y) => x + y, values.at(0)); // Computes modexp without BigInt overflow for large numbers -function modExp(b, e, m) { +export function modExp(b, e, m) { let result = 1n; // If e is a power of two, modexp can be calculated as: @@ -24,10 +24,3 @@ function modExp(b, e, m) { return result; } - -module.exports = { - min, - max, - sum, - modExp, -}; diff --git a/test/helpers/methods.js b/test/helpers/methods.js index a4918972019..5aebe8a495c 100644 --- a/test/helpers/methods.js +++ b/test/helpers/methods.js @@ -1,14 +1,9 @@ -const { ethers } = require('hardhat'); +import { ethers } from 'ethers'; -const selector = signature => ethers.FunctionFragment.from(signature).selector; +export const selector = signature => ethers.FunctionFragment.from(signature).selector; -const interfaceId = signatures => +export const interfaceId = signatures => ethers.toBeHex( signatures.reduce((acc, signature) => acc ^ ethers.toBigInt(selector(signature)), 0n), 4, ); - -module.exports = { - selector, - interfaceId, -}; diff --git a/test/helpers/precompiles.js b/test/helpers/precompiles.js index fb6b7132a70..9fbc3f708a5 100644 --- a/test/helpers/precompiles.js +++ b/test/helpers/precompiles.js @@ -1,12 +1,10 @@ -module.exports = { - ecRecover: '0x0000000000000000000000000000000000000001', - SHA2_256: '0x0000000000000000000000000000000000000002', - RIPEMD_160: '0x0000000000000000000000000000000000000003', - identity: '0x0000000000000000000000000000000000000004', - modexp: '0x0000000000000000000000000000000000000005', - ecAdd: '0x0000000000000000000000000000000000000006', - ecMul: '0x0000000000000000000000000000000000000007', - ecPairing: '0x0000000000000000000000000000000000000008', - blake2f: '0x0000000000000000000000000000000000000009', - pointEvaluation: '0x000000000000000000000000000000000000000a', -}; +export const ecRecover = '0x0000000000000000000000000000000000000001'; +export const SHA2_256 = '0x0000000000000000000000000000000000000002'; +export const RIPEMD_160 = '0x0000000000000000000000000000000000000003'; +export const identity = '0x0000000000000000000000000000000000000004'; +export const modexp = '0x0000000000000000000000000000000000000005'; +export const ecAdd = '0x0000000000000000000000000000000000000006'; +export const ecMul = '0x0000000000000000000000000000000000000007'; +export const ecPairing = '0x0000000000000000000000000000000000000008'; +export const blake2f = '0x0000000000000000000000000000000000000009'; +export const pointEvaluation = '0x000000000000000000000000000000000000000a'; diff --git a/test/helpers/random.js b/test/helpers/random.js index 15d00c15bbc..ef528accb9e 100644 --- a/test/helpers/random.js +++ b/test/helpers/random.js @@ -1,26 +1,12 @@ -const { ethers } = require('hardhat'); - -const generators = { - address: () => ethers.Wallet.createRandom().address, - bytes32: () => ethers.hexlify(ethers.randomBytes(32)), - bytes4: () => ethers.hexlify(ethers.randomBytes(4)), - uint256: () => ethers.toBigInt(ethers.randomBytes(32)), - int256: () => ethers.toBigInt(ethers.randomBytes(32)) + ethers.MinInt256, - bytes: (length = 32) => ethers.hexlify(ethers.randomBytes(length)), - string: () => ethers.uuidV4(ethers.randomBytes(32)), -}; - -generators.address.zero = ethers.ZeroAddress; -generators.bytes32.zero = ethers.ZeroHash; -generators.bytes4.zero = ethers.zeroPadBytes('0x', 4); -generators.uint256.zero = 0n; -generators.int256.zero = 0n; -generators.bytes.zero = '0x'; -generators.string.zero = ''; - -// alias hexBytes -> bytes -generators.hexBytes = generators.bytes; - -module.exports = { - generators, +import { ethers } from 'ethers'; + +export const generators = { + address: Object.assign(() => ethers.Wallet.createRandom().address, { zero: ethers.ZeroAddress }), + bytes32: Object.assign(() => ethers.hexlify(ethers.randomBytes(32)), { zero: ethers.ZeroHash }), + bytes4: Object.assign(() => ethers.hexlify(ethers.randomBytes(4)), { zero: ethers.zeroPadBytes('0x', 4) }), + uint256: Object.assign(() => ethers.toBigInt(ethers.randomBytes(32)), { zero: 0n }), + int256: Object.assign(() => ethers.toBigInt(ethers.randomBytes(32)) + ethers.MinInt256, { zero: 0n }), + bytes: Object.assign((length = 32) => ethers.hexlify(ethers.randomBytes(length)), { zero: '0x' }), + hexBytes: Object.assign((length = 32) => ethers.hexlify(ethers.randomBytes(length)), { zero: '0x' }), + string: Object.assign(() => ethers.uuidV4(ethers.randomBytes(32)), { zero: '' }), }; diff --git a/test/helpers/signers.js b/test/helpers/signers.js index d6ba8d272eb..862e1064bcc 100644 --- a/test/helpers/signers.js +++ b/test/helpers/signers.js @@ -1,9 +1,9 @@ -const { ethers } = require('ethers'); -const { p256 } = require('@noble/curves/nist.js'); -const { generateKeyPairSync, privateEncrypt } = require('crypto'); +import { ethers } from 'ethers'; +import { p256 } from '@noble/curves/nist.js'; +import { generateKeyPairSync, privateEncrypt } from 'crypto'; // Lightweight version of BaseWallet -class NonNativeSigner extends ethers.AbstractSigner { +export class NonNativeSigner extends ethers.AbstractSigner { #signingKey; constructor(privateKey, provider) { @@ -60,7 +60,7 @@ class NonNativeSigner extends ethers.AbstractSigner { } } -class P256SigningKey { +export class P256SigningKey { #privateKey; constructor(privateKey) { @@ -99,7 +99,7 @@ class P256SigningKey { } } -class RSASigningKey { +export class RSASigningKey { #privateKey; #publicKey; @@ -135,14 +135,14 @@ class RSASigningKey { } } -class RSASHA256SigningKey extends RSASigningKey { +export class RSASHA256SigningKey extends RSASigningKey { sign(digest /*: BytesLike*/) /*: ethers.Signature*/ { ethers.assertArgument(ethers.dataLength(digest) === 32, 'invalid digest length', 'digest', digest); return super.sign(ethers.sha256(ethers.getBytes(digest))); } } -class WebAuthnSigningKey extends P256SigningKey { +export class WebAuthnSigningKey extends P256SigningKey { sign(digest /*: BytesLike*/) /*: { serialized: string } */ { ethers.assertArgument(ethers.dataLength(digest) === 32, 'invalid digest length', 'digest', digest); @@ -178,7 +178,7 @@ class WebAuthnSigningKey extends P256SigningKey { } } -class MultiERC7913SigningKey { +export class MultiERC7913SigningKey { // this is a sorted array of objects that contain {signer, weight} #signers; @@ -214,12 +214,3 @@ class MultiERC7913SigningKey { }; } } - -module.exports = { - NonNativeSigner, - P256SigningKey, - RSASigningKey, - RSASHA256SigningKey, - WebAuthnSigningKey, - MultiERC7913SigningKey, -}; diff --git a/test/helpers/storage.js b/test/helpers/storage.js index 466cbb10c56..dc601f3067c 100644 --- a/test/helpers/storage.js +++ b/test/helpers/storage.js @@ -1,48 +1,40 @@ -const { ethers } = require('hardhat'); -const { setStorageAt } = require('@nomicfoundation/hardhat-network-helpers'); +import { artifacts } from 'hardhat'; +import { ethers } from 'ethers'; -const ImplementationLabel = 'eip1967.proxy.implementation'; -const AdminLabel = 'eip1967.proxy.admin'; -const BeaconLabel = 'eip1967.proxy.beacon'; +export const ImplementationLabel = 'eip1967.proxy.implementation'; +export const AdminLabel = 'eip1967.proxy.admin'; +export const BeaconLabel = 'eip1967.proxy.beacon'; -const erc1967Slot = label => ethers.toBeHex(ethers.toBigInt(ethers.id(label)) - 1n); -const erc7201Slot = label => ethers.toBeHex(ethers.toBigInt(ethers.keccak256(erc1967Slot(label))) & ~0xffn); -const erc7201format = contractName => `openzeppelin.storage.${contractName}`; +export const erc1967Slot = label => ethers.toBeHex(ethers.toBigInt(ethers.id(label)) - 1n); +export const erc7201Slot = label => ethers.toBeHex(ethers.toBigInt(ethers.keccak256(erc1967Slot(label))) & ~0xffn); +export const erc7201format = contractName => `openzeppelin.storage.${contractName}`; -const getSlot = (address, slot) => - ethers.provider.getStorage(address, ethers.isBytesLike(slot) ? slot : erc1967Slot(slot)); +export const getSlot = + ({ networkHelpers }) => + (address, slot) => + (ethers.isAddressable(address) ? address.getAddress() : Promise.resolve(address)).then(address => + networkHelpers.getStorageAt(address, ethers.isBytesLike(slot) ? slot : erc1967Slot(slot)), + ); -const setSlot = (address, slot, value) => - Promise.all([ - ethers.isAddressable(address) ? address.getAddress() : Promise.resolve(address), - ethers.isAddressable(value) ? value.getAddress() : Promise.resolve(value), - ]).then(([address, value]) => setStorageAt(address, ethers.isBytesLike(slot) ? slot : erc1967Slot(slot), value)); +export const getAddressInSlot = + ({ networkHelpers }) => + (address, slot) => + getSlot({ networkHelpers })(address, slot).then( + slotValue => ethers.AbiCoder.defaultAbiCoder().decode(['address'], slotValue)[0], + ); -const getAddressInSlot = (address, slot) => - getSlot(address, slot).then(slotValue => ethers.AbiCoder.defaultAbiCoder().decode(['address'], slotValue)[0]); +export const setSlot = + ({ networkHelpers }) => + (address, slot, value) => + Promise.all([ + ethers.isAddressable(address) ? address.getAddress() : Promise.resolve(address), + ethers.isAddressable(value) ? value.getAddress() : Promise.resolve(value), + ]).then(([address, value]) => + networkHelpers.setStorageAt(address, ethers.isBytesLike(slot) ? slot : erc1967Slot(slot), value), + ); -const upgradeableSlot = (contractName, offset) => { - try { - // Try to get the artifact paths, will throw if it doesn't exist - artifacts._getArtifactPathSync(`${contractName}Upgradeable`); - return offset + ethers.toBigInt(erc7201Slot(erc7201format(contractName))); - } catch { - return offset; - } -}; - -module.exports = { - ImplementationLabel, - AdminLabel, - BeaconLabel, - ImplementationSlot: erc1967Slot(ImplementationLabel), - AdminSlot: erc1967Slot(AdminLabel), - BeaconSlot: erc1967Slot(BeaconLabel), - erc1967Slot, - erc7201Slot, - erc7201format, - setSlot, - getSlot, - getAddressInSlot, - upgradeableSlot, -}; +export const upgradeableSlot = (contractName, offset) => + artifacts.readArtifact(`${contractName}Upgradeable`).then( + () => offset + ethers.toBigInt(erc7201Slot(erc7201format(contractName))), + () => offset, + ); diff --git a/test/helpers/strings.js b/test/helpers/strings.js index 4f34099d7df..fcda5e85d87 100644 --- a/test/helpers/strings.js +++ b/test/helpers/strings.js @@ -1,5 +1,3 @@ -module.exports = { - // Capitalize the first char of a string - // Example: capitalize('uint256') → 'Uint256' - capitalize: str => str.charAt(0).toUpperCase() + str.slice(1), -}; +// Capitalize the first char of a string +// Example: capitalize('uint256') → 'Uint256' +export const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1); diff --git a/test/helpers/time.js b/test/helpers/time.js index 9dd26a2f79f..61bf5837e75 100644 --- a/test/helpers/time.js +++ b/test/helpers/time.js @@ -1,33 +1,39 @@ -const { ethers } = require('hardhat'); -const { time, mine, mineUpTo } = require('@nomicfoundation/hardhat-network-helpers'); -const { mapValues } = require('./iterate'); +import { ethers } from 'ethers'; -const clock = { - blockNumber: () => time.latestBlock().then(ethers.toBigInt), - timestamp: () => time.latest().then(ethers.toBigInt), -}; -const clockFromReceipt = { +export const clock = ({ networkHelpers }) => ({ + blockNumber: () => networkHelpers.time.latestBlock().then(ethers.toBigInt), + timestamp: () => networkHelpers.time.latest().then(ethers.toBigInt), +}); + +export const clockFromReceipt = ({ ethers }) => ({ blockNumber: receipt => Promise.resolve(receipt).then(({ blockNumber }) => ethers.toBigInt(blockNumber)), timestamp: receipt => Promise.resolve(receipt) .then(({ blockNumber }) => ethers.provider.getBlock(blockNumber)) .then(({ timestamp }) => ethers.toBigInt(timestamp)), -}; -const increaseBy = { - blockNumber: mine, +}); + +export const increaseBy = ({ networkHelpers }) => ({ + blockNumber: networkHelpers.mine, timestamp: (delay, mine = true) => - time.latest().then(clock => increaseTo.timestamp(clock + ethers.toNumber(delay), mine)), -}; -const increaseTo = { - blockNumber: mineUpTo, - timestamp: (to, mine = true) => (mine ? time.increaseTo(to) : time.setNextBlockTimestamp(to)), -}; -const duration = mapValues(time.duration, fn => n => ethers.toBigInt(fn(ethers.toNumber(n)))); + networkHelpers.time + .latest() + .then(clock => clock + ethers.toNumber(delay)) + .then(to => (mine ? networkHelpers.time.increaseTo(to) : networkHelpers.time.setNextBlockTimestamp(to))), +}); + +export const increaseTo = ({ networkHelpers }) => ({ + blockNumber: networkHelpers.mineUpTo, + timestamp: (to, mine = true) => + mine ? networkHelpers.time.increaseTo(to) : networkHelpers.time.setNextBlockTimestamp(to), +}); -module.exports = { - clock, - clockFromReceipt, - increaseBy, - increaseTo, - duration, -}; +export const duration = ({ networkHelpers }) => ({ + years: n => ethers.toBigInt(networkHelpers.time.duration.years(ethers.toNumber(n))), + weeks: n => ethers.toBigInt(networkHelpers.time.duration.weeks(ethers.toNumber(n))), + days: n => ethers.toBigInt(networkHelpers.time.duration.days(ethers.toNumber(n))), + hours: n => ethers.toBigInt(networkHelpers.time.duration.hours(ethers.toNumber(n))), + minutes: n => ethers.toBigInt(networkHelpers.time.duration.minutes(ethers.toNumber(n))), + seconds: n => ethers.toBigInt(networkHelpers.time.duration.seconds(ethers.toNumber(n))), + millis: n => ethers.toBigInt(networkHelpers.time.duration.millis(ethers.toNumber(n))), +}); diff --git a/test/helpers/trie.js b/test/helpers/trie.js index a6d28e4265b..564caa680e8 100644 --- a/test/helpers/trie.js +++ b/test/helpers/trie.js @@ -1,7 +1,7 @@ -const { ethers } = require('ethers'); -const { MerklePatriciaTrie, createMerkleProof } = require('@ethereumjs/mpt'); +import { ethers } from 'ethers'; +import { MerklePatriciaTrie, createMerkleProof } from '@ethereumjs/mpt'; -class BlockTries { +export class BlockTries { constructor(block) { this.block = block; @@ -75,5 +75,3 @@ class BlockTries { return ethers.getBytes(BlockTries.indexToKey(index)); } } - -module.exports = { BlockTries }; diff --git a/test/helpers/txpool.js b/test/helpers/txpool.js index ad84f45dd77..9d19c317635 100644 --- a/test/helpers/txpool.js +++ b/test/helpers/txpool.js @@ -1,9 +1,7 @@ -const { network } = require('hardhat'); -const { expect } = require('chai'); +import { expect } from 'chai'; +import { unique } from './iterate'; -const { unique } = require('./iterate'); - -async function batchInBlock(txs, provider = network.provider) { +export async function batchInBlock(txs, provider) { try { // disable auto-mining await provider.send('evm_setAutomine', [false]); @@ -22,7 +20,3 @@ async function batchInBlock(txs, provider = network.provider) { await provider.send('evm_setAutomine', [true]); } } - -module.exports = { - batchInBlock, -}; diff --git a/test/metatx/ERC2771Context.test.js b/test/metatx/ERC2771Context.test.js index 377e1d701f2..87058ce3229 100644 --- a/test/metatx/ERC2771Context.test.js +++ b/test/metatx/ERC2771Context.test.js @@ -1,12 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { impersonate } = require('../helpers/account'); -const { getDomain, ForwardRequest } = require('../helpers/eip712'); -const { MAX_UINT48 } = require('../helpers/constants'); - -const { shouldBehaveLikeRegularContext } = require('../utils/Context.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT48 } from '../helpers/constants'; +import { ForwardRequest, getDomain } from '../helpers/eip712'; +import { shouldBehaveLikeRegularContext } from '../utils/Context.behavior'; + +const { + ethers, + helpers: { impersonate }, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [sender, other] = await ethers.getSigners(); @@ -14,6 +16,7 @@ async function fixture() { const forwarder = await ethers.deployContract('ERC2771Forwarder', ['ERC2771Forwarder']); const forwarderAsSigner = await impersonate(forwarder.target); const context = await ethers.deployContract('ERC2771ContextMock', [forwarder]); + const contextHelper = await ethers.deployContract('ContextMockCaller', []); const domain = await getDomain(forwarder); const prepareAndSignRequest = async (signer, request) => { @@ -28,7 +31,7 @@ async function fixture() { return request; }; - return { sender, other, forwarder, forwarderAsSigner, context, prepareAndSignRequest }; + return { sender, other, forwarder, forwarderAsSigner, context, contextHelper, prepareAndSignRequest }; } describe('ERC2771Context', function () { diff --git a/test/metatx/ERC2771Forwarder.t.sol b/test/metatx/ERC2771Forwarder.t.sol index 224367377ff..dcaccd08af1 100644 --- a/test/metatx/ERC2771Forwarder.t.sol +++ b/test/metatx/ERC2771Forwarder.t.sol @@ -99,7 +99,7 @@ contract ERC2771ForwarderTest is Test { function _tamperRequestData( ERC2771Forwarder.ForwardRequestData memory request, TamperType tamper - ) private returns (ERC2771Forwarder.ForwardRequestData memory) { + ) private view returns (ERC2771Forwarder.ForwardRequestData memory) { if (tamper == TamperType.FROM) request.from = vm.randomAddress(); else if (tamper == TamperType.TO) request.to = vm.randomAddress(); else if (tamper == TamperType.VALUE) request.value = vm.randomUint(); @@ -200,7 +200,7 @@ contract ERC2771ForwarderTest is Test { assertEq(refundReceiver.balance, refundExpected); } - function testVerifyTamperedValues(uint8 _tamper) public { + function testVerifyTamperedValues(uint8 _tamper) public view { TamperType tamper = _asTamper(_tamper); // create request, sign, tamper diff --git a/test/metatx/ERC2771Forwarder.test.js b/test/metatx/ERC2771Forwarder.test.js index ec8d20b47a5..e0c6a900103 100644 --- a/test/metatx/ERC2771Forwarder.test.js +++ b/test/metatx/ERC2771Forwarder.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ForwardRequest, getDomain } from '../helpers/eip712'; +import { sum } from '../helpers/math'; -const { getDomain, ForwardRequest } = require('../helpers/eip712'); -const { sum } = require('../helpers/math'); -const time = require('../helpers/time'); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [sender, refundReceiver, another, ...accounts] = await ethers.getSigners(); @@ -149,7 +152,7 @@ describe('ERC2771Forwarder', function () { }); const gasLimit = 100_000n; - await expect(this.forwarder.execute(request, { gasLimit })).to.be.revertedWithoutReason(); + await expect(this.forwarder.execute(request, { gasLimit })).to.be.revertedWithoutReason(ethers); const { gasUsed } = await ethers.provider .getBlock('latest') @@ -178,7 +181,7 @@ describe('ERC2771Forwarder', function () { // The subcall out of gas should be caught by the contract and then bubbled up consuming // the available gas with an `invalid` opcode. - await expect(this.forwarder.execute(request, { gasLimit })).to.be.revertedWithoutReason(); + await expect(this.forwarder.execute(request, { gasLimit })).to.be.revertedWithoutReason(ethers); const { gasUsed } = await ethers.provider .getBlock('latest') @@ -353,7 +356,7 @@ describe('ERC2771Forwarder', function () { gasLimit, value: requestsValue(this.requests), }), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); const { gasUsed } = await ethers.provider .getBlock('latest') @@ -383,7 +386,7 @@ describe('ERC2771Forwarder', function () { gasLimit, value: requestsValue(this.requests), }), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); const { gasUsed } = await ethers.provider .getBlock('latest') diff --git a/test/proxy/Clones.behaviour.js b/test/proxy/Clones.behaviour.js index dcc62066533..704e30f37a7 100644 --- a/test/proxy/Clones.behaviour.js +++ b/test/proxy/Clones.behaviour.js @@ -1,15 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { expect } from 'chai'; -module.exports = function shouldBehaveLikeClone() { +export function shouldBehaveLikeClone() { const assertProxyInitialization = function ({ value, balance }) { it('initializes the proxy', async function () { - const dummy = await ethers.getContractAt('DummyImplementation', this.proxy); + const dummy = await this.ethers.getContractAt('DummyImplementation', this.proxy); expect(await dummy.value()).to.equal(value); }); it('has expected balance', async function () { - expect(await ethers.provider.getBalance(this.proxy)).to.equal(balance); + expect(await this.ethers.provider.getBalance(this.proxy)).to.equal(balance); }); }; @@ -20,9 +19,13 @@ module.exports = function shouldBehaveLikeClone() { await this.deployer.sendTransaction({ to: this.factory, value }); const instance = await this.createClone({ deployValue: value }); - await expect(instance.deploymentTransaction()).to.changeEtherBalances([this.factory, instance], [-value, value]); + await expect(instance.deploymentTransaction()).to.changeEtherBalances( + this.ethers, + [this.factory, instance], + [-value, value], + ); - expect(await ethers.provider.getBalance(instance)).to.equal(value); + expect(await this.ethers.provider.getBalance(instance)).to.equal(value); }); it('factory does not have enough balance', async function () { @@ -47,7 +50,7 @@ module.exports = function shouldBehaveLikeClone() { assertProxyInitialization({ value: expectedInitializedValue, - balance: 0, + balance: 0n, }); }); @@ -55,7 +58,7 @@ module.exports = function shouldBehaveLikeClone() { const value = 10n ** 6n; it('reverts', async function () { - await expect(this.createClone({ initData: this.initializeData, initValue: value })).to.be.reverted; + await expect(this.createClone({ initData: this.initializeData, initValue: value })).to.be.revert(this.ethers); }); }); }); @@ -74,7 +77,7 @@ module.exports = function shouldBehaveLikeClone() { assertProxyInitialization({ value: expectedInitializedValue, - balance: 0, + balance: 0n, }); }); @@ -110,7 +113,7 @@ module.exports = function shouldBehaveLikeClone() { assertProxyInitialization({ value: expectedInitializedValue, - balance: 0, + balance: 0n, }); }); @@ -118,7 +121,7 @@ module.exports = function shouldBehaveLikeClone() { const value = 10n ** 6n; it('reverts', async function () { - await expect(this.createClone({ initData: this.initializeData, initValue: value })).to.be.reverted; + await expect(this.createClone({ initData: this.initializeData, initValue: value })).to.be.revert(this.ethers); }); }); }); @@ -139,7 +142,7 @@ module.exports = function shouldBehaveLikeClone() { assertProxyInitialization({ value: expectedInitializedValue, - balance: 0, + balance: 0n, }); }); @@ -157,4 +160,4 @@ module.exports = function shouldBehaveLikeClone() { }); }); }); -}; +} diff --git a/test/proxy/Clones.t.sol b/test/proxy/Clones.t.sol index 5da6d56d5a6..6bb678c65c4 100644 --- a/test/proxy/Clones.t.sol +++ b/test/proxy/Clones.t.sol @@ -28,8 +28,7 @@ contract ClonesTest is Test { address predicted = Clones.predictDeterministicAddressWithImmutableArgs(implementation, args, salt); bytes32 spillage; - /// @solidity memory-safe-assembly - assembly { + assembly ("memory-safe") { spillage := and(predicted, 0xffffffffffffffffffffffff0000000000000000000000000000000000000000) } assertEq(spillage, bytes32(0)); diff --git a/test/proxy/Clones.test.js b/test/proxy/Clones.test.js index 93bcfba19b9..78850d50fea 100644 --- a/test/proxy/Clones.test.js +++ b/test/proxy/Clones.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { generators } from '../helpers/random'; +import { shouldBehaveLikeClone } from './Clones.behaviour'; -const { generators } = require('../helpers/random'); - -const shouldBehaveLikeClone = require('./Clones.behaviour'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const cloneInitCode = (instance, args = undefined) => args @@ -81,7 +84,7 @@ async function fixture() { describe('Clones', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); for (const args of [undefined, '0x', '0x11223344']) { @@ -120,7 +123,7 @@ describe('Clones', function () { : this.factory.$cloneDeterministic(this.implementation, salt); // deploy once - await expect(deployClone()).to.not.be.reverted; + await expect(deployClone()).to.not.be.revert(ethers); // deploy twice await expect(deployClone()).to.be.revertedWithCustomError(this.factory, 'FailedDeployment'); diff --git a/test/proxy/ERC1967/ERC1967Proxy.test.js b/test/proxy/ERC1967/ERC1967Proxy.test.js index 319830e1f10..efe5e914f70 100644 --- a/test/proxy/ERC1967/ERC1967Proxy.test.js +++ b/test/proxy/ERC1967/ERC1967Proxy.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); +import { network } from 'hardhat'; +import { shouldBehaveLikeProxy } from '../Proxy.behaviour'; -const shouldBehaveLikeProxy = require('../Proxy.behaviour'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const fixture = async () => { const [nonContractAddress] = await ethers.getSigners(); @@ -13,7 +17,7 @@ const fixture = async () => { describe('ERC1967Proxy', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); describe('(default) allowUninitialized is false', function () { diff --git a/test/proxy/ERC1967/ERC1967Utils.test.js b/test/proxy/ERC1967/ERC1967Utils.test.js index 089032498e4..6ec37d25979 100644 --- a/test/proxy/ERC1967/ERC1967Utils.test.js +++ b/test/proxy/ERC1967/ERC1967Utils.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ImplementationLabel, AdminLabel, BeaconLabel } from '../../helpers/storage'; -const { getAddressInSlot, setSlot, ImplementationSlot, AdminSlot, BeaconSlot } = require('../../helpers/storage'); +const { + ethers, + helpers: { storage }, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [, admin, anotherAccount] = await ethers.getSigners(); @@ -21,13 +25,13 @@ describe('ERC1967Utils', function () { describe('IMPLEMENTATION_SLOT', function () { beforeEach('set v1 implementation', async function () { - await setSlot(this.utils, ImplementationSlot, this.v1); + await storage.setSlot(this.utils, ImplementationLabel, this.v1); }); describe('getImplementation', function () { it('returns current implementation and matches implementation slot value', async function () { expect(await this.utils.$getImplementation()).to.equal(this.v1); - expect(await getAddressInSlot(this.utils, ImplementationSlot)).to.equal(this.v1); + expect(await storage.getAddressInSlot(this.utils, ImplementationLabel)).to.equal(this.v1); }); }); @@ -36,7 +40,7 @@ describe('ERC1967Utils', function () { const newImplementation = this.v2; const tx = await this.utils.$upgradeToAndCall(newImplementation, '0x'); - expect(await getAddressInSlot(this.utils, ImplementationSlot)).to.equal(newImplementation); + expect(await storage.getAddressInSlot(this.utils, ImplementationLabel)).to.equal(newImplementation); await expect(tx).to.emit(this.utils, 'Upgraded').withArgs(newImplementation); }); @@ -67,13 +71,13 @@ describe('ERC1967Utils', function () { describe('ADMIN_SLOT', function () { beforeEach('set admin', async function () { - await setSlot(this.utils, AdminSlot, this.admin); + await storage.setSlot(this.utils, AdminLabel, this.admin); }); describe('getAdmin', function () { it('returns current admin and matches admin slot value', async function () { expect(await this.utils.$getAdmin()).to.equal(this.admin); - expect(await getAddressInSlot(this.utils, AdminSlot)).to.equal(this.admin); + expect(await storage.getAddressInSlot(this.utils, AdminLabel)).to.equal(this.admin); }); }); @@ -82,7 +86,7 @@ describe('ERC1967Utils', function () { const newAdmin = this.anotherAccount; const tx = await this.utils.$changeAdmin(newAdmin); - expect(await getAddressInSlot(this.utils, AdminSlot)).to.equal(newAdmin); + expect(await storage.getAddressInSlot(this.utils, AdminLabel)).to.equal(newAdmin); await expect(tx).to.emit(this.utils, 'AdminChanged').withArgs(this.admin, newAdmin); }); @@ -97,13 +101,13 @@ describe('ERC1967Utils', function () { describe('BEACON_SLOT', function () { beforeEach('set beacon', async function () { this.beacon = await ethers.deployContract('UpgradeableBeaconMock', [this.v1]); - await setSlot(this.utils, BeaconSlot, this.beacon); + await storage.setSlot(this.utils, BeaconLabel, this.beacon); }); describe('getBeacon', function () { it('returns current beacon and matches beacon slot value', async function () { expect(await this.utils.$getBeacon()).to.equal(this.beacon); - expect(await getAddressInSlot(this.utils, BeaconSlot)).to.equal(this.beacon); + expect(await storage.getAddressInSlot(this.utils, BeaconLabel)).to.equal(this.beacon); }); }); @@ -112,7 +116,7 @@ describe('ERC1967Utils', function () { const newBeacon = await ethers.deployContract('UpgradeableBeaconMock', [this.v2]); const tx = await this.utils.$upgradeBeaconToAndCall(newBeacon, '0x'); - expect(await getAddressInSlot(this.utils, BeaconSlot)).to.equal(newBeacon); + expect(await storage.getAddressInSlot(this.utils, BeaconLabel)).to.equal(newBeacon); await expect(tx).to.emit(this.utils, 'BeaconUpgraded').withArgs(newBeacon); }); diff --git a/test/proxy/Proxy.behaviour.js b/test/proxy/Proxy.behaviour.js index 53fecffa12a..974b1c66ed2 100644 --- a/test/proxy/Proxy.behaviour.js +++ b/test/proxy/Proxy.behaviour.js @@ -1,12 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { expect } from 'chai'; +import { ImplementationLabel } from '../helpers/storage'; -const { getAddressInSlot, ImplementationSlot } = require('../helpers/storage'); - -module.exports = function shouldBehaveLikeProxy(allowUninitialized = false) { +export function shouldBehaveLikeProxy(allowUninitialized = false) { it('cannot be initialized with a non-contract address', async function () { const initializeData = '0x00'; // non empty data to avoid uninitialized error - const contractFactory = await ethers.getContractFactory('ERC1967Proxy'); + const contractFactory = await this.ethers.getContractFactory('ERC1967Proxy'); await expect(this.createProxy(this.nonContractAddress, initializeData)) .to.be.revertedWithCustomError(contractFactory, 'ERC1967InvalidImplementation') @@ -15,7 +13,9 @@ module.exports = function shouldBehaveLikeProxy(allowUninitialized = false) { const assertProxyInitialization = function ({ value, balance }) { it('sets the implementation address', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.implementation); + expect(await this.helpers.storage.getAddressInSlot(this.proxy, ImplementationLabel)).to.equal( + this.implementation, + ); }); it('initializes the proxy', async function () { @@ -24,7 +24,7 @@ module.exports = function shouldBehaveLikeProxy(allowUninitialized = false) { }); it('has expected balance', async function () { - expect(await ethers.provider.getBalance(this.proxy)).to.equal(balance); + expect(await this.proxy.runner.provider.getBalance(this.proxy)).to.equal(balance); }); }; @@ -44,13 +44,13 @@ module.exports = function shouldBehaveLikeProxy(allowUninitialized = false) { const value = 10n ** 5n; it('reverts', async function () { - await expect(this.createProxy(this.implementation, initializeData, { value })).to.be.reverted; + await expect(this.createProxy(this.implementation, initializeData, { value })).to.be.revert(this.ethers); }); }); } else { it('reverts without initialization', async function () { const initializeData = '0x'; // empty data causes uninitialized error - const contractFactory = await ethers.getContractFactory('ERC1967Proxy'); + const contractFactory = await this.ethers.getContractFactory('ERC1967Proxy'); await expect(this.createProxy(this.implementation, initializeData)).to.be.revertedWithCustomError( contractFactory, @@ -83,7 +83,7 @@ module.exports = function shouldBehaveLikeProxy(allowUninitialized = false) { const value = 10n ** 5n; it('reverts', async function () { - await expect(this.createProxy(this.implementation, this.initializeData, { value })).to.be.reverted; + await expect(this.createProxy(this.implementation, this.initializeData, { value })).to.be.revert(this.ethers); }); }); }); @@ -138,7 +138,7 @@ module.exports = function shouldBehaveLikeProxy(allowUninitialized = false) { assertProxyInitialization({ value: expectedInitializedValue, - balance: 0, + balance: 0n, }); }); @@ -146,7 +146,7 @@ module.exports = function shouldBehaveLikeProxy(allowUninitialized = false) { const value = 10e5; it('reverts', async function () { - await expect(this.createProxy(this.implementation, this.initializeData, { value })).to.be.reverted; + await expect(this.createProxy(this.implementation, this.initializeData, { value })).to.be.revert(this.ethers); }); }); }); @@ -191,8 +191,8 @@ module.exports = function shouldBehaveLikeProxy(allowUninitialized = false) { }); it('reverts', async function () { - await expect(this.createProxy(this.implementation, this.initializeData)).to.be.reverted; + await expect(this.createProxy(this.implementation, this.initializeData)).to.be.revert(this.ethers); }); }); }); -}; +} diff --git a/test/proxy/beacon/BeaconProxy.test.js b/test/proxy/beacon/BeaconProxy.test.js index d64023bbce8..1fb807d9b94 100644 --- a/test/proxy/beacon/BeaconProxy.test.js +++ b/test/proxy/beacon/BeaconProxy.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { BeaconLabel } from '../../helpers/storage'; -const { getAddressInSlot, BeaconSlot } = require('../../helpers/storage'); +const { + ethers, + helpers: { storage }, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [admin, other] = await ethers.getSigners(); @@ -36,7 +40,7 @@ describe('BeaconProxy', function () { // BadBeaconNoImpl does not provide `implementation()` and has no fallback. // This causes ERC1967Utils._setBeacon to revert. - await expect(this.newBeaconProxy(badBeacon, '0x')).to.be.revertedWithoutReason(); + await expect(this.newBeaconProxy(badBeacon, '0x')).to.be.revertedWithoutReason(ethers); }); it('non-contract implementation', async function () { @@ -50,7 +54,7 @@ describe('BeaconProxy', function () { describe('initialization', function () { async function assertInitialized({ value, balance }) { - const beaconAddress = await getAddressInSlot(this.proxy, BeaconSlot); + const beaconAddress = await storage.getAddressInSlot(this.proxy, BeaconLabel); expect(beaconAddress).to.equal(this.beacon); const dummy = this.v1.attach(this.proxy); diff --git a/test/proxy/beacon/UpgradeableBeacon.test.js b/test/proxy/beacon/UpgradeableBeacon.test.js index 2da7d0a2730..c805a3ed998 100644 --- a/test/proxy/beacon/UpgradeableBeacon.test.js +++ b/test/proxy/beacon/UpgradeableBeacon.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [admin, other] = await ethers.getSigners(); diff --git a/test/proxy/transparent/ProxyAdmin.test.js b/test/proxy/transparent/ProxyAdmin.test.js index 5f7aaec915f..38d969cae54 100644 --- a/test/proxy/transparent/ProxyAdmin.test.js +++ b/test/proxy/transparent/ProxyAdmin.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ImplementationLabel } from '../../helpers/storage'; -const { getAddressInSlot, ImplementationSlot } = require('../../helpers/storage'); +const { + ethers, + helpers: { storage }, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [admin, other] = await ethers.getSigners(); @@ -47,7 +51,7 @@ describe('ProxyAdmin', function () { describe('with authorized account', function () { it('upgrades implementation', async function () { await this.proxyAdmin.connect(this.admin).upgradeAndCall(this.proxy, this.v2, '0x'); - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.v2); + expect(await storage.getAddressInSlot(this.proxy, ImplementationLabel)).to.equal(this.v2); }); }); }); @@ -66,7 +70,9 @@ describe('ProxyAdmin', function () { describe('with invalid callData', function () { it('fails to upgrade', async function () { const data = '0x12345678'; - await expect(this.proxyAdmin.connect(this.admin).upgradeAndCall(this.proxy, this.v2, data)).to.be.reverted; + await expect(this.proxyAdmin.connect(this.admin).upgradeAndCall(this.proxy, this.v2, data)).to.be.revert( + ethers, + ); }); }); @@ -74,7 +80,7 @@ describe('ProxyAdmin', function () { it('upgrades implementation', async function () { const data = this.v2.interface.encodeFunctionData('initializeNonPayableWithValue', [1337n]); await this.proxyAdmin.connect(this.admin).upgradeAndCall(this.proxy, this.v2, data); - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.v2); + expect(await storage.getAddressInSlot(this.proxy, ImplementationLabel)).to.equal(this.v2); }); }); }); diff --git a/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js b/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js index 2ad527d1bc6..cfc0789f316 100644 --- a/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js +++ b/test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js @@ -1,25 +1,26 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); - -const { impersonate } = require('../../helpers/account'); -const { getAddressInSlot, ImplementationSlot, AdminSlot } = require('../../helpers/storage'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { ImplementationLabel, AdminLabel } from '../../helpers/storage'; // createProxy, initialOwner, accounts -module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { +export function shouldBehaveLikeTransparentUpgradeableProxy() { before(async function () { - const implementationV0 = await ethers.deployContract('DummyImplementation'); - const implementationV1 = await ethers.deployContract('DummyImplementation'); + const implementationV0 = await this.ethers.deployContract('DummyImplementation'); + const implementationV1 = await this.ethers.deployContract('DummyImplementation'); const createProxyWithImpersonatedProxyAdmin = async (logic, initData, opts = undefined) => { const [proxy, tx] = await this.createProxy(logic, initData, opts).then(instance => - Promise.all([ethers.getContractAt('ITransparentUpgradeableProxy', instance), instance.deploymentTransaction()]), + Promise.all([ + this.ethers.getContractAt('ITransparentUpgradeableProxy', instance), + instance.deploymentTransaction(), + ]), ); - const proxyAdmin = await ethers.getContractAt( + const proxyAdmin = await this.ethers.getContractAt( 'ProxyAdmin', ethers.getCreateAddress({ from: proxy.target, nonce: 1n }), ); - const proxyAdminAsSigner = await proxyAdmin.getAddress().then(impersonate); + const proxyAdminAsSigner = await proxyAdmin.getAddress().then(this.helpers.impersonate); return { instance: logic.attach(proxy.target), // attaching proxy directly works well for everything except for event resolution @@ -49,7 +50,9 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { describe('implementation', function () { it('returns the current implementation address', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.implementationV0); + expect(await this.helpers.storage.getAddressInSlot(this.proxy, ImplementationLabel)).to.equal( + this.implementationV0, + ); }); it('delegates to the implementation', async function () { @@ -63,7 +66,7 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('sets the proxy admin in storage with the correct initial owner', async function () { - expect(await getAddressInSlot(this.proxy, AdminSlot)).to.equal(this.proxyAdmin); + expect(await this.helpers.storage.getAddressInSlot(this.proxy, AdminLabel)).to.equal(this.proxyAdmin); expect(await this.proxyAdmin.owner()).to.equal(this.owner); }); @@ -71,7 +74,7 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { it('can overwrite the admin by the implementation', async function () { await this.instance.unsafeOverrideAdmin(this.other); - const ERC1967AdminSlotValue = await getAddressInSlot(this.proxy, AdminSlot); + const ERC1967AdminSlotValue = await this.helpers.storage.getAddressInSlot(this.proxy, AdminLabel); expect(ERC1967AdminSlotValue).to.equal(this.other); expect(ERC1967AdminSlotValue).to.not.equal(this.proxyAdmin); @@ -85,7 +88,7 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { describe('upgradeToAndCall', function () { describe('without migrations', function () { beforeEach(async function () { - this.behavior = await ethers.deployContract('InitializableMock'); + this.behavior = await this.ethers.deployContract('InitializableMock'); }); describe('when the call does not fail', function () { @@ -105,7 +108,9 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('upgrades to the requested implementation', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.behavior); + expect(await this.helpers.storage.getAddressInSlot(this.proxy, ImplementationLabel)).to.equal( + this.behavior, + ); }); it('emits an event', async function () { @@ -117,21 +122,22 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('sends given value to the proxy', async function () { - expect(await ethers.provider.getBalance(this.proxy)).to.equal(value); + expect(await this.proxy.runner.provider.getBalance(this.proxy)).to.equal(value); }); it('uses the storage of the proxy', async function () { // storage layout should look as follows: // - 0: Initializable storage ++ initializerRan ++ onlyInitializingRan // - 1: x - expect(await ethers.provider.getStorage(this.proxy, 1n)).to.equal(42n); + expect(await this.proxy.runner.provider.getStorage(this.proxy, 1n)).to.equal(42n); }); }); describe('when the sender is not the admin', function () { it('reverts', async function () { - await expect(this.proxy.connect(this.other).upgradeToAndCall(this.behavior, this.initializeData)).to.be - .reverted; + await expect( + this.proxy.connect(this.other).upgradeToAndCall(this.behavior, this.initializeData), + ).to.be.revert(ethers); }); }); }); @@ -142,8 +148,9 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('reverts', async function () { - await expect(this.proxy.connect(this.proxyAdminAsSigner).upgradeToAndCall(this.behavior, this.initializeData)) - .to.be.reverted; + await expect( + this.proxy.connect(this.proxyAdminAsSigner).upgradeToAndCall(this.behavior, this.initializeData), + ).to.be.revert(ethers); }); }); }); @@ -154,10 +161,10 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { describe('when upgrading to V1', function () { beforeEach(async function () { - this.behaviorV1 = await ethers.deployContract('MigratableMockV1'); + this.behaviorV1 = await this.ethers.deployContract('MigratableMockV1'); const v1MigrationData = this.behaviorV1.interface.encodeFunctionData('initialize', [42n]); - this.balancePreviousV1 = await ethers.provider.getBalance(this.proxy); + this.balancePreviousV1 = await this.proxy.runner.provider.getBalance(this.proxy); this.tx = await this.proxy .connect(this.proxyAdminAsSigner) .upgradeToAndCall(this.behaviorV1, v1MigrationData, { @@ -166,22 +173,24 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('upgrades to the requested version and emits an event', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.behaviorV1); + expect(await this.helpers.storage.getAddressInSlot(this.proxy, ImplementationLabel)).to.equal( + this.behaviorV1, + ); await expect(this.tx).to.emit(this.proxy, 'Upgraded').withArgs(this.behaviorV1); }); it("calls the 'initialize' function and sends given value to the proxy", async function () { expect(await this.behaviorV1.attach(this.proxy).x()).to.equal(42n); - expect(await ethers.provider.getBalance(this.proxy)).to.equal(this.balancePreviousV1 + value); + expect(await this.proxy.runner.provider.getBalance(this.proxy)).to.equal(this.balancePreviousV1 + value); }); describe('when upgrading to V2', function () { beforeEach(async function () { - this.behaviorV2 = await ethers.deployContract('MigratableMockV2'); + this.behaviorV2 = await this.ethers.deployContract('MigratableMockV2'); const v2MigrationData = this.behaviorV2.interface.encodeFunctionData('migrate', [10n, 42n]); - this.balancePreviousV2 = await ethers.provider.getBalance(this.proxy); + this.balancePreviousV2 = await this.proxy.runner.provider.getBalance(this.proxy); this.tx = await this.proxy .connect(this.proxyAdminAsSigner) .upgradeToAndCall(this.behaviorV2, v2MigrationData, { @@ -190,7 +199,9 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('upgrades to the requested version and emits an event', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.behaviorV2); + expect(await this.helpers.storage.getAddressInSlot(this.proxy, ImplementationLabel)).to.equal( + this.behaviorV2, + ); await expect(this.tx).to.emit(this.proxy, 'Upgraded').withArgs(this.behaviorV2); }); @@ -198,15 +209,15 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { it("calls the 'migrate' function and sends given value to the proxy", async function () { expect(await this.behaviorV2.attach(this.proxy).x()).to.equal(10n); expect(await this.behaviorV2.attach(this.proxy).y()).to.equal(42n); - expect(await ethers.provider.getBalance(this.proxy)).to.equal(this.balancePreviousV2 + value); + expect(await this.proxy.runner.provider.getBalance(this.proxy)).to.equal(this.balancePreviousV2 + value); }); describe('when upgrading to V3', function () { beforeEach(async function () { - this.behaviorV3 = await ethers.deployContract('MigratableMockV3'); + this.behaviorV3 = await this.ethers.deployContract('MigratableMockV3'); const v3MigrationData = this.behaviorV3.interface.encodeFunctionData('migrate()'); - this.balancePreviousV3 = await ethers.provider.getBalance(this.proxy); + this.balancePreviousV3 = await this.proxy.runner.provider.getBalance(this.proxy); this.tx = await this.proxy .connect(this.proxyAdminAsSigner) .upgradeToAndCall(this.behaviorV3, v3MigrationData, { @@ -215,7 +226,9 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('upgrades to the requested version and emits an event', async function () { - expect(await getAddressInSlot(this.proxy, ImplementationSlot)).to.equal(this.behaviorV3); + expect(await this.helpers.storage.getAddressInSlot(this.proxy, ImplementationLabel)).to.equal( + this.behaviorV3, + ); await expect(this.tx).to.emit(this.proxy, 'Upgraded').withArgs(this.behaviorV3); }); @@ -223,7 +236,9 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { it("calls the 'migrate' function and sends given value to the proxy", async function () { expect(await this.behaviorV3.attach(this.proxy).x()).to.equal(42n); expect(await this.behaviorV3.attach(this.proxy).y()).to.equal(10n); - expect(await ethers.provider.getBalance(this.proxy)).to.equal(this.balancePreviousV3 + value); + expect(await this.proxy.runner.provider.getBalance(this.proxy)).to.equal( + this.balancePreviousV3 + value, + ); }); }); }); @@ -232,9 +247,11 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { describe('when the sender is not the admin', function () { it('reverts', async function () { - const behaviorV1 = await ethers.deployContract('MigratableMockV1'); + const behaviorV1 = await this.ethers.deployContract('MigratableMockV1'); const v1MigrationData = behaviorV1.interface.encodeFunctionData('initialize', [42n]); - await expect(this.proxy.connect(this.other).upgradeToAndCall(behaviorV1, v1MigrationData)).to.be.reverted; + await expect(this.proxy.connect(this.other).upgradeToAndCall(behaviorV1, v1MigrationData)).to.be.revert( + ethers, + ); }); }); }); @@ -242,8 +259,8 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { describe('transparent proxy', function () { beforeEach('creating proxy', async function () { - this.clashingImplV0 = await ethers.deployContract('ClashingImplementation'); - this.clashingImplV1 = await ethers.deployContract('ClashingImplementation'); + this.clashingImplV0 = await this.ethers.deployContract('ClashingImplementation'); + this.clashingImplV1 = await this.ethers.deployContract('ClashingImplementation'); Object.assign( this, @@ -255,7 +272,7 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('proxy admin cannot call delegated functions', async function () { - const factory = await ethers.getContractFactory('TransparentUpgradeableProxy'); + const factory = await this.ethers.getContractFactory('TransparentUpgradeableProxy'); await expect(this.instance.connect(this.proxyAdminAsSigner).delegatedFunction()).to.be.revertedWithCustomError( factory, @@ -280,8 +297,8 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { describe('regression', function () { it('should add new function', async function () { - const impl1 = await ethers.deployContract('Implementation1'); - const impl2 = await ethers.deployContract('Implementation2'); + const impl1 = await this.ethers.deployContract('Implementation1'); + const impl2 = await this.ethers.deployContract('Implementation2'); const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( impl1, impl1.interface.encodeFunctionData('initialize'), @@ -290,7 +307,7 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { await instance.setValue(42n); // `getValue` is not available in impl1 - await expect(impl2.attach(instance).getValue()).to.be.reverted; + await expect(impl2.attach(instance).getValue()).to.be.revert(ethers); // do upgrade await proxy.connect(proxyAdminAsSigner).upgradeToAndCall(impl2, '0x'); @@ -300,8 +317,8 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('should remove function', async function () { - const impl1 = await ethers.deployContract('Implementation1'); - const impl2 = await ethers.deployContract('Implementation2'); + const impl1 = await this.ethers.deployContract('Implementation1'); + const impl2 = await this.ethers.deployContract('Implementation2'); const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( impl2, impl2.interface.encodeFunctionData('initialize'), @@ -316,12 +333,12 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { await proxy.connect(proxyAdminAsSigner).upgradeToAndCall(impl1, '0x'); // `getValue` is not available in impl1 - await expect(impl2.attach(instance).getValue()).to.be.reverted; + await expect(impl2.attach(instance).getValue()).to.be.revert(ethers); }); it('should change function signature', async function () { - const impl1 = await ethers.deployContract('Implementation1'); - const impl3 = await ethers.deployContract('Implementation3'); + const impl1 = await this.ethers.deployContract('Implementation1'); + const impl3 = await this.ethers.deployContract('Implementation3'); const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( impl1, impl1.interface.encodeFunctionData('initialize'), @@ -335,8 +352,8 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('should add fallback function', async function () { - const impl1 = await ethers.deployContract('Implementation1'); - const impl4 = await ethers.deployContract('Implementation4'); + const impl1 = await this.ethers.deployContract('Implementation1'); + const impl4 = await this.ethers.deployContract('Implementation4'); const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( impl1, impl1.interface.encodeFunctionData('initialize'), @@ -350,8 +367,8 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { }); it('should remove fallback function', async function () { - const impl2 = await ethers.deployContract('Implementation2'); - const impl4 = await ethers.deployContract('Implementation4'); + const impl2 = await this.ethers.deployContract('Implementation2'); + const impl4 = await this.ethers.deployContract('Implementation4'); const { instance, proxy, proxyAdminAsSigner } = await this.createProxyWithImpersonatedProxyAdmin( impl4, impl4.interface.encodeFunctionData('initialize'), @@ -359,9 +376,9 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy() { await proxy.connect(proxyAdminAsSigner).upgradeToAndCall(impl2, '0x'); - await expect(this.other.sendTransaction({ to: proxy })).to.be.reverted; + await expect(this.other.sendTransaction({ to: proxy })).to.be.revert(ethers); expect(await impl2.attach(instance).getValue()).to.equal(0n); }); }); -}; +} diff --git a/test/proxy/transparent/TransparentUpgradeableProxy.test.js b/test/proxy/transparent/TransparentUpgradeableProxy.test.js index 61e18014e5b..853c791dea2 100644 --- a/test/proxy/transparent/TransparentUpgradeableProxy.test.js +++ b/test/proxy/transparent/TransparentUpgradeableProxy.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { shouldBehaveLikeProxy } from '../Proxy.behaviour'; +import { shouldBehaveLikeTransparentUpgradeableProxy } from './TransparentUpgradeableProxy.behaviour'; -const shouldBehaveLikeProxy = require('../Proxy.behaviour'); -const shouldBehaveLikeTransparentUpgradeableProxy = require('./TransparentUpgradeableProxy.behaviour'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { const [owner, other, ...accounts] = await ethers.getSigners(); @@ -17,6 +21,10 @@ async function fixture() { } describe('TransparentUpgradeableProxy', function () { + before(function () { + Object.assign(this, connection); + }); + beforeEach(async function () { Object.assign(this, await loadFixture(fixture)); }); diff --git a/test/proxy/utils/Initializable.test.js b/test/proxy/utils/Initializable.test.js index 6bf213f0d9d..4f84e76074e 100644 --- a/test/proxy/utils/Initializable.test.js +++ b/test/proxy/utils/Initializable.test.js @@ -1,6 +1,8 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { MAX_UINT64 } = require('../../helpers/constants'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT64 } from '../../helpers/constants'; + +const { ethers } = await network.create(); describe('Initializable', function () { describe('basic testing without inheritance', function () { diff --git a/test/proxy/utils/UUPSUpgradeable.test.js b/test/proxy/utils/UUPSUpgradeable.test.js index 55f910df67e..7b3a55128a0 100644 --- a/test/proxy/utils/UUPSUpgradeable.test.js +++ b/test/proxy/utils/UUPSUpgradeable.test.js @@ -1,8 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { ImplementationLabel } from '../../helpers/storage'; -const { getAddressInSlot, ImplementationSlot } = require('../../helpers/storage'); +const connection = await network.create(); +const { + ethers, + helpers: { storage }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { const implInitial = await ethers.deployContract('UUPSUpgradeableMock'); @@ -30,7 +35,7 @@ async function fixture() { describe('UUPSUpgradeable', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); it('has an interface version', async function () { @@ -42,7 +47,7 @@ describe('UUPSUpgradeable', function () { .to.emit(this.instance, 'Upgraded') .withArgs(this.implUpgradeOk); - expect(await getAddressInSlot(this.instance, ImplementationSlot)).to.equal(this.implUpgradeOk); + expect(await storage.getAddressInSlot(this.instance, ImplementationLabel)).to.equal(this.implUpgradeOk); }); it('upgrade to upgradeable implementation with call', async function () { @@ -54,7 +59,7 @@ describe('UUPSUpgradeable', function () { .to.emit(this.instance, 'Upgraded') .withArgs(this.implUpgradeOk); - expect(await getAddressInSlot(this.instance, ImplementationSlot)).to.equal(this.implUpgradeOk); + expect(await storage.getAddressInSlot(this.instance, ImplementationLabel)).to.equal(this.implUpgradeOk); expect(await this.instance.current()).to.equal(1n); }); @@ -98,7 +103,7 @@ describe('UUPSUpgradeable', function () { .to.emit(this.instance, 'Upgraded') .withArgs(this.implUpgradeUnsafe); - expect(await getAddressInSlot(this.instance, ImplementationSlot)).to.equal(this.implUpgradeUnsafe); + expect(await storage.getAddressInSlot(this.instance, ImplementationLabel)).to.equal(this.implUpgradeUnsafe); }); // delegate to a non existing upgradeTo function causes a low level revert diff --git a/test/sanity.test.js b/test/sanity.test.js index ea0175c48c6..8bcf03a52be 100644 --- a/test/sanity.test.js +++ b/test/sanity.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture, mine }, +} = await network.create(); async function fixture() { return {}; diff --git a/test/token/ERC1155/ERC1155.behavior.js b/test/token/ERC1155/ERC1155.behavior.js index 22f3ac6c40a..fe71afcb650 100644 --- a/test/token/ERC1155/ERC1155.behavior.js +++ b/test/token/ERC1155/ERC1155.behavior.js @@ -1,11 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; +import { RevertType } from '../../helpers/enums'; +import { shouldSupportInterfaces } from '../../utils/introspection/SupportsInterface.behavior'; -const { RevertType } = require('../../helpers/enums'); -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -function shouldBehaveLikeERC1155() { +export function shouldBehaveLikeERC1155() { const firstTokenId = 1n; const secondTokenId = 2n; const unknownTokenId = 3n; @@ -259,7 +258,7 @@ function shouldBehaveLikeERC1155() { describe('when sending to a valid receiver', function () { beforeEach(async function () { - this.receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + this.receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.None, @@ -317,7 +316,7 @@ function shouldBehaveLikeERC1155() { describe('to a receiver contract returning unexpected value', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ '0x00c0ffee', RECEIVER_BATCH_MAGIC_VALUE, RevertType.None, @@ -336,7 +335,7 @@ function shouldBehaveLikeERC1155() { describe('to a receiver contract that reverts', function () { describe('with a revert string', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.RevertWithMessage, @@ -352,7 +351,7 @@ function shouldBehaveLikeERC1155() { describe('without a revert string', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.RevertWithoutMessage, @@ -370,7 +369,7 @@ function shouldBehaveLikeERC1155() { describe('with a custom error', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.RevertWithCustomError, @@ -388,7 +387,7 @@ function shouldBehaveLikeERC1155() { describe('with a panic', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.Panic, @@ -613,7 +612,7 @@ function shouldBehaveLikeERC1155() { describe('when sending to a valid receiver', function () { beforeEach(async function () { - this.receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + this.receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.None, @@ -719,7 +718,7 @@ function shouldBehaveLikeERC1155() { describe('to a receiver contract returning unexpected value', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_SINGLE_MAGIC_VALUE, RevertType.None, @@ -744,7 +743,7 @@ function shouldBehaveLikeERC1155() { describe('to a receiver contract that reverts', function () { describe('with a revert string', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.RevertWithMessage, @@ -766,7 +765,7 @@ function shouldBehaveLikeERC1155() { describe('without a revert string', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.RevertWithoutMessage, @@ -790,7 +789,7 @@ function shouldBehaveLikeERC1155() { describe('with a custom error', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.RevertWithCustomError, @@ -814,7 +813,7 @@ function shouldBehaveLikeERC1155() { describe('with a panic', function () { it('reverts', async function () { - const receiver = await ethers.deployContract('$ERC1155ReceiverMock', [ + const receiver = await this.ethers.deployContract('$ERC1155ReceiverMock', [ RECEIVER_SINGLE_MAGIC_VALUE, RECEIVER_BATCH_MAGIC_VALUE, RevertType.Panic, @@ -859,7 +858,3 @@ function shouldBehaveLikeERC1155() { shouldSupportInterfaces(['ERC1155', 'ERC1155MetadataURI']); }); } - -module.exports = { - shouldBehaveLikeERC1155, -}; diff --git a/test/token/ERC1155/ERC1155.test.js b/test/token/ERC1155/ERC1155.test.js index 265cfb17555..a1803cd4778 100644 --- a/test/token/ERC1155/ERC1155.test.js +++ b/test/token/ERC1155/ERC1155.test.js @@ -1,10 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { RevertType } = require('../../helpers/enums'); -const { zip } = require('../../helpers/iterate'); -const { shouldBehaveLikeERC1155 } = require('./ERC1155.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { RevertType } from '../../helpers/enums'; +import { zip } from '../../helpers/iterate'; +import { shouldBehaveLikeERC1155 } from './ERC1155.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const initialURI = 'https://token-cdn-domain/{id}.json'; @@ -16,7 +20,7 @@ async function fixture() { describe('ERC1155', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeERC1155(); diff --git a/test/token/ERC1155/extensions/ERC1155Burnable.test.js b/test/token/ERC1155/extensions/ERC1155Burnable.test.js index 01e7ee2edbf..0268c18fd38 100644 --- a/test/token/ERC1155/extensions/ERC1155Burnable.test.js +++ b/test/token/ERC1155/extensions/ERC1155Burnable.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const ids = [42n, 1137n]; const values = [3000n, 9902n]; diff --git a/test/token/ERC1155/extensions/ERC1155Crosschain.test.js b/test/token/ERC1155/extensions/ERC1155Crosschain.test.js index 69ebe1cda7e..839a06cff7d 100644 --- a/test/token/ERC1155/extensions/ERC1155Crosschain.test.js +++ b/test/token/ERC1155/extensions/ERC1155Crosschain.test.js @@ -1,14 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeBridgeERC1155 } from '../../../crosschain/BridgeERC1155.behavior'; -const { impersonate } = require('../../../helpers/account'); -const { getLocalChain } = require('../../../helpers/chains'); - -const { shouldBehaveLikeBridgeERC1155 } = require('../../../crosschain/BridgeERC1155.behavior'); +const connection = await network.create(); +const { + ethers, + helpers: { chain, impersonate }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { - const chain = await getLocalChain(); const accounts = await ethers.getSigners(); // Mock gateway @@ -31,12 +32,12 @@ async function fixture() { .to.emit(bridgeA, 'LinkRegistered') .withArgs(gateway, chain.toErc7930(bridgeB)); - return { chain, accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; + return { accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; } describe('ERC1155Crosschain', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeBridgeERC1155(); diff --git a/test/token/ERC1155/extensions/ERC1155Pausable.test.js b/test/token/ERC1155/extensions/ERC1155Pausable.test.js index 81c4f69bc45..dce2baa7f11 100644 --- a/test/token/ERC1155/extensions/ERC1155Pausable.test.js +++ b/test/token/ERC1155/extensions/ERC1155Pausable.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [holder, operator, receiver, other] = await ethers.getSigners(); diff --git a/test/token/ERC1155/extensions/ERC1155Supply.test.js b/test/token/ERC1155/extensions/ERC1155Supply.test.js index cca36a0dfed..9866ff3da06 100644 --- a/test/token/ERC1155/extensions/ERC1155Supply.test.js +++ b/test/token/ERC1155/extensions/ERC1155Supply.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [holder] = await ethers.getSigners(); diff --git a/test/token/ERC1155/extensions/ERC1155URIStorage.test.js b/test/token/ERC1155/extensions/ERC1155URIStorage.test.js index a0d9b570488..ea86913034d 100644 --- a/test/token/ERC1155/extensions/ERC1155URIStorage.test.js +++ b/test/token/ERC1155/extensions/ERC1155URIStorage.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const erc1155Uri = 'https://token.com/nfts/'; const baseUri = 'https://token.com/'; diff --git a/test/token/ERC1155/utils/ERC1155Holder.test.js b/test/token/ERC1155/utils/ERC1155Holder.test.js index 9bff487adad..9112fb1796a 100644 --- a/test/token/ERC1155/utils/ERC1155Holder.test.js +++ b/test/token/ERC1155/utils/ERC1155Holder.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldSupportInterfaces } from '../../../utils/introspection/SupportsInterface.behavior'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const ids = [1n, 2n, 3n]; const values = [1000n, 2000n, 3000n]; diff --git a/test/token/ERC1155/utils/ERC1155Utils.test.js b/test/token/ERC1155/utils/ERC1155Utils.test.js index 5687568d341..57a8d3d0263 100644 --- a/test/token/ERC1155/utils/ERC1155Utils.test.js +++ b/test/token/ERC1155/utils/ERC1155Utils.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { RevertType } = require('../../../helpers/enums'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { RevertType } from '../../../helpers/enums'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const firstTokenId = 1n; const secondTokenId = 2n; @@ -52,7 +56,7 @@ describe('ERC1155Utils', function () { firstTokenValue, '0x', ), - ).to.not.be.reverted; + ).to.not.be.revert(ethers); }); it('succeeds when data is passed', async function () { @@ -66,7 +70,7 @@ describe('ERC1155Utils', function () { firstTokenValue, data, ), - ).to.not.be.reverted; + ).to.not.be.revert(ethers); }); it('succeeds when data is empty', async function () { @@ -79,7 +83,7 @@ describe('ERC1155Utils', function () { firstTokenValue, '0x', ), - ).to.not.be.reverted; + ).to.not.be.revert(ethers); }); it('reverts when receiver returns invalid value', async function () { @@ -180,7 +184,7 @@ describe('ERC1155Utils', function () { [firstTokenValue, secondTokenValue], '0x', ), - ).to.not.be.reverted; + ).to.not.be.revert(ethers); }); it('succeeds when data is passed', async function () { @@ -194,7 +198,7 @@ describe('ERC1155Utils', function () { [firstTokenValue, secondTokenValue], data, ), - ).to.not.be.reverted; + ).to.not.be.revert(ethers); }); it('succeeds when data is empty', async function () { @@ -207,7 +211,7 @@ describe('ERC1155Utils', function () { [firstTokenValue, secondTokenValue], '0x', ), - ).to.not.be.reverted; + ).to.not.be.revert(ethers); }); it('reverts when receiver returns invalid value', async function () { diff --git a/test/token/ERC20/ERC20.behavior.js b/test/token/ERC20/ERC20.behavior.js index 2447602dbbf..fc83a0a133b 100644 --- a/test/token/ERC20/ERC20.behavior.js +++ b/test/token/ERC20/ERC20.behavior.js @@ -1,7 +1,7 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; -function shouldBehaveLikeERC20(initialSupply, opts = {}) { +export function shouldBehaveLikeERC20(initialSupply, opts = {}) { const { forcedApproval } = opts; beforeEach(async function () { @@ -46,7 +46,12 @@ function shouldBehaveLikeERC20(initialSupply, opts = {}) { }); it('transfers the requested value', async function () { - await expect(this.tx).to.changeTokenBalances(this.token, [this.holder, this.other], [-value, value]); + await expect(this.tx).to.changeTokenBalances( + this.ethers, + this.token, + [this.holder, this.other], + [-value, value], + ); }); it('decreases the spender allowance', async function () { @@ -157,7 +162,7 @@ function shouldBehaveLikeERC20(initialSupply, opts = {}) { }); } -function shouldBehaveLikeERC20Transfer(balance) { +export function shouldBehaveLikeERC20Transfer(balance) { describe('when the recipient is not the zero address', function () { it('reverts when the sender does not have enough balance', async function () { const value = balance + 1n; @@ -174,7 +179,12 @@ function shouldBehaveLikeERC20Transfer(balance) { }); it('transfers the requested value', async function () { - await expect(this.tx).to.changeTokenBalances(this.token, [this.holder, this.recipient], [-value, value]); + await expect(this.tx).to.changeTokenBalances( + this.ethers, + this.token, + [this.holder, this.recipient], + [-value, value], + ); }); it('emits a transfer event', async function () { @@ -190,7 +200,7 @@ function shouldBehaveLikeERC20Transfer(balance) { }); it('transfers the requested value', async function () { - await expect(this.tx).to.changeTokenBalances(this.token, [this.holder, this.recipient], [0n, 0n]); + await expect(this.tx).to.changeTokenBalances(this.ethers, this.token, [this.holder, this.recipient], [0n, 0n]); }); it('emits a transfer event', async function () { @@ -206,7 +216,7 @@ function shouldBehaveLikeERC20Transfer(balance) { }); } -function shouldBehaveLikeERC20Approve(supply) { +export function shouldBehaveLikeERC20Approve(supply) { describe('when the spender is not the zero address', function () { describe('when the sender has enough balance', function () { const value = supply; @@ -261,9 +271,3 @@ function shouldBehaveLikeERC20Approve(supply) { .withArgs(ethers.ZeroAddress); }); } - -module.exports = { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -}; diff --git a/test/token/ERC20/ERC20.test.js b/test/token/ERC20/ERC20.test.js index 2d9eefe1c89..43db634a201 100644 --- a/test/token/ERC20/ERC20.test.js +++ b/test/token/ERC20/ERC20.test.js @@ -1,13 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { shouldBehaveLikeERC20, shouldBehaveLikeERC20Transfer, shouldBehaveLikeERC20Approve } from './ERC20.behavior'; +const connection = await network.create(); const { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -} = require('./ERC20.behavior'); + ethers, + networkHelpers: { loadFixture }, +} = connection; const TOKENS = [{ Token: '$ERC20' }, { Token: '$ERC20ApprovalMock', forcedApproval: true }]; @@ -30,7 +30,7 @@ describe('ERC20', function () { }; beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeERC20(initialSupply, { forcedApproval }); @@ -71,7 +71,7 @@ describe('ERC20', function () { }); it('increments recipient balance', async function () { - await expect(this.tx).to.changeTokenBalance(this.token, this.recipient, value); + await expect(this.tx).to.changeTokenBalance(ethers, this.token, this.recipient, value); }); it('emits Transfer event', async function () { @@ -105,7 +105,7 @@ describe('ERC20', function () { }); it('decrements holder balance', async function () { - await expect(this.tx).to.changeTokenBalance(this.token, this.holder, -value); + await expect(this.tx).to.changeTokenBalance(ethers, this.token, this.holder, -value); }); it('emits Transfer event', async function () { @@ -131,7 +131,7 @@ describe('ERC20', function () { await expect(tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, this.holder, value); expect(await this.token.totalSupply()).to.equal(this.totalSupply + value); - await expect(tx).to.changeTokenBalance(this.token, this.holder, value); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.holder, value); }); it('to is the zero address', async function () { @@ -139,7 +139,7 @@ describe('ERC20', function () { await expect(tx).to.emit(this.token, 'Transfer').withArgs(this.holder, ethers.ZeroAddress, value); expect(await this.token.totalSupply()).to.equal(this.totalSupply - value); - await expect(tx).to.changeTokenBalance(this.token, this.holder, -value); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.holder, -value); }); describe('from and to are the same address', function () { @@ -148,7 +148,7 @@ describe('ERC20', function () { await expect(tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, ethers.ZeroAddress, value); expect(await this.token.totalSupply()).to.equal(this.totalSupply); - await expect(tx).to.changeTokenBalance(this.token, ethers.ZeroAddress, 0n); + await expect(tx).to.changeTokenBalance(ethers, this.token, ethers.ZeroAddress, 0n); }); describe('non zero address', function () { @@ -160,7 +160,7 @@ describe('ERC20', function () { it('executes with balance', async function () { const tx = await this.token.$_update(this.holder, this.holder, value); - await expect(tx).to.changeTokenBalance(this.token, this.holder, 0n); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.holder, 0n); await expect(tx).to.emit(this.token, 'Transfer').withArgs(this.holder, this.holder, value); }); }); diff --git a/test/token/ERC20/extensions/ERC1363.test.js b/test/token/ERC20/extensions/ERC1363.test.js index 3d1f4e58f8e..b3e73edd580 100644 --- a/test/token/ERC20/extensions/ERC1363.test.js +++ b/test/token/ERC20/extensions/ERC1363.test.js @@ -1,14 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeERC20, shouldBehaveLikeERC20Transfer, shouldBehaveLikeERC20Approve } from '../ERC20.behavior'; +import { shouldSupportInterfaces } from '../../../utils/introspection/SupportsInterface.behavior'; +import { RevertType } from '../../../helpers/enums'; +const connection = await network.create(); const { - shouldBehaveLikeERC20, - shouldBehaveLikeERC20Transfer, - shouldBehaveLikeERC20Approve, -} = require('../ERC20.behavior.js'); -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); -const { RevertType } = require('../../../helpers/enums.js'); + ethers, + networkHelpers: { loadFixture }, +} = connection; const name = 'My Token'; const symbol = 'MTKN'; @@ -42,7 +42,7 @@ async function fixture() { describe('ERC1363', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldSupportInterfaces(['ERC165', 'ERC1363']); diff --git a/test/token/ERC20/extensions/ERC20Burnable.test.js b/test/token/ERC20/extensions/ERC20Burnable.test.js index dc40c791773..9a8d729f94e 100644 --- a/test/token/ERC20/extensions/ERC20Burnable.test.js +++ b/test/token/ERC20/extensions/ERC20Burnable.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'My Token'; const symbol = 'MTKN'; @@ -40,7 +44,7 @@ describe('ERC20Burnable', function () { }); it('burns the requested value', async function () { - await expect(this.tx).to.changeTokenBalance(this.token, this.owner, -value); + await expect(this.tx).to.changeTokenBalance(ethers, this.token, this.owner, -value); }); it('emits a transfer event', async function () { @@ -88,7 +92,7 @@ describe('ERC20Burnable', function () { }); it('burns the requested value', async function () { - await expect(this.tx).to.changeTokenBalance(this.token, this.owner, -value); + await expect(this.tx).to.changeTokenBalance(ethers, this.token, this.owner, -value); }); it('decrements allowance', async function () { diff --git a/test/token/ERC20/extensions/ERC20Capped.test.js b/test/token/ERC20/extensions/ERC20Capped.test.js index a32ec43a8ea..392100cd97f 100644 --- a/test/token/ERC20/extensions/ERC20Capped.test.js +++ b/test/token/ERC20/extensions/ERC20Capped.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'My Token'; const symbol = 'MTKN'; diff --git a/test/token/ERC20/extensions/ERC20Crosschain.test.js b/test/token/ERC20/extensions/ERC20Crosschain.test.js index cd1acdb2c54..9faf82cb0d4 100644 --- a/test/token/ERC20/extensions/ERC20Crosschain.test.js +++ b/test/token/ERC20/extensions/ERC20Crosschain.test.js @@ -1,15 +1,16 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { impersonate } = require('../../../helpers/account'); -const { getLocalChain } = require('../../../helpers/chains'); - -const { shouldBehaveLikeBridgeERC20 } = require('../../../crosschain/BridgeERC20.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; +import { shouldBehaveLikeBridgeERC20 } from '../../../crosschain/BridgeERC20.behavior'; + +const connection = await network.create(); +const { + ethers, + helpers: { chain, impersonate }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { - const chain = await getLocalChain(); const accounts = await ethers.getSigners(); // Mock gateway @@ -30,12 +31,12 @@ async function fixture() { .withArgs(gateway, chain.toErc7930(bridgeB)); await tokenB.$_setBridge(bridgeB); - return { chain, accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; + return { accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; } describe('ERC20Crosschain', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeBridgeERC20(); @@ -49,18 +50,18 @@ describe('ERC20Crosschain', function () { await this.tokenA.connect(alice).approve(chris, ethers.MaxUint256); // Alice sends tokens from chain A to Bruce on chain B. - await expect(this.tokenA.connect(chris).crosschainTransferFrom(alice, this.chain.toErc7930(bruce), amount)) + await expect(this.tokenA.connect(chris).crosschainTransferFrom(alice, chain.toErc7930(bruce), amount)) // bridge on chain A takes custody of the funds .to.emit(this.tokenA, 'Transfer') .withArgs(alice, ethers.ZeroAddress, amount) // crosschain transfer sent .to.emit(this.tokenA, 'CrosschainFungibleTransferSent') - .withArgs(anyValue, alice, this.chain.toErc7930(bruce), amount) + .withArgs(anyValue, alice, chain.toErc7930(bruce), amount) // ERC-7786 event .to.emit(this.gateway, 'MessageSent') // crosschain transfer received .to.emit(this.bridgeB, 'CrosschainFungibleTransferReceived') - .withArgs(anyValue, this.chain.toErc7930(alice), bruce, amount) + .withArgs(anyValue, chain.toErc7930(alice), bruce, amount) // crosschain mint event .to.emit(this.tokenB, 'CrosschainMint') .withArgs(bruce, amount, this.bridgeB) @@ -75,7 +76,7 @@ describe('ERC20Crosschain', function () { await this.tokenA.$_mint(alice, amount); - await expect(this.tokenA.connect(chris).crosschainTransferFrom(alice, this.chain.toErc7930(bruce), amount)) + await expect(this.tokenA.connect(chris).crosschainTransferFrom(alice, chain.toErc7930(bruce), amount)) .to.be.revertedWithCustomError(this.tokenA, 'ERC20InsufficientAllowance') .withArgs(chris, 0n, amount); }); diff --git a/test/token/ERC20/extensions/ERC20FlashMint.test.js b/test/token/ERC20/extensions/ERC20FlashMint.test.js index 1c751f74cec..39381def620 100644 --- a/test/token/ERC20/extensions/ERC20FlashMint.test.js +++ b/test/token/ERC20/extensions/ERC20FlashMint.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'My Token'; const symbol = 'MTKN'; @@ -63,7 +67,7 @@ describe('ERC20FlashMint', function () { .withArgs(this.token, receiver, loanValue) .to.emit(receiver, 'TotalSupply') .withArgs(this.token, initialSupply + loanValue); - await expect(tx).to.changeTokenBalance(this.token, receiver, 0); + await expect(tx).to.changeTokenBalance(ethers, this.token, receiver, 0); expect(await this.token.totalSupply()).to.equal(initialSupply); expect(await this.token.allowance(receiver, this.token)).to.equal(0n); @@ -110,7 +114,7 @@ describe('ERC20FlashMint', function () { await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(ethers.ZeroAddress, this.receiver, receiverInitialBalance); - await expect(tx).to.changeTokenBalance(this.token, this.receiver, receiverInitialBalance); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.receiver, receiverInitialBalance); await this.token.setFlashFee(flashFee); expect(await this.token.flashFee(this.token, loanValue)).to.equal(flashFee); @@ -127,7 +131,12 @@ describe('ERC20FlashMint', function () { .withArgs(this.token, this.receiver, receiverInitialBalance + loanValue) .to.emit(this.receiver, 'TotalSupply') .withArgs(this.token, initialSupply + receiverInitialBalance + loanValue); - await expect(tx).to.changeTokenBalances(this.token, [this.receiver, ethers.ZeroAddress], [-flashFee, 0]); + await expect(tx).to.changeTokenBalances( + ethers, + this.token, + [this.receiver, ethers.ZeroAddress], + [-flashFee, 0], + ); expect(await this.token.totalSupply()).to.equal(initialSupply + receiverInitialBalance - flashFee); expect(await this.token.allowance(this.receiver, this.token)).to.equal(0n); @@ -151,6 +160,7 @@ describe('ERC20FlashMint', function () { .to.emit(this.receiver, 'TotalSupply') .withArgs(this.token, initialSupply + receiverInitialBalance + loanValue); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.receiver, flashFeeReceiverAddress], [-flashFee, flashFee], diff --git a/test/token/ERC20/extensions/ERC20Pausable.test.js b/test/token/ERC20/extensions/ERC20Pausable.test.js index 1f1157c19e9..bfa18715fc5 100644 --- a/test/token/ERC20/extensions/ERC20Pausable.test.js +++ b/test/token/ERC20/extensions/ERC20Pausable.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'My Token'; const symbol = 'MTKN'; @@ -24,6 +28,7 @@ describe('ERC20Pausable', function () { describe('transfer', function () { it('allows to transfer when unpaused', async function () { await expect(this.token.connect(this.holder).transfer(this.recipient, initialSupply)).to.changeTokenBalances( + ethers, this.token, [this.holder, this.recipient], [-initialSupply, initialSupply], @@ -35,6 +40,7 @@ describe('ERC20Pausable', function () { await this.token.$_unpause(); await expect(this.token.connect(this.holder).transfer(this.recipient, initialSupply)).to.changeTokenBalances( + ethers, this.token, [this.holder, this.recipient], [-initialSupply, initialSupply], @@ -60,7 +66,7 @@ describe('ERC20Pausable', function () { it('allows to transfer from when unpaused', async function () { await expect( this.token.connect(this.approved).transferFrom(this.holder, this.recipient, allowance), - ).to.changeTokenBalances(this.token, [this.holder, this.recipient], [-allowance, allowance]); + ).to.changeTokenBalances(ethers, this.token, [this.holder, this.recipient], [-allowance, allowance]); }); it('allows to transfer when paused and then unpaused', async function () { @@ -69,7 +75,7 @@ describe('ERC20Pausable', function () { await expect( this.token.connect(this.approved).transferFrom(this.holder, this.recipient, allowance), - ).to.changeTokenBalances(this.token, [this.holder, this.recipient], [-allowance, allowance]); + ).to.changeTokenBalances(ethers, this.token, [this.holder, this.recipient], [-allowance, allowance]); }); it('reverts when trying to transfer from when paused', async function () { @@ -85,14 +91,24 @@ describe('ERC20Pausable', function () { const value = 42n; it('allows to mint when unpaused', async function () { - await expect(this.token.$_mint(this.recipient, value)).to.changeTokenBalance(this.token, this.recipient, value); + await expect(this.token.$_mint(this.recipient, value)).to.changeTokenBalance( + ethers, + this.token, + this.recipient, + value, + ); }); it('allows to mint when paused and then unpaused', async function () { await this.token.$_pause(); await this.token.$_unpause(); - await expect(this.token.$_mint(this.recipient, value)).to.changeTokenBalance(this.token, this.recipient, value); + await expect(this.token.$_mint(this.recipient, value)).to.changeTokenBalance( + ethers, + this.token, + this.recipient, + value, + ); }); it('reverts when trying to mint when paused', async function () { @@ -109,14 +125,24 @@ describe('ERC20Pausable', function () { const value = 42n; it('allows to burn when unpaused', async function () { - await expect(this.token.$_burn(this.holder, value)).to.changeTokenBalance(this.token, this.holder, -value); + await expect(this.token.$_burn(this.holder, value)).to.changeTokenBalance( + ethers, + this.token, + this.holder, + -value, + ); }); it('allows to burn when paused and then unpaused', async function () { await this.token.$_pause(); await this.token.$_unpause(); - await expect(this.token.$_burn(this.holder, value)).to.changeTokenBalance(this.token, this.holder, -value); + await expect(this.token.$_burn(this.holder, value)).to.changeTokenBalance( + ethers, + this.token, + this.holder, + -value, + ); }); it('reverts when trying to burn when paused', async function () { diff --git a/test/token/ERC20/extensions/ERC20Permit.test.js b/test/token/ERC20/extensions/ERC20Permit.test.js index c3c80d7bbe9..64465b1a3ec 100644 --- a/test/token/ERC20/extensions/ERC20Permit.test.js +++ b/test/token/ERC20/extensions/ERC20Permit.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain, domainSeparator, Permit } = require('../../../helpers/eip712'); -const time = require('../../../helpers/time'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { Permit, getDomain, domainSeparator } from '../../../helpers/eip712'; + +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'My Token'; const symbol = 'MTKN'; diff --git a/test/token/ERC20/extensions/ERC20Votes.test.js b/test/token/ERC20/extensions/ERC20Votes.test.js index da350b741ea..c7e26f238ae 100644 --- a/test/token/ERC20/extensions/ERC20Votes.test.js +++ b/test/token/ERC20/extensions/ERC20Votes.test.js @@ -1,12 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); - -const { getDomain, Delegation } = require('../../../helpers/eip712'); -const { batchInBlock } = require('../../../helpers/txpool'); -const time = require('../../../helpers/time'); - -const { shouldBehaveLikeVotes } = require('../../../governance/utils/Votes.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { Delegation, getDomain } from '../../../helpers/eip712'; +import { batchInBlock } from '../../../helpers/txpool'; +import { shouldBehaveLikeVotes } from '../../../governance/utils/Votes.behavior'; + +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture, mine }, +} = connection; const TOKENS = [ { Token: '$ERC20Votes', mode: 'blockNumber' }, @@ -33,7 +36,7 @@ describe('ERC20Votes', function () { describe(`vote with ${mode}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); this.votes = this.token; }); @@ -401,11 +404,14 @@ describe('ERC20Votes', function () { await this.token.connect(this.holder).transfer(this.recipient, 100n); expect(await this.token.numCheckpoints(this.other1)).to.equal(0n); - const [t1, t2, t3] = await batchInBlock([ - () => this.token.connect(this.recipient).delegate(this.other1, { gasLimit: 200000 }), - () => this.token.connect(this.recipient).transfer(this.other2, 10n, { gasLimit: 200000 }), - () => this.token.connect(this.recipient).transfer(this.other2, 10n, { gasLimit: 200000 }), - ]); + const [t1, t2, t3] = await batchInBlock( + [ + () => this.token.connect(this.recipient).delegate(this.other1, { gasLimit: 200_000n }), + () => this.token.connect(this.recipient).transfer(this.other2, 10n, { gasLimit: 200_000n }), + () => this.token.connect(this.recipient).transfer(this.other2, 10n, { gasLimit: 200_000n }), + ], + ethers.provider, + ); t1.timepoint = await time.clockFromReceipt[mode](t1); t2.timepoint = await time.clockFromReceipt[mode](t2); t3.timepoint = await time.clockFromReceipt[mode](t3); diff --git a/test/token/ERC20/extensions/ERC20Wrapper.test.js b/test/token/ERC20/extensions/ERC20Wrapper.test.js index 2f630e638c1..8bebf468cab 100644 --- a/test/token/ERC20/extensions/ERC20Wrapper.test.js +++ b/test/token/ERC20/extensions/ERC20Wrapper.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeERC20 } from '../ERC20.behavior'; -const { shouldBehaveLikeERC20 } = require('../ERC20.behavior'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const name = 'My Token'; const symbol = 'MTKN'; @@ -24,7 +28,7 @@ async function fixture() { describe('ERC20Wrapper', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); afterEach('Underlying balance', async function () { @@ -64,11 +68,12 @@ describe('ERC20Wrapper', function () { .to.emit(this.token, 'Transfer') .withArgs(ethers.ZeroAddress, this.holder, initialSupply); await expect(tx).to.changeTokenBalances( + ethers, this.underlying, [this.holder, this.token], [-initialSupply, initialSupply], ); - await expect(tx).to.changeTokenBalance(this.token, this.holder, initialSupply); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.holder, initialSupply); }); it('reverts when missing approval', async function () { @@ -95,11 +100,12 @@ describe('ERC20Wrapper', function () { .to.emit(this.token, 'Transfer') .withArgs(ethers.ZeroAddress, this.recipient, initialSupply); await expect(tx).to.changeTokenBalances( + ethers, this.underlying, [this.holder, this.token], [-initialSupply, initialSupply], ); - await expect(tx).to.changeTokenBalances(this.token, [this.holder, this.recipient], [0, initialSupply]); + await expect(tx).to.changeTokenBalances(ethers, this.token, [this.holder, this.recipient], [0, initialSupply]); }); it('reverts minting to the wrapper contract', async function () { @@ -132,8 +138,8 @@ describe('ERC20Wrapper', function () { .withArgs(this.token.target, this.holder, value) .to.emit(this.token, 'Transfer') .withArgs(this.holder, ethers.ZeroAddress, value); - await expect(tx).to.changeTokenBalances(this.underlying, [this.token, this.holder], [-value, value]); - await expect(tx).to.changeTokenBalance(this.token, this.holder, -value); + await expect(tx).to.changeTokenBalances(ethers, this.underlying, [this.token, this.holder], [-value, value]); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.holder, -value); }); it('entire balance', async function () { @@ -144,11 +150,12 @@ describe('ERC20Wrapper', function () { .to.emit(this.token, 'Transfer') .withArgs(this.holder, ethers.ZeroAddress, initialSupply); await expect(tx).to.changeTokenBalances( + ethers, this.underlying, [this.token, this.holder], [-initialSupply, initialSupply], ); - await expect(tx).to.changeTokenBalance(this.token, this.holder, -initialSupply); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.holder, -initialSupply); }); it('to other account', async function () { @@ -159,11 +166,12 @@ describe('ERC20Wrapper', function () { .to.emit(this.token, 'Transfer') .withArgs(this.holder, ethers.ZeroAddress, initialSupply); await expect(tx).to.changeTokenBalances( + ethers, this.underlying, [this.token, this.holder, this.recipient], [-initialSupply, 0, initialSupply], ); - await expect(tx).to.changeTokenBalance(this.token, this.holder, -initialSupply); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.holder, -initialSupply); }); it('reverts withdrawing to the wrapper contract', async function () { @@ -180,7 +188,7 @@ describe('ERC20Wrapper', function () { const tx = await this.token.$_recover(this.recipient); await expect(tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, this.recipient, 0n); - await expect(tx).to.changeTokenBalance(this.token, this.recipient, 0); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.recipient, 0); }); it('something to recover', async function () { @@ -188,7 +196,7 @@ describe('ERC20Wrapper', function () { const tx = await this.token.$_recover(this.recipient); await expect(tx).to.emit(this.token, 'Transfer').withArgs(ethers.ZeroAddress, this.recipient, initialSupply); - await expect(tx).to.changeTokenBalance(this.token, this.recipient, initialSupply); + await expect(tx).to.changeTokenBalance(ethers, this.token, this.recipient, initialSupply); }); }); diff --git a/test/token/ERC20/extensions/ERC4626.test.js b/test/token/ERC20/extensions/ERC4626.test.js index ad8c926917f..1e542edca8e 100644 --- a/test/token/ERC20/extensions/ERC4626.test.js +++ b/test/token/ERC20/extensions/ERC4626.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { Enum } from '../../../helpers/enums'; -const { Enum } = require('../../../helpers/enums'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'My Token'; const symbol = 'MTKN'; @@ -260,11 +263,12 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).deposit(parseToken(1n), this.recipient); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.holder, this.vault], [-parseToken(1n), parseToken(1n)], ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, parseShare(1n)); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.recipient, parseShare(1n)); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.holder, this.vault, parseToken(1n)) @@ -281,11 +285,12 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).mint(parseShare(1n), this.recipient); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.holder, this.vault], [-parseToken(1n), parseToken(1n)], ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, parseShare(1n)); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.recipient, parseShare(1n)); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.holder, this.vault, parseToken(1n)) @@ -301,8 +306,8 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).withdraw(0n, this.recipient, this.holder); - await expect(tx).to.changeTokenBalances(this.token, [this.vault, this.recipient], [0n, 0n]); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, 0n); + await expect(tx).to.changeTokenBalances(ethers, this.token, [this.vault, this.recipient], [0n, 0n]); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.holder, 0n); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.vault, this.recipient, 0n) @@ -318,8 +323,8 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).redeem(0n, this.recipient, this.holder); - await expect(tx).to.changeTokenBalances(this.token, [this.vault, this.recipient], [0n, 0n]); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, 0n); + await expect(tx).to.changeTokenBalances(ethers, this.token, [this.vault, this.recipient], [0n, 0n]); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.holder, 0n); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.vault, this.recipient, 0n) @@ -365,11 +370,12 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).deposit(depositAssets, this.recipient); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.holder, this.vault], [-depositAssets, depositAssets], ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, expectedShares); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.recipient, expectedShares); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.holder, this.vault, depositAssets) @@ -403,11 +409,12 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).mint(mintShares, this.recipient); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.holder, this.vault], [-expectedAssets, expectedAssets], ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, mintShares); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.recipient, mintShares); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.holder, this.vault, expectedAssets) @@ -423,8 +430,8 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).withdraw(0n, this.recipient, this.holder); - await expect(tx).to.changeTokenBalances(this.token, [this.vault, this.recipient], [0n, 0n]); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, 0n); + await expect(tx).to.changeTokenBalances(ethers, this.token, [this.vault, this.recipient], [0n, 0n]); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.holder, 0n); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.vault, this.recipient, 0n) @@ -440,8 +447,8 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).redeem(0n, this.recipient, this.holder); - await expect(tx).to.changeTokenBalances(this.token, [this.vault, this.recipient], [0n, 0n]); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, 0n); + await expect(tx).to.changeTokenBalances(ethers, this.token, [this.vault, this.recipient], [0n, 0n]); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.holder, 0n); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.vault, this.recipient, 0n) @@ -486,11 +493,12 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).deposit(depositAssets, this.recipient); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.holder, this.vault], [-depositAssets, depositAssets], ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, expectedShares); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.recipient, expectedShares); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.holder, this.vault, depositAssets) @@ -522,11 +530,12 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).mint(mintShares, this.recipient); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.holder, this.vault], [-expectedAssets, expectedAssets], ); - await expect(tx).to.changeTokenBalance(this.vault, this.recipient, mintShares); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.recipient, mintShares); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.holder, this.vault, expectedAssets) @@ -549,11 +558,12 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).withdraw(withdrawAssets, this.recipient, this.holder); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.vault, this.recipient], [-withdrawAssets, withdrawAssets], ); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, -expectedShares); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.holder, -expectedShares); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.vault, this.recipient, withdrawAssets) @@ -570,8 +580,9 @@ describe('ERC4626', function () { .to.be.revertedWithCustomError(this.vault, 'ERC20InsufficientAllowance') .withArgs(this.other, 0n, assets); - await expect(this.vault.connect(this.spender).withdraw(parseToken(1n), this.recipient, this.holder)).to.not.be - .reverted; + await expect( + this.vault.connect(this.spender).withdraw(parseToken(1n), this.recipient, this.holder), + ).to.not.be.revert(ethers); }); it('redeem', async function () { @@ -587,11 +598,12 @@ describe('ERC4626', function () { const tx = this.vault.connect(this.holder).redeem(redeemShares, this.recipient, this.holder); await expect(tx).to.changeTokenBalances( + ethers, this.token, [this.vault, this.recipient], [-expectedAssets, expectedAssets], ); - await expect(tx).to.changeTokenBalance(this.vault, this.holder, -redeemShares); + await expect(tx).to.changeTokenBalance(ethers, this.vault, this.holder, -redeemShares); await expect(tx) .to.emit(this.token, 'Transfer') .withArgs(this.vault, this.recipient, expectedAssets) @@ -606,8 +618,9 @@ describe('ERC4626', function () { .to.be.revertedWithCustomError(this.vault, 'ERC20InsufficientAllowance') .withArgs(this.other, 0n, parseShare(100n)); - await expect(this.vault.connect(this.spender).redeem(parseShare(100n), this.recipient, this.holder)).to.not.be - .reverted; + await expect( + this.vault.connect(this.spender).redeem(parseShare(100n), this.recipient, this.holder), + ).to.not.be.revert(ethers); }); }); }); @@ -650,11 +663,12 @@ describe('ERC4626', function () { afterEach(async function () { await expect(this.tx).to.changeTokenBalances( + ethers, this.token, [this.holder, this.vault, this.other], [-valueWithFees, valueWithoutFees, fees], ); - await expect(this.tx).to.changeTokenBalance(this.vault, this.recipient, valueWithoutFees); + await expect(this.tx).to.changeTokenBalance(ethers, this.vault, this.recipient, valueWithoutFees); await expect(this.tx) // get total .to.emit(this.token, 'Transfer') @@ -702,11 +716,12 @@ describe('ERC4626', function () { afterEach(async function () { await expect(this.tx).to.changeTokenBalances( + ethers, this.token, [this.vault, this.recipient, this.other], [-valueWithFees, valueWithoutFees, fees], ); - await expect(this.tx).to.changeTokenBalance(this.vault, this.holder, -valueWithFees); + await expect(this.tx).to.changeTokenBalance(ethers, this.vault, this.holder, -valueWithFees); await expect(this.tx) // withdraw principal .to.emit(this.token, 'Transfer') diff --git a/test/token/ERC20/extensions/draft-ERC20Bridgeable.test.js b/test/token/ERC20/extensions/draft-ERC20Bridgeable.test.js index 06c3bb29095..8c3b07c5d2e 100644 --- a/test/token/ERC20/extensions/draft-ERC20Bridgeable.test.js +++ b/test/token/ERC20/extensions/draft-ERC20Bridgeable.test.js @@ -1,9 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeERC20 } from '../ERC20.behavior'; +import { shouldSupportInterfaces } from '../../../utils/introspection/SupportsInterface.behavior'; -const { shouldBehaveLikeERC20 } = require('../ERC20.behavior.js'); -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const name = 'My Token'; const symbol = 'MTKN'; @@ -20,7 +24,7 @@ async function fixture() { describe('ERC20Bridgeable', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); describe('onlyTokenBridgeFn', function () { diff --git a/test/token/ERC20/extensions/draft-ERC20TemporaryApproval.test.js b/test/token/ERC20/extensions/draft-ERC20TemporaryApproval.test.js index a1f6362add6..f4e7a323658 100644 --- a/test/token/ERC20/extensions/draft-ERC20TemporaryApproval.test.js +++ b/test/token/ERC20/extensions/draft-ERC20TemporaryApproval.test.js @@ -1,9 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { max, min } = require('../../../helpers/math.js'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { max, min } from '../../../helpers/math'; +import { shouldBehaveLikeERC20 } from '../ERC20.behavior'; -const { shouldBehaveLikeERC20 } = require('../ERC20.behavior.js'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const name = 'My Token'; const symbol = 'MTKN'; @@ -26,7 +30,7 @@ async function fixture() { describe('ERC20TemporaryApproval', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeERC20(initialSupply); diff --git a/test/token/ERC20/utils/SafeERC20.test.js b/test/token/ERC20/utils/SafeERC20.test.js index 2a503385d24..c29d2fd6f09 100644 --- a/test/token/ERC20/utils/SafeERC20.test.js +++ b/test/token/ERC20/utils/SafeERC20.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'ERC20Mock'; const symbol = 'ERC20Mock'; @@ -84,12 +88,12 @@ describe('SafeERC20', function () { it('reverts on increaseAllowance', async function () { // Call to 'token.allowance' does not return any data, resulting in a decoding error (revert without reason) - await expect(this.mock.$safeIncreaseAllowance(this.token, this.spender, 0n)).to.be.revertedWithoutReason(); + await expect(this.mock.$safeIncreaseAllowance(this.token, this.spender, 0n)).to.be.revertedWithoutReason(ethers); }); it('reverts on decreaseAllowance', async function () { // Call to 'token.allowance' does not return any data, resulting in a decoding error (revert without reason) - await expect(this.mock.$safeDecreaseAllowance(this.token, this.spender, 0n)).to.be.revertedWithoutReason(); + await expect(this.mock.$safeDecreaseAllowance(this.token, this.spender, 0n)).to.be.revertedWithoutReason(ethers); }); it('reverts on forceApprove', async function () { @@ -320,19 +324,19 @@ describe('SafeERC20', function () { it('reverts on transferAndCallRelaxed', async function () { await expect( this.mock.$transferAndCallRelaxed(this.token, this.erc1363Receiver, 0n, data), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); }); it('reverts on transferFromAndCallRelaxed', async function () { await expect( this.mock.$transferFromAndCallRelaxed(this.token, this.mock, this.erc1363Receiver, 0n, data), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); }); it('reverts on approveAndCallRelaxed', async function () { await expect( this.mock.$approveAndCallRelaxed(this.token, this.erc1363Spender, 0n, data), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); }); }); diff --git a/test/token/ERC6909/ERC6909.behavior.js b/test/token/ERC6909/ERC6909.behavior.js index adfe15a32e6..df51d5ad0e5 100644 --- a/test/token/ERC6909/ERC6909.behavior.js +++ b/test/token/ERC6909/ERC6909.behavior.js @@ -1,9 +1,8 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { shouldSupportInterfaces } from '../../utils/introspection/SupportsInterface.behavior'; -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -function shouldBehaveLikeERC6909() { +export function shouldBehaveLikeERC6909() { const firstTokenId = 1n; const secondTokenId = 2n; const randomTokenId = 125523n; @@ -210,7 +209,3 @@ function shouldBehaveLikeERC6909() { shouldSupportInterfaces(['ERC6909']); }); } - -module.exports = { - shouldBehaveLikeERC6909, -}; diff --git a/test/token/ERC6909/ERC6909.test.js b/test/token/ERC6909/ERC6909.test.js index fa41145aa69..e3ed34d4c81 100644 --- a/test/token/ERC6909/ERC6909.test.js +++ b/test/token/ERC6909/ERC6909.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldBehaveLikeERC6909 } = require('./ERC6909.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeERC6909 } from './ERC6909.behavior'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [holder, operator, recipient, other] = await ethers.getSigners(); diff --git a/test/token/ERC6909/extensions/ERC6909ContentURI.test.js b/test/token/ERC6909/extensions/ERC6909ContentURI.test.js index 72021a4d643..0437a81762e 100644 --- a/test/token/ERC6909/extensions/ERC6909ContentURI.test.js +++ b/test/token/ERC6909/extensions/ERC6909ContentURI.test.js @@ -1,11 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldSupportInterfaces } from '../../../utils/introspection/SupportsInterface.behavior'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const token = await ethers.deployContract('$ERC6909ContentURI'); - return { token }; + return { token: await ethers.deployContract('$ERC6909ContentURI') }; } describe('ERC6909ContentURI', function () { diff --git a/test/token/ERC6909/extensions/ERC6909Metadata.test.js b/test/token/ERC6909/extensions/ERC6909Metadata.test.js index 2fa2e153dc6..4a734dc9c19 100644 --- a/test/token/ERC6909/extensions/ERC6909Metadata.test.js +++ b/test/token/ERC6909/extensions/ERC6909Metadata.test.js @@ -1,12 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldSupportInterfaces } from '../../../utils/introspection/SupportsInterface.behavior'; -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const token = await ethers.deployContract('$ERC6909Metadata'); - return { token }; + return { token: await ethers.deployContract('$ERC6909Metadata') }; } describe('ERC6909Metadata', function () { diff --git a/test/token/ERC6909/extensions/ERC6909TokenSupply.test.js b/test/token/ERC6909/extensions/ERC6909TokenSupply.test.js index 9ccd5e5a6c3..3750061dfba 100644 --- a/test/token/ERC6909/extensions/ERC6909TokenSupply.test.js +++ b/test/token/ERC6909/extensions/ERC6909TokenSupply.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldBehaveLikeERC6909 } = require('../ERC6909.behavior'); -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeERC6909 } from '../ERC6909.behavior'; +import { shouldSupportInterfaces } from '../../../utils/introspection/SupportsInterface.behavior'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [holder, operator, recipient, other] = await ethers.getSigners(); diff --git a/test/token/ERC721/ERC721.behavior.js b/test/token/ERC721/ERC721.behavior.js index 63b4e19bece..f1048802658 100644 --- a/test/token/ERC721/ERC721.behavior.js +++ b/test/token/ERC721/ERC721.behavior.js @@ -1,10 +1,9 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); -const { anyValue } = require('@nomicfoundation/hardhat-chai-matchers/withArgs'); - -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); -const { RevertType } = require('../../helpers/enums'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { anyValue } from '@nomicfoundation/hardhat-ethers-chai-matchers/withArgs'; +import { RevertType } from '../../helpers/enums'; +import { shouldSupportInterfaces } from '../../utils/introspection/SupportsInterface.behavior'; const firstTokenId = 5042n; const secondTokenId = 79217n; @@ -13,7 +12,7 @@ const fourthTokenId = 4n; const RECEIVER_MAGIC_VALUE = '0x150b7a02'; -function shouldBehaveLikeERC721() { +export function shouldBehaveLikeERC721() { beforeEach(async function () { const [owner, newOwner, approved, operator, other] = this.accounts; Object.assign(this, { owner, newOwner, approved, operator, other }); @@ -240,7 +239,7 @@ function shouldBehaveLikeERC721() { describe('to a valid receiver contract', function () { beforeEach(async function () { - this.to = await ethers.deployContract('ERC721ReceiverMock', [RECEIVER_MAGIC_VALUE, RevertType.None]); + this.to = await this.ethers.deployContract('ERC721ReceiverMock', [RECEIVER_MAGIC_VALUE, RevertType.None]); }); shouldTransferTokensByUsers(fragment, opts); @@ -297,7 +296,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract returning unexpected value', function () { it('reverts', async function () { - const invalidReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const invalidReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ '0xdeadbeef', RevertType.None, ]); @@ -310,7 +309,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract that reverts with message', function () { it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const revertingReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ RECEIVER_MAGIC_VALUE, RevertType.RevertWithMessage, ]); @@ -323,7 +322,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract that reverts without message', function () { it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const revertingReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ RECEIVER_MAGIC_VALUE, RevertType.RevertWithoutMessage, ]); @@ -336,7 +335,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract that reverts with custom error', function () { it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const revertingReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ RECEIVER_MAGIC_VALUE, RevertType.RevertWithCustomError, ]); @@ -349,7 +348,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract that panics', function () { it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const revertingReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ RECEIVER_MAGIC_VALUE, RevertType.Panic, ]); @@ -362,7 +361,7 @@ function shouldBehaveLikeERC721() { describe('to a contract that does not implement the required function', function () { it('reverts', async function () { - const nonReceiver = await ethers.deployContract('CallReceiverMock'); + const nonReceiver = await this.ethers.deployContract('CallReceiverMock'); await expect(this.token.connect(this.owner)[fnName](this.owner, nonReceiver, tokenId)) .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') @@ -380,7 +379,10 @@ function shouldBehaveLikeERC721() { describe('via safeMint', function () { // regular minting is tested in ERC721Mintable.test.js and others it('calls onERC721Received — with data', async function () { - const receiver = await ethers.deployContract('ERC721ReceiverMock', [RECEIVER_MAGIC_VALUE, RevertType.None]); + const receiver = await this.ethers.deployContract('ERC721ReceiverMock', [ + RECEIVER_MAGIC_VALUE, + RevertType.None, + ]); await expect(await this.token.$_safeMint(receiver, tokenId, ethers.Typed.bytes(data))) .to.emit(receiver, 'Received') @@ -388,7 +390,10 @@ function shouldBehaveLikeERC721() { }); it('calls onERC721Received — without data', async function () { - const receiver = await ethers.deployContract('ERC721ReceiverMock', [RECEIVER_MAGIC_VALUE, RevertType.None]); + const receiver = await this.ethers.deployContract('ERC721ReceiverMock', [ + RECEIVER_MAGIC_VALUE, + RevertType.None, + ]); await expect(await this.token.$_safeMint(receiver, tokenId)) .to.emit(receiver, 'Received') @@ -397,7 +402,10 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract returning unexpected value', function () { it('reverts', async function () { - const invalidReceiver = await ethers.deployContract('ERC721ReceiverMock', ['0xdeadbeef', RevertType.None]); + const invalidReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ + '0xdeadbeef', + RevertType.None, + ]); await expect(this.token.$_safeMint(invalidReceiver, tokenId)) .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') @@ -407,7 +415,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract that reverts with message', function () { it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const revertingReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ RECEIVER_MAGIC_VALUE, RevertType.RevertWithMessage, ]); @@ -420,7 +428,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract that reverts without message', function () { it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const revertingReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ RECEIVER_MAGIC_VALUE, RevertType.RevertWithoutMessage, ]); @@ -433,7 +441,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract that reverts with custom error', function () { it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const revertingReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ RECEIVER_MAGIC_VALUE, RevertType.RevertWithCustomError, ]); @@ -446,7 +454,7 @@ function shouldBehaveLikeERC721() { describe('to a receiver contract that panics', function () { it('reverts', async function () { - const revertingReceiver = await ethers.deployContract('ERC721ReceiverMock', [ + const revertingReceiver = await this.ethers.deployContract('ERC721ReceiverMock', [ RECEIVER_MAGIC_VALUE, RevertType.Panic, ]); @@ -459,7 +467,7 @@ function shouldBehaveLikeERC721() { describe('to a contract that does not implement the required function', function () { it('reverts', async function () { - const nonReceiver = await ethers.deployContract('CallReceiverMock'); + const nonReceiver = await this.ethers.deployContract('CallReceiverMock'); await expect(this.token.$_safeMint(nonReceiver, tokenId)) .to.be.revertedWithCustomError(this.token, 'ERC721InvalidReceiver') @@ -755,7 +763,7 @@ function shouldBehaveLikeERC721() { }); } -function shouldBehaveLikeERC721Enumerable() { +export function shouldBehaveLikeERC721Enumerable() { beforeEach(async function () { const [owner, newOwner, approved, operator, other] = this.accounts; Object.assign(this, { owner, newOwner, approved, operator, other }); @@ -917,7 +925,7 @@ function shouldBehaveLikeERC721Enumerable() { }); } -function shouldBehaveLikeERC721Metadata(name, symbol) { +export function shouldBehaveLikeERC721Metadata(name, symbol) { shouldSupportInterfaces(['ERC721Metadata']); describe('metadata', function () { @@ -946,9 +954,3 @@ function shouldBehaveLikeERC721Metadata(name, symbol) { }); }); } - -module.exports = { - shouldBehaveLikeERC721, - shouldBehaveLikeERC721Enumerable, - shouldBehaveLikeERC721Metadata, -}; diff --git a/test/token/ERC721/ERC721.test.js b/test/token/ERC721/ERC721.test.js index 1454cb057c6..02d1c5246bc 100644 --- a/test/token/ERC721/ERC721.test.js +++ b/test/token/ERC721/ERC721.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { shouldBehaveLikeERC721, shouldBehaveLikeERC721Metadata } from './ERC721.behavior'; -const { shouldBehaveLikeERC721, shouldBehaveLikeERC721Metadata } = require('./ERC721.behavior'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const name = 'Non Fungible Token'; const symbol = 'NFT'; @@ -15,7 +19,7 @@ async function fixture() { describe('ERC721', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeERC721(); diff --git a/test/token/ERC721/ERC721Enumerable.test.js b/test/token/ERC721/ERC721Enumerable.test.js index a3bdea73f5a..861cf35333a 100644 --- a/test/token/ERC721/ERC721Enumerable.test.js +++ b/test/token/ERC721/ERC721Enumerable.test.js @@ -1,11 +1,15 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { +import { network } from 'hardhat'; +import { shouldBehaveLikeERC721, shouldBehaveLikeERC721Metadata, shouldBehaveLikeERC721Enumerable, -} = require('./ERC721.behavior'); +} from './ERC721.behavior'; + +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const name = 'Non Fungible Token'; const symbol = 'NFT'; @@ -19,7 +23,7 @@ async function fixture() { describe('ERC721', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeERC721(); diff --git a/test/token/ERC721/extensions/ERC721Burnable.test.js b/test/token/ERC721/extensions/ERC721Burnable.test.js index d6f0b80c4f2..2e7fdb3c35a 100644 --- a/test/token/ERC721/extensions/ERC721Burnable.test.js +++ b/test/token/ERC721/extensions/ERC721Burnable.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'Non Fungible Token'; const symbol = 'NFT'; diff --git a/test/token/ERC721/extensions/ERC721Consecutive.test.js b/test/token/ERC721/extensions/ERC721Consecutive.test.js index 8d8a3037893..b64fd48706d 100644 --- a/test/token/ERC721/extensions/ERC721Consecutive.test.js +++ b/test/token/ERC721/extensions/ERC721Consecutive.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { sum } = require('../../../helpers/math'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { sum } from '../../../helpers/math'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'Non Fungible Token'; const symbol = 'NFT'; diff --git a/test/token/ERC721/extensions/ERC721Crosschain.test.js b/test/token/ERC721/extensions/ERC721Crosschain.test.js index 88c2a968bf1..4534b584418 100644 --- a/test/token/ERC721/extensions/ERC721Crosschain.test.js +++ b/test/token/ERC721/extensions/ERC721Crosschain.test.js @@ -1,14 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeBridgeERC721 } from '../../../crosschain/BridgeERC721.behavior'; -const { impersonate } = require('../../../helpers/account'); -const { getLocalChain } = require('../../../helpers/chains'); - -const { shouldBehaveLikeBridgeERC721 } = require('../../../crosschain/BridgeERC721.behavior'); +const connection = await network.create(); +const { + ethers, + helpers: { chain, impersonate }, + networkHelpers: { loadFixture }, +} = connection; async function fixture() { - const chain = await getLocalChain(); const accounts = await ethers.getSigners(); // Mock gateway @@ -32,12 +33,12 @@ async function fixture() { .to.emit(bridgeA, 'LinkRegistered') .withArgs(gateway, chain.toErc7930(bridgeB)); - return { chain, accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; + return { accounts, gateway, gatewayAsEOA, tokenA, tokenB, bridgeA, bridgeB }; } describe('ERC721Crosschain', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); shouldBehaveLikeBridgeERC721(); diff --git a/test/token/ERC721/extensions/ERC721Pausable.test.js b/test/token/ERC721/extensions/ERC721Pausable.test.js index acf731a4560..445bc09746a 100644 --- a/test/token/ERC721/extensions/ERC721Pausable.test.js +++ b/test/token/ERC721/extensions/ERC721Pausable.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'Non Fungible Token'; const symbol = 'NFT'; diff --git a/test/token/ERC721/extensions/ERC721Royalty.test.js b/test/token/ERC721/extensions/ERC721Royalty.test.js index e11954ae7a3..54d5d3a2d3f 100644 --- a/test/token/ERC721/extensions/ERC721Royalty.test.js +++ b/test/token/ERC721/extensions/ERC721Royalty.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldBehaveLikeERC2981 } = require('../../common/ERC2981.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeERC2981 } from '../../common/ERC2981.behavior'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'Non Fungible Token'; const symbol = 'NFT'; diff --git a/test/token/ERC721/extensions/ERC721URIStorage.test.js b/test/token/ERC721/extensions/ERC721URIStorage.test.js index 2048a85de70..bbb629cec1a 100644 --- a/test/token/ERC721/extensions/ERC721URIStorage.test.js +++ b/test/token/ERC721/extensions/ERC721URIStorage.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { shouldSupportInterfaces } = require('../../../utils/introspection/SupportsInterface.behavior'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldSupportInterfaces } from '../../../utils/introspection/SupportsInterface.behavior'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const name = 'Non Fungible Token'; const symbol = 'NFT'; diff --git a/test/token/ERC721/extensions/ERC721Votes.test.js b/test/token/ERC721/extensions/ERC721Votes.test.js index 2af0e89e199..b519a347dd8 100644 --- a/test/token/ERC721/extensions/ERC721Votes.test.js +++ b/test/token/ERC721/extensions/ERC721Votes.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mine } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeVotes } from '../../../governance/utils/Votes.behavior'; -const time = require('../../../helpers/time'); - -const { shouldBehaveLikeVotes } = require('../../../governance/utils/Votes.behavior'); +const connection = await network.create(); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture, mine }, +} = connection; const TOKENS = [ { Token: '$ERC721Votes', mode: 'blockNumber' }, @@ -30,7 +33,7 @@ describe('ERC721Votes', function () { describe(`vote with ${mode}`, function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); this.votes = this.token; }); diff --git a/test/token/ERC721/extensions/ERC721Wrapper.test.js b/test/token/ERC721/extensions/ERC721Wrapper.test.js index eeead4c1f10..541292af51f 100644 --- a/test/token/ERC721/extensions/ERC721Wrapper.test.js +++ b/test/token/ERC721/extensions/ERC721Wrapper.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { shouldBehaveLikeERC721 } from '../ERC721.behavior'; -const { shouldBehaveLikeERC721 } = require('../ERC721.behavior'); +const connection = await network.create(); +const { + ethers, + networkHelpers: { loadFixture }, +} = connection; const name = 'Non Fungible Token'; const symbol = 'NFT'; @@ -23,7 +27,7 @@ async function fixture() { describe('ERC721Wrapper', function () { beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); + Object.assign(this, connection, await loadFixture(fixture)); }); it('has a name', async function () { diff --git a/test/token/ERC721/utils/ERC721Holder.test.js b/test/token/ERC721/utils/ERC721Holder.test.js index 31dd2fd20db..26d370e0133 100644 --- a/test/token/ERC721/utils/ERC721Holder.test.js +++ b/test/token/ERC721/utils/ERC721Holder.test.js @@ -1,5 +1,7 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { ethers } = await network.create(); const name = 'Non Fungible Token'; const symbol = 'NFT'; diff --git a/test/token/ERC721/utils/ERC721Utils.test.js b/test/token/ERC721/utils/ERC721Utils.test.js index 2327d1ac7da..380215323fc 100644 --- a/test/token/ERC721/utils/ERC721Utils.test.js +++ b/test/token/ERC721/utils/ERC721Utils.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { RevertType } = require('../../../helpers/enums'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { RevertType } from '../../../helpers/enums'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const tokenId = 1n; @@ -36,19 +40,22 @@ describe('ERC721Utils', function () { describe('onERC721Received', function () { it('succeeds when called by an EOA', async function () { - await expect(this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.eoa, tokenId, '0x')).to - .not.be.reverted; + await expect( + this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.eoa, tokenId, '0x'), + ).to.not.be.revert(ethers); }); it('succeeds when data is passed', async function () { const data = '0x12345678'; - await expect(this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.correct, tokenId, data)) - .to.not.be.reverted; + await expect( + this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.correct, tokenId, data), + ).to.not.be.revert(ethers); }); it('succeeds when data is empty', async function () { - await expect(this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.correct, tokenId, '0x')) - .to.not.be.reverted; + await expect( + this.utils.$checkOnERC721Received(this.operator, this.owner, this.receivers.correct, tokenId, '0x'), + ).to.not.be.revert(ethers); }); it('reverts when receiver returns invalid value', async function () { diff --git a/test/token/common/ERC2981.behavior.js b/test/token/common/ERC2981.behavior.js index ae6abccaedb..317a1a57afe 100644 --- a/test/token/common/ERC2981.behavior.js +++ b/test/token/common/ERC2981.behavior.js @@ -1,9 +1,8 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { shouldSupportInterfaces } from '../../utils/introspection/SupportsInterface.behavior'; -const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior'); - -function shouldBehaveLikeERC2981() { +export function shouldBehaveLikeERC2981() { const royaltyFraction = 10n; shouldSupportInterfaces(['ERC2981']); @@ -146,7 +145,3 @@ function shouldBehaveLikeERC2981() { }); }); } - -module.exports = { - shouldBehaveLikeERC2981, -}; diff --git a/test/utils/Address.test.js b/test/utils/Address.test.js index 2335c223722..05fd1f1a289 100644 --- a/test/utils/Address.test.js +++ b/test/utils/Address.test.js @@ -1,9 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; -const coder = ethers.AbiCoder.defaultAbiCoder(); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const fakeContract = { interface: ethers.Interface.from(['error SomeCustomErrorWithoutArgs()']) }; const returndata = fakeContract.interface.encodeErrorResult('SomeCustomErrorWithoutArgs'); @@ -26,7 +28,7 @@ describe('Address', function () { describe('sendValue', function () { describe('when sender contract has no funds', function () { it('sends 0 wei', async function () { - await expect(this.mock.$sendValue(this.other, 0n)).to.changeEtherBalance(this.recipient, 0n); + await expect(this.mock.$sendValue(this.other, 0n)).to.changeEtherBalance(ethers, this.recipient, 0n); }); it('reverts when sending non-zero amounts', async function () { @@ -45,18 +47,23 @@ describe('Address', function () { describe('with EOA recipient', function () { it('sends 0 wei', async function () { - await expect(this.mock.$sendValue(this.recipient, 0n)).to.changeEtherBalance(this.recipient, 0n); + await expect(this.mock.$sendValue(this.recipient, 0n)).to.changeEtherBalance(ethers, this.recipient, 0n); }); it('sends non-zero amounts', async function () { await expect(this.mock.$sendValue(this.recipient, funds - 1n)).to.changeEtherBalance( + ethers, this.recipient, funds - 1n, ); }); it('sends the whole balance', async function () { - await expect(this.mock.$sendValue(this.recipient, funds)).to.changeEtherBalance(this.recipient, funds); + await expect(this.mock.$sendValue(this.recipient, funds)).to.changeEtherBalance( + ethers, + this.recipient, + funds, + ); expect(await ethers.provider.getBalance(this.mock)).to.equal(0n); }); @@ -70,7 +77,11 @@ describe('Address', function () { describe('with contract recipient', function () { it('sends funds', async function () { await this.targetEther.setAcceptEther(true); - await expect(this.mock.$sendValue(this.targetEther, funds)).to.changeEtherBalance(this.targetEther, funds); + await expect(this.mock.$sendValue(this.targetEther, funds)).to.changeEtherBalance( + ethers, + this.targetEther, + funds, + ); }); it('reverts on recipient revert', async function () { @@ -92,7 +103,7 @@ describe('Address', function () { await expect(this.mock.$functionCall(this.target, call)) .to.emit(this.target, 'MockFunctionCalled') .to.emit(this.mock, 'return$functionCall') - .withArgs(coder.encode(['string'], ['0x1234'])); + .withArgs(ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['0x1234'])); }); it('calls the requested empty return function', async function () { @@ -156,7 +167,7 @@ describe('Address', function () { await expect(this.mock.$functionCallWithValue(this.target, call, 0n)) .to.emit(this.target, 'MockFunctionCalled') .to.emit(this.mock, 'return$functionCallWithValue') - .withArgs(coder.encode(['string'], ['0x1234'])); + .withArgs(ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['0x1234'])); }); }); @@ -177,12 +188,12 @@ describe('Address', function () { const call = this.target.interface.encodeFunctionData('mockFunction'); const tx = await this.mock.$functionCallWithValue(this.target, call, value); - await expect(tx).to.changeEtherBalance(this.target, value); + await expect(tx).to.changeEtherBalance(ethers, this.target, value); await expect(tx) .to.emit(this.target, 'MockFunctionCalled') .to.emit(this.mock, 'return$functionCallWithValue') - .withArgs(coder.encode(['string'], ['0x1234'])); + .withArgs(ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['0x1234'])); }); it('calls the requested function with transaction funds', async function () { @@ -191,11 +202,11 @@ describe('Address', function () { const call = this.target.interface.encodeFunctionData('mockFunction'); const tx = await this.mock.connect(this.other).$functionCallWithValue(this.target, call, value, { value }); - await expect(tx).to.changeEtherBalance(this.target, value); + await expect(tx).to.changeEtherBalance(ethers, this.target, value); await expect(tx) .to.emit(this.target, 'MockFunctionCalled') .to.emit(this.mock, 'return$functionCallWithValue') - .withArgs(coder.encode(['string'], ['0x1234'])); + .withArgs(ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['0x1234'])); }); it('reverts when calling non-payable functions', async function () { @@ -215,7 +226,9 @@ describe('Address', function () { it('calls the requested function', async function () { const call = this.target.interface.encodeFunctionData('mockStaticFunction'); - expect(await this.mock.$functionStaticCall(this.target, call)).to.equal(coder.encode(['string'], ['0x1234'])); + expect(await this.mock.$functionStaticCall(this.target, call)).to.equal( + ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['0x1234']), + ); }); it('reverts on a non-static function', async function () { @@ -253,7 +266,7 @@ describe('Address', function () { await expect(await this.mock.$functionDelegateCall(this.target, call)) .to.emit(this.mock, 'return$functionDelegateCall') - .withArgs(coder.encode(['string'], ['0x1234'])); + .withArgs(ethers.AbiCoder.defaultAbiCoder().encode(['string'], ['0x1234'])); expect(await ethers.provider.getStorage(this.mock, slot)).to.equal(value); }); diff --git a/test/utils/Arrays.test.js b/test/utils/Arrays.test.js index 8a4bcb0162b..11856c2ebe4 100644 --- a/test/utils/Arrays.test.js +++ b/test/utils/Arrays.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { generators } from '../helpers/random'; +import { capitalize } from '../../scripts/helpers'; +import { TYPES } from '../../scripts/generate/templates/Arrays.opts'; -const { generators } = require('../helpers/random'); -const { capitalize } = require('../../scripts/helpers'); -const { TYPES } = require('../../scripts/generate/templates/Arrays.opts'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); // See https://en.cppreference.com/w/cpp/algorithm/lower_bound const lowerBound = (array, value) => { @@ -22,11 +25,11 @@ const bigintSign = x => (x > 0n ? 1 : x < 0n ? -1 : 0); const comparator = (a, b) => bigintSign(ethers.toBigInt(a) - ethers.toBigInt(b)); const hasDuplicates = array => array.some((v, i) => array.indexOf(v) != i); -describe('Arrays', function () { - const fixture = async () => { - return { mock: await ethers.deployContract('$Arrays') }; - }; +async function fixture() { + return { mock: await ethers.deployContract('$Arrays') }; +} +describe('Arrays', function () { beforeEach(async function () { Object.assign(this, await loadFixture(fixture)); }); diff --git a/test/utils/Base58.test.js b/test/utils/Base58.test.js index 87611ae3059..1c8dfb46808 100644 --- a/test/utils/Base58.test.js +++ b/test/utils/Base58.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$Base58'); - return { mock }; + return { mock: await ethers.deployContract('$Base58') }; } describe('Base58', function () { diff --git a/test/utils/Base64.test.js b/test/utils/Base64.test.js index c4b7a7b5303..bbd46505cb9 100644 --- a/test/utils/Base64.test.js +++ b/test/utils/Base64.test.js @@ -1,14 +1,17 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); // Replace "+/" with "-_" in the char table, and remove the padding // see https://datatracker.ietf.org/doc/html/rfc4648#section-5 const base64toBase64Url = str => str.replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', ''); async function fixture() { - const mock = await ethers.deployContract('$Base64'); - return { mock }; + return { mock: await ethers.deployContract('$Base64') }; } describe('Base64', function () { diff --git a/test/utils/Blockhash.t.sol b/test/utils/Blockhash.t.sol index e585ccba8b1..bd36aa6e47c 100644 --- a/test/utils/Blockhash.t.sol +++ b/test/utils/Blockhash.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.24; import {Test} from "forge-std/Test.sol"; -import {Blockhash} from "../../contracts/utils/Blockhash.sol"; +import {Blockhash} from "@openzeppelin/contracts/utils/Blockhash.sol"; contract BlockhashTest is Test { uint256 internal startingBlock; diff --git a/test/utils/Blockhash.test.js b/test/utils/Blockhash.test.js index 7ec92262184..7e0c2300725 100644 --- a/test/utils/Blockhash.test.js +++ b/test/utils/Blockhash.test.js @@ -1,7 +1,11 @@ -const { ethers, predeploy } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, mineUpTo, setCode } = require('@nomicfoundation/hardhat-network-helpers'); -const { impersonate } = require('../helpers/account'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + helpers: { impersonate, time }, + networkHelpers: { loadFixture, setCode }, +} = await network.create(); const SYSTEM_ADDRESS = '0xfffffffffffffffffffffffffffffffffffffffe'; const HISTORY_SERVE_WINDOW = 8191; @@ -24,21 +28,21 @@ describe('Blockhash', function () { describe(`${supported ? 'supported' : 'unsupported'} chain`, function () { beforeEach(async function () { if (supported) { - await this.systemSigner.sendTransaction({ to: predeploy.eip2935, data: this.latestBlock.hash }); + await this.systemSigner.sendTransaction({ to: ethers.predeploy.eip2935, data: this.latestBlock.hash }); } else { - await setCode(predeploy.eip2935.target, '0x'); + await setCode(ethers.predeploy.eip2935.target, '0x'); } }); it('recent block', async function () { // fast forward (less than blockhash serve window) - await mineUpTo(this.latestBlock.number + BLOCKHASH_SERVE_WINDOW); + await time.increaseTo.blockNumber(this.latestBlock.number + BLOCKHASH_SERVE_WINDOW); await expect(this.mock.$blockHash(this.latestBlock.number)).to.eventually.equal(this.latestBlock.hash); }); it('old block', async function () { // fast forward (more than blockhash serve window) - await mineUpTo(this.latestBlock.number + BLOCKHASH_SERVE_WINDOW + 1); + await time.increaseTo.blockNumber(this.latestBlock.number + BLOCKHASH_SERVE_WINDOW + 1); await expect(this.mock.$blockHash(this.latestBlock.number)).to.eventually.equal( supported ? this.latestBlock.hash : ethers.ZeroHash, ); @@ -46,7 +50,7 @@ describe('Blockhash', function () { it('very old block', async function () { // fast forward (more than history serve window) - await mineUpTo(this.latestBlock.number + HISTORY_SERVE_WINDOW + 10); + await time.increaseTo.blockNumber(this.latestBlock.number + HISTORY_SERVE_WINDOW + 10); await expect(this.mock.$blockHash(this.latestBlock.number)).to.eventually.equal(ethers.ZeroHash); }); diff --git a/test/utils/Bytes.test.js b/test/utils/Bytes.test.js index 9366c5d269f..e90f9dbcb4f 100644 --- a/test/utils/Bytes.test.js +++ b/test/utils/Bytes.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { MAX_UINT128, MAX_UINT64, MAX_UINT32, MAX_UINT16 } = require('../helpers/constants'); -const { generators } = require('../helpers/random'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT128, MAX_UINT64, MAX_UINT32, MAX_UINT16 } from '../helpers/constants'; +import { generators } from '../helpers/random'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); // Helper functions for fixed bytes types const bytes32 = value => ethers.toBeHex(value, 32); @@ -12,8 +16,7 @@ const bytes4 = value => ethers.toBeHex(value, 4); const bytes2 = value => ethers.toBeHex(value, 2); async function fixture() { - const mock = await ethers.deployContract('$Bytes'); - return { mock }; + return { mock: await ethers.deployContract('$Bytes') }; } const lorem = ethers.toUtf8Bytes( diff --git a/test/utils/CAIP.test.js b/test/utils/CAIP.test.js index bb0bae023c4..87e66247623 100644 --- a/test/utils/CAIP.test.js +++ b/test/utils/CAIP.test.js @@ -1,55 +1,57 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { CHAINS } from '../helpers/chains'; +import { generators } from '../helpers/random'; -const { CHAINS, getLocalChain } = require('../helpers/chains'); +const { + ethers, + helpers: { chain }, +} = await network.create(); describe('CAIP utilities', function () { - before(async function () { - this.local = await getLocalChain(); - }); - describe('CAIP-2', function () { before(async function () { this.mock = await ethers.deployContract('$CAIP2'); }); it('local()', async function () { - const { caip2 } = this.local; - expect(await this.mock.$local()).to.equal(caip2); + await expect(this.mock.$local()).to.eventually.equal(chain.caip2); }); for (const { namespace, reference, caip2 } of Object.values(CHAINS)) { it(`format(${namespace}, ${reference})`, async function () { - expect(await this.mock.$format(namespace, reference)).to.equal(caip2); + await expect(this.mock.$format(namespace, reference)).to.eventually.equal(caip2); }); it(`parse(${caip2})`, async function () { - expect(await this.mock.$parse(caip2)).to.deep.equal([namespace, reference]); + await expect(this.mock.$parse(caip2)).to.eventually.deep.equal([namespace, reference]); }); } }); describe('CAIP-10', function () { - const { address: account } = ethers.Wallet.createRandom(); + const account = generators.address(); before(async function () { this.mock = await ethers.deployContract('$CAIP10'); }); it(`local(${account})`, async function () { - const caip10 = this.local.toCaip10(account); - expect(await this.mock.$local(ethers.Typed.address(account))).to.equal(caip10); + const caip10 = chain.toCaip10(account); + await expect(this.mock.$local(ethers.Typed.address(account))).to.eventually.equal(caip10); }); for (const { caip2, toCaip10 } of Object.values(CHAINS)) { const caip10 = toCaip10(account); it(`format(${caip2}, ${account})`, async function () { - expect(await this.mock.$format(ethers.Typed.string(caip2), ethers.Typed.string(account))).to.equal(caip10); + await expect(this.mock.$format(ethers.Typed.string(caip2), ethers.Typed.string(account))).to.eventually.equal( + caip10, + ); }); it(`parse(${caip10})`, async function () { - expect(await this.mock.$parse(caip10)).to.deep.equal([caip2, account]); + await expect(this.mock.$parse(caip10)).to.eventually.deep.equal([caip2, account]); }); } }); diff --git a/test/utils/Calldata.test.js b/test/utils/Calldata.test.js index 7e9d3d47813..8351af59ff0 100644 --- a/test/utils/Calldata.test.js +++ b/test/utils/Calldata.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$Calldata'); - return { mock }; + return { mock: await ethers.deployContract('$Calldata') }; } describe('Calldata utilities', function () { diff --git a/test/utils/Context.behavior.js b/test/utils/Context.behavior.js index adb140fc150..8c271ac3590 100644 --- a/test/utils/Context.behavior.js +++ b/test/utils/Context.behavior.js @@ -1,15 +1,6 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -async function fixture() { - return { contextHelper: await ethers.deployContract('ContextMockCaller', []) }; -} -function shouldBehaveLikeRegularContext() { - beforeEach(async function () { - Object.assign(this, await loadFixture(fixture)); - }); +import { expect } from 'chai'; +export async function shouldBehaveLikeRegularContext() { describe('msgSender', function () { it('returns the transaction sender when called from an EOA', async function () { await expect(this.context.connect(this.sender).msgSender()).to.emit(this.context, 'Sender').withArgs(this.sender); @@ -42,7 +33,3 @@ function shouldBehaveLikeRegularContext() { }); }); } - -module.exports = { - shouldBehaveLikeRegularContext, -}; diff --git a/test/utils/Context.test.js b/test/utils/Context.test.js index b766729e2f6..4305d768a72 100644 --- a/test/utils/Context.test.js +++ b/test/utils/Context.test.js @@ -1,12 +1,16 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { shouldBehaveLikeRegularContext } from './Context.behavior'; -const { shouldBehaveLikeRegularContext } = require('./Context.behavior'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [sender] = await ethers.getSigners(); const context = await ethers.deployContract('ContextMock', []); - return { sender, context }; + const contextHelper = await ethers.deployContract('ContextMockCaller', []); + return { sender, context, contextHelper }; } describe('Context', function () { diff --git a/test/utils/Create2.test.js b/test/utils/Create2.test.js index 99c47a0e34a..f5ed30bb400 100644 --- a/test/utils/Create2.test.js +++ b/test/utils/Create2.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { RevertType } = require('../helpers/enums'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { RevertType } from '../helpers/enums'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [deployer, other] = await ethers.getSigners(); diff --git a/test/utils/Create3.test.js b/test/utils/Create3.test.js index ea624251032..0f4d0df1025 100644 --- a/test/utils/Create3.test.js +++ b/test/utils/Create3.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture, takeSnapshot } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { RevertType } = require('../helpers/enums'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { RevertType } from '../helpers/enums'; + +const { + ethers, + networkHelpers: { loadFixture, takeSnapshot }, +} = await network.create(); const PROXY_INITCODE_HASH = '0xd61bbde0460e6c48ddd99fb8b7e1ad36529d2ec79cbac1db0300b3d26ddcdc2a'; const getCreate3Address = (deployer, salt) => diff --git a/test/utils/ERC6372Utils.test.js b/test/utils/ERC6372Utils.test.js index db9fc3e3fbd..de4d4058763 100644 --- a/test/utils/ERC6372Utils.test.js +++ b/test/utils/ERC6372Utils.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; -const time = require('../helpers/time'); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = await network.create(); const CLOCK_MODE = { timestamp: 'mode=timestamp', @@ -11,6 +14,7 @@ const CLOCK_MODE = { async function fixture() { const mock = await ethers.deployContract('$ERC6372Utils'); + const instances = { blockNumber: await ethers.deployContract('$ERC20Votes', ['My Token', 'MTKN', 'My Token', '1']), timestamp: await ethers.deployContract('$ERC20VotesTimestampMock', ['My Token', 'MTKN', 'My Token', '1']), diff --git a/test/utils/LowLevelCall.test.js b/test/utils/LowLevelCall.test.js index c0f06a45e1d..2f13db9ef2c 100644 --- a/test/utils/LowLevelCall.test.js +++ b/test/utils/LowLevelCall.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const value = ethers.parseEther('1'); const returnValue1 = ethers.id('hello'); @@ -39,7 +43,7 @@ describe('LowLevelCall', function () { ethers.Typed.uint256(value), this.target.interface.encodeFunctionData('mockFunction'), ); - await expect(tx).to.changeEtherBalances([this.mock, this.target], [-value, value]); + await expect(tx).to.changeEtherBalances(ethers, [this.mock, this.target], [-value, value]); await expect(tx).to.emit(this.mock, 'return$callNoReturn_address_uint256_bytes').withArgs(true); }); @@ -49,7 +53,7 @@ describe('LowLevelCall', function () { ethers.Typed.uint256(value), this.target.interface.encodeFunctionData('mockFunction'), ); - await expect(tx).to.changeEtherBalances([this.mock, this.target], [0n, 0n]); + await expect(tx).to.changeEtherBalances(ethers, [this.mock, this.target], [0n, 0n]); await expect(tx).to.emit(this.mock, 'return$callNoReturn_address_uint256_bytes').withArgs(false); }); @@ -84,7 +88,7 @@ describe('LowLevelCall', function () { ethers.Typed.uint256(value), this.target.interface.encodeFunctionData('mockFunctionWithArgsReturn', [returnValue1, returnValue2]), ); - await expect(tx).to.changeEtherBalances([this.mock, this.target], [-value, value]); + await expect(tx).to.changeEtherBalances(ethers, [this.mock, this.target], [-value, value]); await expect(tx) .to.emit(this.mock, 'return$callReturn64Bytes_address_uint256_bytes') .withArgs(true, returnValue1, returnValue2); @@ -96,7 +100,7 @@ describe('LowLevelCall', function () { ethers.Typed.uint256(value), this.target.interface.encodeFunctionData('mockFunctionWithArgsReturn', [returnValue1, returnValue2]), ); - await expect(tx).to.changeEtherBalances([this.mock, this.target], [0n, 0n]); + await expect(tx).to.changeEtherBalances(ethers, [this.mock, this.target], [0n, 0n]); await expect(tx) .to.emit(this.mock, 'return$callReturn64Bytes_address_uint256_bytes') .withArgs(false, ethers.ZeroHash, ethers.ZeroHash); diff --git a/test/utils/Memory.test.js b/test/utils/Memory.test.js index 5ca028466dc..714aef9d453 100644 --- a/test/utils/Memory.test.js +++ b/test/utils/Memory.test.js @@ -1,16 +1,18 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { generators } from '../helpers/random'; -const { generators } = require('../helpers/random'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const formatSlice = ({ length, ptr = 0xa0 }) => ethers.toBeHex((ethers.toBigInt(length) << 128n) | ethers.toBigInt(ptr), 32); async function fixture() { - const mock = await ethers.deployContract('$Memory'); - return { mock }; + return { mock: await ethers.deployContract('$Memory') }; } describe('Memory', function () { @@ -22,7 +24,7 @@ describe('Memory', function () { describe('free pointer', function () { it('sets free memory pointer', async function () { const ptr = ethers.toBeHex(0xa0, 32); - await expect(this.mock.$unsafeSetFreeMemoryPointer(ptr)).to.not.be.reverted; + await expect(this.mock.$unsafeSetFreeMemoryPointer(ptr)).to.not.be.revert(ethers); }); it('gets free memory pointer', async function () { diff --git a/test/utils/Multicall.test.js b/test/utils/Multicall.test.js index 9c84e443a4e..ec6837d9257 100644 --- a/test/utils/Multicall.test.js +++ b/test/utils/Multicall.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [holder, alice, bruce] = await ethers.getSigners(); diff --git a/test/utils/Nonces.behavior.js b/test/utils/Nonces.behavior.js index c62864ea2bc..3237b05b886 100644 --- a/test/utils/Nonces.behavior.js +++ b/test/utils/Nonces.behavior.js @@ -1,7 +1,7 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; -function shouldBehaveLikeNonces() { +export function shouldBehaveLikeNonces() { describe('should behave like Nonces', function () { const sender = ethers.Wallet.createRandom(); const other = ethers.Wallet.createRandom(); @@ -66,7 +66,7 @@ function shouldBehaveLikeNonces() { }); } -function shouldBehaveLikeNoncesKeyed() { +export function shouldBehaveLikeNoncesKeyed() { describe('should support nonces with keys', function () { const sender = ethers.Wallet.createRandom(); @@ -182,8 +182,3 @@ function shouldBehaveLikeNoncesKeyed() { }); }); } - -module.exports = { - shouldBehaveLikeNonces, - shouldBehaveLikeNoncesKeyed, -}; diff --git a/test/utils/Nonces.test.js b/test/utils/Nonces.test.js index 85aa7358a00..f02220d90bf 100644 --- a/test/utils/Nonces.test.js +++ b/test/utils/Nonces.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { shouldBehaveLikeNonces } = require('./Nonces.behavior'); +import { network } from 'hardhat'; +import { shouldBehaveLikeNonces } from './Nonces.behavior'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$Nonces'); - return { mock }; + return { mock: await ethers.deployContract('$Nonces') }; } describe('Nonces', function () { diff --git a/test/utils/NoncesKeyed.test.js b/test/utils/NoncesKeyed.test.js index c46948ee402..9d040242d56 100644 --- a/test/utils/NoncesKeyed.test.js +++ b/test/utils/NoncesKeyed.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { shouldBehaveLikeNonces, shouldBehaveLikeNoncesKeyed } = require('./Nonces.behavior'); +import { network } from 'hardhat'; +import { shouldBehaveLikeNonces, shouldBehaveLikeNoncesKeyed } from './Nonces.behavior'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$NoncesKeyed'); - return { mock }; + return { mock: await ethers.deployContract('$NoncesKeyed') }; } describe('NoncesKeyed', function () { diff --git a/test/utils/Packing.test.js b/test/utils/Packing.test.js index dd36f45d774..0226c65a12a 100644 --- a/test/utils/Packing.test.js +++ b/test/utils/Packing.test.js @@ -1,13 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { product } from '../helpers/iterate'; +import { SIZES } from '../../scripts/generate/templates/Packing.opts'; -const { forceDeployCode } = require('../helpers/deploy'); -const { product } = require('../helpers/iterate'); -const { SIZES } = require('../../scripts/generate/templates/Packing.opts'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - return { mock: await forceDeployCode('$Packing') }; + return { mock: await ethers.deployContract('$Packing') }; } describe('Packing', function () { diff --git a/test/utils/Panic.test.js b/test/utils/Panic.test.js index 49673c751cc..32093bf6a47 100644 --- a/test/utils/Panic.test.js +++ b/test/utils/Panic.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { return { mock: await ethers.deployContract('$Panic') }; diff --git a/test/utils/Pausable.test.js b/test/utils/Pausable.test.js index 67d74a0d88c..d092850e7c8 100644 --- a/test/utils/Pausable.test.js +++ b/test/utils/Pausable.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [pauser] = await ethers.getSigners(); diff --git a/test/utils/RLP.test.js b/test/utils/RLP.test.js index f0172eab05d..c7129181a0f 100644 --- a/test/utils/RLP.test.js +++ b/test/utils/RLP.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { MAX_UINT64 } = require('../helpers/constants'); -const { product } = require('../helpers/iterate'); -const { generators } = require('../helpers/random'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MAX_UINT64 } from '../helpers/constants'; +import { product } from '../helpers/iterate'; +import { generators } from '../helpers/random'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const mock = await ethers.deployContract('$RLP'); diff --git a/test/utils/ReentrancyGuard.test.js b/test/utils/ReentrancyGuard.test.js index 4a157864998..0d9c0bbac1f 100644 --- a/test/utils/ReentrancyGuard.test.js +++ b/test/utils/ReentrancyGuard.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); for (const variant of ['', 'Transient']) { describe(`Reentrancy${variant}Guard`, function () { diff --git a/test/utils/RelayedCall.test.js b/test/utils/RelayedCall.test.js index 685d090e913..9ef6ee2e46f 100644 --- a/test/utils/RelayedCall.test.js +++ b/test/utils/RelayedCall.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { impersonate } = require('../helpers/account'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + helpers: { impersonate }, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [admin, receiver, other] = await ethers.getSigners(); @@ -74,7 +78,7 @@ describe('RelayedCall', function () { ethers.Typed.bytes('0x'), ); - await expect(tx).to.changeEtherBalances([this.mock, this.relayer, this.receiver], [-value, 0n, value]); + await expect(tx).to.changeEtherBalances(ethers, [this.mock, this.relayer, this.receiver], [-value, 0n, value]); await expect(tx).to.emit(this.mock, 'return$relayCall_address_uint256_bytes').withArgs(true, '0x'); }); @@ -97,7 +101,7 @@ describe('RelayedCall', function () { // unauthorized caller await expect( this.other.sendTransaction({ to: this.relayer, data: '0x7859821024E633C5dC8a4FcF86fC52e7720Ce525' }), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); }); it('relayer input format', async function () { @@ -110,15 +114,15 @@ describe('RelayedCall', function () { // 20 bytes (address + empty data) - OK await expect( mockAsWallet.sendTransaction({ to: this.relayer, data: '0x7859821024E633C5dC8a4FcF86fC52e7720Ce525' }), - ).to.not.be.reverted; + ).to.not.be.revert(ethers); // 19 bytes (not enough for an address) - REVERT await expect( mockAsWallet.sendTransaction({ to: this.relayer, data: '0x7859821024E633C5dC8a4FcF86fC52e7720Ce5' }), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); // 0 bytes (not enough for an address) - REVERT - await expect(mockAsWallet.sendTransaction({ to: this.relayer, data: '0x' })).to.be.revertedWithoutReason(); + await expect(mockAsWallet.sendTransaction({ to: this.relayer, data: '0x' })).to.be.revertedWithoutReason(ethers); }); }); @@ -172,7 +176,7 @@ describe('RelayedCall', function () { ethers.Typed.bytes32(this.salt), ); - await expect(tx).to.changeEtherBalances([this.mock, this.relayer, this.receiver], [-value, 0n, value]); + await expect(tx).to.changeEtherBalances(ethers, [this.mock, this.relayer, this.receiver], [-value, 0n, value]); await expect(tx).to.emit(this.mock, 'return$relayCall_address_uint256_bytes_bytes32').withArgs(true, '0x'); }); @@ -196,7 +200,7 @@ describe('RelayedCall', function () { // unauthorized caller await expect( this.other.sendTransaction({ to: this.relayer, data: '0x7859821024E633C5dC8a4FcF86fC52e7720Ce525' }), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); }); it('input format', async function () { @@ -209,15 +213,15 @@ describe('RelayedCall', function () { // 20 bytes (address + empty data) - OK await expect( mockAsWallet.sendTransaction({ to: this.relayer, data: '0x7859821024E633C5dC8a4FcF86fC52e7720Ce525' }), - ).to.not.be.reverted; + ).to.not.be.revert(ethers); // 19 bytes (not enough for an address) - REVERT await expect( mockAsWallet.sendTransaction({ to: this.relayer, data: '0x7859821024E633C5dC8a4FcF86fC52e7720Ce5' }), - ).to.be.revertedWithoutReason(); + ).to.be.revertedWithoutReason(ethers); // 0 bytes (not enough for an address) - REVERT - await expect(mockAsWallet.sendTransaction({ to: this.relayer, data: '0x' })).to.be.revertedWithoutReason(); + await expect(mockAsWallet.sendTransaction({ to: this.relayer, data: '0x' })).to.be.revertedWithoutReason(ethers); }); }); }); diff --git a/test/utils/ShortStrings.test.js b/test/utils/ShortStrings.test.js index cb1a06aa5c7..2438fc5914b 100644 --- a/test/utils/ShortStrings.test.js +++ b/test/utils/ShortStrings.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const FALLBACK_SENTINEL = ethers.zeroPadValue('0xFF', 32); diff --git a/test/utils/SimulatedCall.test.js b/test/utils/SimulatedCall.test.js index ab2e875543e..a2e89e93ad9 100644 --- a/test/utils/SimulatedCall.test.js +++ b/test/utils/SimulatedCall.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const value = 42n; @@ -51,7 +55,7 @@ describe('SimulateCall', function () { ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionWithArgsReturn', [10, 20])), ); - await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]); + await expect(txPromise).to.changeEtherBalances(ethers, [this.mock, this.simulator, this.target], [0n, 0n, 0n]); await expect(txPromise) .to.emit(this.mock, 'return$simulateCall_address_bytes') .withArgs(true, ethers.AbiCoder.defaultAbiCoder().encode(['uint256', 'uint256'], [10, 20])) @@ -66,7 +70,7 @@ describe('SimulateCall', function () { ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionExtra')), ); - await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]); + await expect(txPromise).to.changeEtherBalances(ethers, [this.mock, this.simulator, this.target], [0n, 0n, 0n]); await expect(txPromise) .to.emit(this.mock, 'return$simulateCall_address_uint256_bytes') .withArgs(true, ethers.AbiCoder.defaultAbiCoder().encode(['address', 'uint256'], [this.mock.target, value])) @@ -79,7 +83,7 @@ describe('SimulateCall', function () { ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionRevertsReason')), ); - await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]); + await expect(txPromise).to.changeEtherBalances(ethers, [this.mock, this.simulator, this.target], [0n, 0n, 0n]); await expect(txPromise) .to.emit(this.mock, 'return$simulateCall_address_bytes') .withArgs(false, this.target.interface.encodeErrorResult('Error', ['CallReceiverMock: reverting'])); @@ -92,7 +96,7 @@ describe('SimulateCall', function () { ethers.Typed.bytes(this.target.interface.encodeFunctionData('mockFunctionRevertsReason')), ); - await expect(txPromise).to.changeEtherBalances([this.mock, this.simulator, this.target], [0n, 0n, 0n]); + await expect(txPromise).to.changeEtherBalances(ethers, [this.mock, this.simulator, this.target], [0n, 0n, 0n]); await expect(txPromise) .to.emit(this.mock, 'return$simulateCall_address_uint256_bytes') .withArgs(false, this.target.interface.encodeErrorResult('Error', ['CallReceiverMock: reverting'])); diff --git a/test/utils/SlotDerivation.test.js b/test/utils/SlotDerivation.test.js index 22582b37572..5529387d882 100644 --- a/test/utils/SlotDerivation.test.js +++ b/test/utils/SlotDerivation.test.js @@ -1,8 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { erc7201Slot } = require('../helpers/storage'); -const { generators } = require('../helpers/random'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { erc7201Slot } from '../helpers/storage'; +import { generators } from '../helpers/random'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const [account] = await ethers.getSigners(); diff --git a/test/utils/StorageSlot.test.js b/test/utils/StorageSlot.test.js index ddcf305d1a7..8da0cdb6fdb 100644 --- a/test/utils/StorageSlot.test.js +++ b/test/utils/StorageSlot.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { generators } = require('../helpers/random'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { generators } from '../helpers/random'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const slot = ethers.id('some.storage.slot'); const otherSlot = ethers.id('some.other.storage.slot'); diff --git a/test/utils/Strings.test.js b/test/utils/Strings.test.js index c3b60ffa41f..68a1d418ba7 100644 --- a/test/utils/Strings.test.js +++ b/test/utils/Strings.test.js @@ -1,11 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$Strings'); - return { mock }; + return { mock: await ethers.deployContract('$Strings') }; } describe('Strings', function () { diff --git a/test/utils/TransientSlot.test.js b/test/utils/TransientSlot.test.js index 7b70be375d4..0271d79de9e 100644 --- a/test/utils/TransientSlot.test.js +++ b/test/utils/TransientSlot.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { generators } = require('../helpers/random'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { generators } from '../helpers/random'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const slot = ethers.id('some.storage.slot'); const otherSlot = ethers.id('some.other.storage.slot'); diff --git a/test/utils/cryptography/ECDSA.test.js b/test/utils/cryptography/ECDSA.test.js index f910f9d4c13..644dbbc4455 100644 --- a/test/utils/cryptography/ECDSA.test.js +++ b/test/utils/cryptography/ECDSA.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { secp256k1 } = require('@noble/curves/secp256k1.js'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { secp256k1 } from '@noble/curves/secp256k1.js'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const TEST_MESSAGE = ethers.id('OpenZeppelin'); const WRONG_MESSAGE = ethers.id('Nope'); diff --git a/test/utils/cryptography/EIP712.test.js b/test/utils/cryptography/EIP712.test.js index 2b6e7fa9787..507cebcdd86 100644 --- a/test/utils/cryptography/EIP712.test.js +++ b/test/utils/cryptography/EIP712.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { getDomain, domainSeparator, hashTypedData } from '../../helpers/eip712'; +import { formatType } from '../../helpers/eip712-types'; -const { getDomain, domainSeparator, hashTypedData } = require('../../helpers/eip712'); -const { formatType } = require('../../helpers/eip712-types'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const LENGTHS = { short: ['A Name', '1'], @@ -90,7 +93,9 @@ describe('EIP712', function () { const signature = await this.from.signTypedData(this.domain, types, message); - await expect(this.eip712.verify(signature, this.from.address, message.to, message.contents)).to.not.be.reverted; + await expect(this.eip712.verify(signature, this.from.address, message.to, message.contents)).to.not.be.revert( + ethers, + ); }); it('name', async function () { diff --git a/test/utils/cryptography/ERC1271.behavior.js b/test/utils/cryptography/ERC1271.behavior.js index ef3e668028e..e2231de97d0 100644 --- a/test/utils/cryptography/ERC1271.behavior.js +++ b/test/utils/cryptography/ERC1271.behavior.js @@ -1,16 +1,16 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { Permit, formatType, getDomain } = require('../../helpers/eip712'); -const { ERC7739Signer } = require('../../helpers/erc7739'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { Permit, formatType, getDomain } from '../../helpers/eip712'; +import { ERC7739Signer } from '../../helpers/erc7739'; -function shouldBehaveLikeERC1271({ erc7739 = false } = {}) { +export function shouldBehaveLikeERC1271({ erc7739 = false } = {}) { const MAGIC_VALUE = '0x1626ba7e'; describe(`supports ERC-${erc7739 ? 7739 : 1271}`, function () { beforeEach(async function () { // if deploy function is present, check that code is already in place if (this.mock.deploy) { - await ethers.provider.getCode(this.mock.address).then(code => code != '0x' || this.mock.deploy()); + await this.mock.runner.provider.getCode(this.mock.address).then(code => code != '0x' || this.mock.deploy()); } this._signer = erc7739 ? new ERC7739Signer(this.signer, this.domain ?? (await getDomain(this.mock))) @@ -45,7 +45,7 @@ function shouldBehaveLikeERC1271({ erc7739 = false } = {}) { this.appDomain = { name: 'SomeApp', version: '1', - chainId: await ethers.provider.getNetwork().then(({ chainId }) => chainId), + chainId: await this.mock.runner.provider.getNetwork().then(({ chainId }) => chainId), verifyingContract: '0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512', salt: '0x02cb3d8cb5e8928c9c6de41e935e16a4e28b2d54e7e7ba47e99f16071efab785', }; @@ -105,7 +105,3 @@ function shouldBehaveLikeERC1271({ erc7739 = false } = {}) { }); }); } - -module.exports = { - shouldBehaveLikeERC1271, -}; diff --git a/test/utils/cryptography/ERC7739.test.js b/test/utils/cryptography/ERC7739.test.js index 8dc6a2b42b8..1e59b906246 100644 --- a/test/utils/cryptography/ERC7739.test.js +++ b/test/utils/cryptography/ERC7739.test.js @@ -1,6 +1,8 @@ -const { ethers } = require('hardhat'); -const { shouldBehaveLikeERC1271 } = require('./ERC1271.behavior'); -const { NonNativeSigner, P256SigningKey, RSASHA256SigningKey } = require('../../helpers/signers'); +import { network } from 'hardhat'; +import { shouldBehaveLikeERC1271 } from './ERC1271.behavior'; +import { NonNativeSigner, P256SigningKey, RSASHA256SigningKey } from '../../helpers/signers'; + +const { ethers } = await network.create(); describe('ERC7739', function () { describe('for an ECDSA signer', function () { diff --git a/test/utils/cryptography/ERC7739Utils.test.js b/test/utils/cryptography/ERC7739Utils.test.js index 93e382df611..b4c1337b800 100644 --- a/test/utils/cryptography/ERC7739Utils.test.js +++ b/test/utils/cryptography/ERC7739Utils.test.js @@ -1,9 +1,12 @@ -const { expect } = require('chai'); -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const { Permit } = require('../../helpers/eip712'); -const { ERC4337Utils, PersonalSign } = require('../../helpers/erc7739'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { Permit } from '../../helpers/eip712'; +import { ERC4337Utils, PersonalSign } from '../../helpers/erc7739'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const details = ERC4337Utils.getContentsDetail({ Permit }); diff --git a/test/utils/cryptography/MerkleProof.test.js b/test/utils/cryptography/MerkleProof.test.js index fd480dd9374..93fc07c913f 100644 --- a/test/utils/cryptography/MerkleProof.test.js +++ b/test/utils/cryptography/MerkleProof.test.js @@ -1,7 +1,9 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); -const { SimpleMerkleTree } = require('@openzeppelin/merkle-tree'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { SimpleMerkleTree } from '@openzeppelin/merkle-tree'; + +const { ethers } = await network.create(); // generate bytes32 leaves from a string const toLeaves = (str, separator = '') => str.split(separator).map(e => ethers.keccak256(ethers.toUtf8Bytes(e))); diff --git a/test/utils/cryptography/MessageHashUtils.test.js b/test/utils/cryptography/MessageHashUtils.test.js index 7f18b51c929..e5a06fe0b1e 100644 --- a/test/utils/cryptography/MessageHashUtils.test.js +++ b/test/utils/cryptography/MessageHashUtils.test.js @@ -1,13 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { domainType, domainSeparator, hashTypedData } from '../../helpers/eip712'; +import { generators } from '../../helpers/random'; -const { domainType, domainSeparator, hashTypedData } = require('../../helpers/eip712'); -const { generators } = require('../../helpers/random'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$MessageHashUtils'); - return { mock }; + return { mock: await ethers.deployContract('$MessageHashUtils') }; } describe('MessageHashUtils', function () { diff --git a/test/utils/cryptography/P256.test.js b/test/utils/cryptography/P256.test.js index d255427640b..573489284ae 100644 --- a/test/utils/cryptography/P256.test.js +++ b/test/utils/cryptography/P256.test.js @@ -1,7 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { p256 } = require('@noble/curves/nist.js'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import fs from 'fs'; +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { p256 } from '@noble/curves/nist.js'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const N = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551n; @@ -21,11 +26,11 @@ const prepareSignature = ( return { privateKey, publicKey, signature, recovery, messageHash }; }; -describe('P256', function () { - async function fixture() { - return { mock: await ethers.deployContract('$P256') }; - } +async function fixture() { + return { mock: await ethers.deployContract('$P256') }; +} +describe('P256', function () { beforeEach(async function () { Object.assign(this, await loadFixture(fixture)); }); @@ -140,7 +145,11 @@ describe('P256', function () { // test cases for https://github.com/C2SP/wycheproof/blob/4672ff74d68766e7785c2cac4c597effccef2c5c/testvectors/ecdsa_secp256r1_sha256_p1363_test.json describe('wycheproof tests', function () { - for (const { key, tests } of require('./ecdsa_secp256r1_sha256_p1363_test.json').testGroups) { + const { testGroups } = JSON.parse( + fs.readFileSync('./test/utils/cryptography/ecdsa_secp256r1_sha256_p1363_test.json', 'utf8'), + ); + + for (const { key, tests } of testGroups) { // parse public key let [x, y] = [key.wx, key.wy].map(v => ethers.stripZerosLeft('0x' + v, 32)); if (x.length > 66 || y.length > 66) continue; diff --git a/test/utils/cryptography/RSA.helper.js b/test/utils/cryptography/RSA.helper.js index 48c8ee43cb2..cf14c1568d0 100644 --- a/test/utils/cryptography/RSA.helper.js +++ b/test/utils/cryptography/RSA.helper.js @@ -1,9 +1,8 @@ -const path = require('path'); -const fs = require('fs'); +import fs from 'fs'; -module.exports = function* parse(file) { +export function* parse(file) { const cache = {}; - const data = fs.readFileSync(path.resolve(__dirname, file), 'utf8'); + const data = fs.readFileSync(file, 'utf8'); for (const line of data.split('\r\n')) { const groups = line.match(/^(?\w+) = (?\w+)(?.*)$/)?.groups; if (groups) { @@ -14,4 +13,4 @@ module.exports = function* parse(file) { } } } -}; +} diff --git a/test/utils/cryptography/RSA.test.js b/test/utils/cryptography/RSA.test.js index 7ddf4d3a238..0e61b3adaed 100644 --- a/test/utils/cryptography/RSA.test.js +++ b/test/utils/cryptography/RSA.test.js @@ -1,9 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { bytes, bytes32 } = ethers.Typed; +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { parse } from './RSA.helper'; -const parse = require('./RSA.helper'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { return { mock: await ethers.deployContract('$RSA') }; @@ -17,7 +19,7 @@ describe('RSA', function () { // Load test cases from file SigVer15_186-3.rsp from: // https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/dss/186-2rsatestvectors.zip describe('SigVer15_186-3.rsp tests', function () { - for (const test of parse('SigVer15_186-3.rsp')) { + for (const test of parse('./test/utils/cryptography/SigVer15_186-3.rsp')) { const { length } = Buffer.from(test.S, 'hex'); /// For now, RSA only supports digest that are 32bytes long. If we ever extend that, we can use these hashing functions for @noble: @@ -34,8 +36,10 @@ describe('RSA', function () { const exp = ethers.stripZerosLeft('0x' + test.e); // strip zeros to reduce gas cost of the precompile const mod = '0x' + test.n; - expect(await this.mock.$pkcs1Sha256(bytes32(ethers.sha256(data)), sig, exp, mod)).to.equal(result); - expect(await this.mock.$pkcs1Sha256(bytes(data), sig, exp, mod)).to.equal(result); + expect(await this.mock.$pkcs1Sha256(ethers.Typed.bytes32(ethers.sha256(data)), sig, exp, mod)).to.equal( + result, + ); + expect(await this.mock.$pkcs1Sha256(ethers.Typed.bytes(data), sig, exp, mod)).to.equal(result); }); } } @@ -95,7 +99,7 @@ describe('RSA', function () { for (const { descr, data, sig, exp, mod, result } of [openssl, rfc4055, shortN, differentLength, sTooLarge]) { it(descr, async function () { - expect(await this.mock.$pkcs1Sha256(bytes(data), sig, exp, mod)).to.equal(result); + expect(await this.mock.$pkcs1Sha256(ethers.Typed.bytes(data), sig, exp, mod)).to.equal(result); }); } }); diff --git a/test/utils/cryptography/SignatureChecker.test.js b/test/utils/cryptography/SignatureChecker.test.js index 99b4f694adc..76b6c5f0382 100644 --- a/test/utils/cryptography/SignatureChecker.test.js +++ b/test/utils/cryptography/SignatureChecker.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); - -const precompile = require('../../helpers/precompiles'); -const { P256SigningKey, NonNativeSigner } = require('../../helpers/signers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import * as precompile from '../../helpers/precompiles'; +import { P256SigningKey, NonNativeSigner } from '../../helpers/signers'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const TEST_MESSAGE = ethers.id('OpenZeppelin'); const TEST_MESSAGE_HASH = ethers.hashMessage(TEST_MESSAGE); diff --git a/test/utils/cryptography/TrieProof.test.js b/test/utils/cryptography/TrieProof.test.js index 69f37306d7f..5f7ed522293 100644 --- a/test/utils/cryptography/TrieProof.test.js +++ b/test/utils/cryptography/TrieProof.test.js @@ -1,13 +1,16 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { MerklePatriciaTrie, createMerkleProof } = require('@ethereumjs/mpt'); - -const { Enum } = require('../../helpers/enums'); -const { zip } = require('../../helpers/iterate'); -const { generators } = require('../../helpers/random'); -const { BlockTries } = require('../../helpers/trie'); -const { batchInBlock } = require('../../helpers/txpool'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { MerklePatriciaTrie, createMerkleProof } from '@ethereumjs/mpt'; +import { Enum } from '../../helpers/enums'; +import { zip } from '../../helpers/iterate'; +import { generators } from '../../helpers/random'; +import { BlockTries } from '../../helpers/trie'; +import { batchInBlock } from '../../helpers/txpool'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const ProofError = Enum( 'NO_ERROR', // No error occurred during proof traversal @@ -44,11 +47,14 @@ describe('TrieProof', function () { describe('verify', function () { it('verify transaction and receipt inclusion in block', async function () { // Multiple transactions/events in a block - const txs = await batchInBlock([ - () => this.target.mockFunction({ gasLimit: 100000 }), - () => this.target.mockFunctionWithArgs(0, 1, { gasLimit: 100000 }), - () => this.target.mockFunctionWithArgs(17, 42, { gasLimit: 100000 }), - ]); + const txs = await batchInBlock( + [ + () => this.target.mockFunction({ gasLimit: 100_000n }), + () => this.target.mockFunctionWithArgs(0, 1, { gasLimit: 100_000n }), + () => this.target.mockFunctionWithArgs(17, 42, { gasLimit: 100_000n }), + ], + ethers.provider, + ); // for some reason ethers doesn't expose the transactionsRoot in blocks, so we fetch the block details via RPC instead. const blockTries = await ethers.provider.getBlock('latest').then(block => BlockTries.from(block).ready()); diff --git a/test/utils/draft-InteroperableAddress.t.sol b/test/utils/draft-InteroperableAddress.t.sol index 8fdf400d14b..98de4b745f9 100644 --- a/test/utils/draft-InteroperableAddress.t.sol +++ b/test/utils/draft-InteroperableAddress.t.sol @@ -2,7 +2,7 @@ pragma solidity ^0.8.26; import {Test} from "forge-std/Test.sol"; -import {InteroperableAddress} from "../../contracts/utils/draft-InteroperableAddress.sol"; +import {InteroperableAddress} from "@openzeppelin/contracts/utils/draft-InteroperableAddress.sol"; contract InteroperableAddressTest is Test { using InteroperableAddress for bytes; diff --git a/test/utils/draft-InteroperableAddress.test.js b/test/utils/draft-InteroperableAddress.test.js index 2332427c5d2..f24a9ba2076 100644 --- a/test/utils/draft-InteroperableAddress.test.js +++ b/test/utils/draft-InteroperableAddress.test.js @@ -1,15 +1,17 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { addressCoder, nameCoder } = require('interoperable-addresses'); -const { CAIP350, chainTypeCoder } = require('interoperable-addresses/dist/CAIP350'); - -const { getLocalChain } = require('../helpers/chains'); -const { generators } = require('../helpers/random'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { addressCoder, nameCoder } from 'interoperable-addresses'; +import { CAIP350, chainTypeCoder } from 'interoperable-addresses/dist/CAIP350'; +import { generators } from '../helpers/random'; + +const { + ethers, + helpers: { chain }, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$InteroperableAddress'); - return { mock }; + return { mock: await ethers.deployContract('$InteroperableAddress') }; } describe('ERC7390', function () { @@ -18,10 +20,9 @@ describe('ERC7390', function () { }); it('formatEvmV1 address on the local chain', async function () { - const { reference: chainid, toErc7930 } = await getLocalChain(); await expect( - this.mock.$formatEvmV1(ethers.Typed.uint256(chainid), ethers.Typed.address(this.mock)), - ).to.eventually.equal(toErc7930(this.mock)); + this.mock.$formatEvmV1(ethers.Typed.uint256(chain.reference), ethers.Typed.address(this.mock)), + ).to.eventually.equal(chain.toErc7930(this.mock)); }); it('formatV1 fails if both reference and address are empty', async function () { diff --git a/test/utils/introspection/ERC165.test.js b/test/utils/introspection/ERC165.test.js index 8117c695ebd..97d7bfd389c 100644 --- a/test/utils/introspection/ERC165.test.js +++ b/test/utils/introspection/ERC165.test.js @@ -1,12 +1,13 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { shouldSupportInterfaces } from './SupportsInterface.behavior'; -const { shouldSupportInterfaces } = require('./SupportsInterface.behavior'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - return { - mock: await ethers.deployContract('$ERC165'), - }; + return { mock: await ethers.deployContract('$ERC165') }; } describe('ERC165', function () { diff --git a/test/utils/introspection/ERC165Checker.test.js b/test/utils/introspection/ERC165Checker.test.js index 7954b3d7621..8911f0258eb 100644 --- a/test/utils/introspection/ERC165Checker.test.js +++ b/test/utils/introspection/ERC165Checker.test.js @@ -1,6 +1,10 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const DUMMY_ID = '0xdeadbeef'; const DUMMY_ID_2 = '0xcafebabe'; diff --git a/test/utils/introspection/SupportsInterface.behavior.js b/test/utils/introspection/SupportsInterface.behavior.js index d40dc8b2e7b..866d0492c29 100644 --- a/test/utils/introspection/SupportsInterface.behavior.js +++ b/test/utils/introspection/SupportsInterface.behavior.js @@ -1,8 +1,7 @@ -const { expect } = require('chai'); -const { interfaceId } = require('../../helpers/methods'); -const { mapValues } = require('../../helpers/iterate'); +import { expect } from 'chai'; +import { interfaceId } from '../../helpers/methods'; +import { mapValues } from '../../helpers/iterate'; -const INVALID_ID = '0xffffffff'; const GOVERNOR_INTERFACE = [ 'name()', 'version()', @@ -31,7 +30,8 @@ const GOVERNOR_INTERFACE = [ 'castVoteBySig(uint256,uint8,address,bytes)', 'castVoteWithReasonAndParamsBySig(uint256,uint8,address,string,bytes,bytes)', ]; -const SIGNATURES = { + +export const SIGNATURES = { ERC165: ['supportsInterface(bytes4)'], ERC721: [ 'balanceOf(address)', @@ -104,9 +104,10 @@ const SIGNATURES = { ERC6909ContentURI: ['contractURI()', 'tokenURI(uint256)'], }; -const INTERFACE_IDS = mapValues(SIGNATURES, interfaceId); +export const INVALID_ID = '0xffffffff'; +export const INTERFACE_IDS = mapValues(SIGNATURES, interfaceId); -function shouldSupportInterfaces(interfaces = [], signatures = SIGNATURES) { +export function shouldSupportInterfaces(interfaces = [], signatures = SIGNATURES) { // case where only signatures are provided if (!Array.isArray(interfaces)) { signatures = interfaces; @@ -161,9 +162,3 @@ function shouldSupportInterfaces(interfaces = [], signatures = SIGNATURES) { }); }); } - -module.exports = { - SIGNATURES, - INTERFACE_IDS, - shouldSupportInterfaces, -}; diff --git a/test/utils/math/Math.test.js b/test/utils/math/Math.test.js index 507a3e9cec0..e41ac5a59b5 100644 --- a/test/utils/math/Math.test.js +++ b/test/utils/math/Math.test.js @@ -1,12 +1,15 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { Rounding } = require('../../helpers/enums'); -const { min, max, modExp } = require('../../helpers/math'); -const { generators } = require('../../helpers/random'); -const { product, range } = require('../../helpers/iterate'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { Rounding } from '../../helpers/enums'; +import { min, max, modExp } from '../../helpers/math'; +import { generators } from '../../helpers/random'; +import { product, range } from '../../helpers/iterate'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const RoundingDown = [Rounding.Floor, Rounding.Trunc]; const RoundingUp = [Rounding.Ceil, Rounding.Expand]; diff --git a/test/utils/math/SafeCast.test.js b/test/utils/math/SafeCast.test.js index ab62406ce45..4b03b16d0fa 100644 --- a/test/utils/math/SafeCast.test.js +++ b/test/utils/math/SafeCast.test.js @@ -1,12 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { range } from '../../helpers/iterate'; -const { range } = require('../../helpers/iterate'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$SafeCast'); - return { mock }; + return { mock: await ethers.deployContract('$SafeCast') }; } describe('SafeCast', function () { diff --git a/test/utils/math/SignedMath.t.sol b/test/utils/math/SignedMath.t.sol index aa567d61a6f..2af3d0fd4aa 100644 --- a/test/utils/math/SignedMath.t.sol +++ b/test/utils/math/SignedMath.t.sol @@ -4,8 +4,8 @@ pragma solidity ^0.8.20; import {Test} from "forge-std/Test.sol"; -import {Math} from "../../../contracts/utils/math/Math.sol"; -import {SignedMath} from "../../../contracts/utils/math/SignedMath.sol"; +import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; +import {SignedMath} from "@openzeppelin/contracts/utils/math/SignedMath.sol"; contract SignedMathTest is Test { function testSymbolicTernary(bool f, int256 a, int256 b) public pure { diff --git a/test/utils/math/SignedMath.test.js b/test/utils/math/SignedMath.test.js index 877f3b480c4..65be7958ddd 100644 --- a/test/utils/math/SignedMath.test.js +++ b/test/utils/math/SignedMath.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { min, max } from '../../helpers/math'; -const { min, max } = require('../../helpers/math'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function testCommutative(fn, lhs, rhs, expected, ...extra) { expect(await fn(lhs, rhs, ...extra)).to.deep.equal(expected); @@ -10,8 +13,7 @@ async function testCommutative(fn, lhs, rhs, expected, ...extra) { } async function fixture() { - const mock = await ethers.deployContract('$SignedMath'); - return { mock }; + return { mock: await ethers.deployContract('$SignedMath') }; } describe('SignedMath', function () { diff --git a/test/utils/structs/BitMap.test.js b/test/utils/structs/BitMap.test.js index 5662ab13f88..d7571df5b2a 100644 --- a/test/utils/structs/BitMap.test.js +++ b/test/utils/structs/BitMap.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const bitmap = await ethers.deployContract('$BitMaps'); - return { bitmap }; + return { bitmap: await ethers.deployContract('$BitMaps') }; } describe('BitMap', function () { diff --git a/test/utils/structs/Checkpoints.test.js b/test/utils/structs/Checkpoints.test.js index fe055a77805..984bcbec05b 100644 --- a/test/utils/structs/Checkpoints.test.js +++ b/test/utils/structs/Checkpoints.test.js @@ -1,8 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { OPTS } from '../../../scripts/generate/templates/Checkpoints.opts'; -const { OPTS } = require('../../../scripts/generate/templates/Checkpoints.opts'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); describe('Checkpoints', function () { for (const opt of OPTS) { @@ -32,7 +35,7 @@ describe('Checkpoints', function () { describe('without checkpoints', function () { it('at zero reverts', async function () { // Reverts with array out of bound access, which is unspecified - await expect(this.methods.at(0)).to.be.reverted; + await expect(this.methods.at(0)).to.be.revert(ethers); }); it('returns zero as latest value', async function () { diff --git a/test/utils/structs/CircularBuffer.test.js b/test/utils/structs/CircularBuffer.test.js index e79ba6923b4..389fdcee5a8 100644 --- a/test/utils/structs/CircularBuffer.test.js +++ b/test/utils/structs/CircularBuffer.test.js @@ -1,9 +1,12 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); - -const { generators } = require('../../helpers/random'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { generators } from '../../helpers/random'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const LENGTH = 4; diff --git a/test/utils/structs/DoubleEndedQueue.test.js b/test/utils/structs/DoubleEndedQueue.test.js index 6f8235ccdd3..dfcc046f8ba 100644 --- a/test/utils/structs/DoubleEndedQueue.test.js +++ b/test/utils/structs/DoubleEndedQueue.test.js @@ -1,7 +1,11 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { const mock = await ethers.deployContract('$DoubleEndedQueue'); diff --git a/test/utils/structs/EnumerableMap.behavior.js b/test/utils/structs/EnumerableMap.behavior.js index 4074b077973..daf7e0d8ab1 100644 --- a/test/utils/structs/EnumerableMap.behavior.js +++ b/test/utils/structs/EnumerableMap.behavior.js @@ -1,9 +1,8 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); +import { ethers } from 'ethers'; +import { expect } from 'chai'; +import { zip } from '../../helpers/iterate'; -const zip = (array1, array2) => array1.map((item, index) => [item, array2[index]]); - -function shouldBehaveLikeMap() { +export function shouldBehaveLikeMap() { async function expectMembersMatch(methods, keys, values) { expect(keys.length).to.equal(values.length); expect(await methods.length()).to.equal(keys.length); @@ -208,7 +207,3 @@ function shouldBehaveLikeMap() { } }); } - -module.exports = { - shouldBehaveLikeMap, -}; diff --git a/test/utils/structs/EnumerableMap.test.js b/test/utils/structs/EnumerableMap.test.js index 567c82dec0c..b5e0ffa1621 100644 --- a/test/utils/structs/EnumerableMap.test.js +++ b/test/utils/structs/EnumerableMap.test.js @@ -1,11 +1,13 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { mapValues } from '../../helpers/iterate'; +import { generators } from '../../helpers/random'; +import { MAP_TYPES, typeDescr, toMapTypeDescr } from '../../../scripts/generate/templates/Enumerable.opts'; +import { shouldBehaveLikeMap } from './EnumerableMap.behavior'; -const { mapValues } = require('../../helpers/iterate'); -const { generators } = require('../../helpers/random'); -const { MAP_TYPES, typeDescr, toMapTypeDescr } = require('../../../scripts/generate/templates/Enumerable.opts'); - -const { shouldBehaveLikeMap } = require('./EnumerableMap.behavior'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); // Add Bytes32ToBytes32Map that must be tested but is not part of the generated types. MAP_TYPES.unshift(toMapTypeDescr({ key: typeDescr({ type: 'bytes32' }), value: typeDescr({ type: 'bytes32' }) })); diff --git a/test/utils/structs/EnumerableSet.behavior.js b/test/utils/structs/EnumerableSet.behavior.js index 286563b2262..4f40a4a953b 100644 --- a/test/utils/structs/EnumerableSet.behavior.js +++ b/test/utils/structs/EnumerableSet.behavior.js @@ -1,7 +1,7 @@ -const { expect } = require('chai'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; -function shouldBehaveLikeSet() { +export function shouldBehaveLikeSet() { async function expectMembersMatch(methods, values) { expect(await methods.length()).to.equal(values.length); for (const value of values) expect(await methods.contains(value)).to.be.true; @@ -169,7 +169,3 @@ function shouldBehaveLikeSet() { } }); } - -module.exports = { - shouldBehaveLikeSet, -}; diff --git a/test/utils/structs/EnumerableSet.test.js b/test/utils/structs/EnumerableSet.test.js index 135bdf5084d..893193c9ba7 100644 --- a/test/utils/structs/EnumerableSet.test.js +++ b/test/utils/structs/EnumerableSet.test.js @@ -1,11 +1,13 @@ -const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { mapValues } from '../../helpers/iterate'; +import { generators } from '../../helpers/random'; +import { SET_TYPES } from '../../../scripts/generate/templates/Enumerable.opts'; +import { shouldBehaveLikeSet } from './EnumerableSet.behavior'; -const { mapValues } = require('../../helpers/iterate'); -const { generators } = require('../../helpers/random'); -const { SET_TYPES } = require('../../../scripts/generate/templates/Enumerable.opts'); - -const { shouldBehaveLikeSet } = require('./EnumerableSet.behavior'); +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const getMethods = (mock, fnSigs) => mapValues( diff --git a/test/utils/structs/Heap.test.js b/test/utils/structs/Heap.test.js index 0c6581d68fc..6af62e6605d 100644 --- a/test/utils/structs/Heap.test.js +++ b/test/utils/structs/Heap.test.js @@ -1,11 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); async function fixture() { - const mock = await ethers.deployContract('$Heap'); - return { mock }; + return { mock: await ethers.deployContract('$Heap') }; } describe('Heap', function () { diff --git a/test/utils/structs/MerkleTree.test.js b/test/utils/structs/MerkleTree.test.js index f0380ed023d..b4262beb852 100644 --- a/test/utils/structs/MerkleTree.test.js +++ b/test/utils/structs/MerkleTree.test.js @@ -1,11 +1,14 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { PANIC_CODES } = require('@nomicfoundation/hardhat-chai-matchers/panic'); -const { StandardMerkleTree } = require('@openzeppelin/merkle-tree'); - -const { generators } = require('../../helpers/random'); -const { range } = require('../../helpers/iterate'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { PANIC_CODES } from '@nomicfoundation/hardhat-ethers-chai-matchers/panic'; +import { StandardMerkleTree } from '@openzeppelin/merkle-tree'; +import { generators } from '../../helpers/random'; +import { range } from '../../helpers/iterate'; + +const { + ethers, + networkHelpers: { loadFixture }, +} = await network.create(); const DEPTH = 4; // 16 slots diff --git a/test/utils/types/Time.test.js b/test/utils/types/Time.test.js index 64add3d99a5..1d0bbfdcec2 100644 --- a/test/utils/types/Time.test.js +++ b/test/utils/types/Time.test.js @@ -1,10 +1,13 @@ -const { ethers } = require('hardhat'); -const { expect } = require('chai'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +import { network } from 'hardhat'; +import { expect } from 'chai'; +import { product } from '../../helpers/iterate'; +import { max } from '../../helpers/math'; -const { product } = require('../../helpers/iterate'); -const { max } = require('../../helpers/math'); -const time = require('../../helpers/time'); +const { + ethers, + helpers: { time }, + networkHelpers: { loadFixture }, +} = await network.create(); const MAX_UINT32 = (1n << 32n) - 1n; const MAX_UINT48 = (1n << 48n) - 1n; @@ -37,8 +40,7 @@ const effectSamplesForTimepoint = timepoint => [ ]; async function fixture() { - const mock = await ethers.deployContract('$Time'); - return { mock }; + return { mock: await ethers.deployContract('$Time') }; } describe('Time', function () {