Compare commits

..

4 Commits

  1. 9
      README.md
  2. 10
      lib/registrar.js
  3. 10
      package.json
  4. 34
      plugins/hardhat.plugin.js
  5. 12
      plugins/resources/nomiclabs.ui.js
  6. 14
      plugins/resources/nomiclabs.utils.js
  7. 17
      test/integration/errors.js
  8. 18
      test/integration/standard.js
  9. 5
      test/sources/projects/viem/.solcover.js
  10. 31
      test/sources/projects/viem/contracts/Lock.sol
  11. 20
      test/sources/projects/viem/hardhat.config.js
  12. 137
      test/sources/projects/viem/test/lock.js
  13. 9
      test/sources/solidity/contracts/statements/require.sol
  14. 5
      test/units/statements.js
  15. 105
      yarn.lock

@ -56,6 +56,15 @@ $ npx hardhat compile
$ TS_NODE_TRANSPILE_ONLY=true npx hardhat coverage
```
**Weird test failures or plugin conflicts?**
```sh
# Setting the `SOLIDITY_COVERAGE` env variable tells the coverage plugin to configure the provider
# early in the hardhat task cycle, minimizing conflicts with other plugins or `extendEnvironment` hooks
$ SOLIDITY_COVERAGE=true npx hardhat coverage
```
**Additional Help**
+ [FAQ][1007]
+ [Advanced Topics][1005]

@ -23,6 +23,14 @@ class Registrar {
this.modifierWhitelist = [];
}
_seekSemiColon(contract, pos) {
const end = pos + 5;
for(pos; pos <= end; pos++) {
if (contract[pos] === ';') break;
}
return pos;
}
/**
* Adds injection point to injection points map
* @param {Object} contract instrumentation target
@ -441,7 +449,7 @@ class Registrar {
);
this._createInjectionPoint(
contract,
expression.range[1] + 2,
this._seekSemiColon(contract.instrumented, expression.range[1] + 1) + 1,
{
type: 'injectRequirePost',
branchId: contract.branchId,

@ -1,6 +1,6 @@
{
"name": "solidity-coverage",
"version": "0.8.11",
"version": "0.8.12",
"description": "Code coverage for Solidity testing",
"main": "plugins/nomiclabs.plugin.js",
"bin": {
@ -35,7 +35,7 @@
"global-modules": "^2.0.0",
"globby": "^10.0.1",
"jsonschema": "^1.2.4",
"lodash": "^4.17.15",
"lodash": "^4.17.21",
"mocha": "^10.2.0",
"node-emoji": "^1.10.0",
"pify": "^4.0.1",
@ -46,18 +46,22 @@
"web3-utils": "^1.3.6"
},
"devDependencies": {
"@nomicfoundation/hardhat-network-helpers": "^1.0.10",
"@nomicfoundation/hardhat-viem": "^2.0.0",
"@nomiclabs/hardhat-ethers": "^2.0.4",
"@nomiclabs/hardhat-truffle5": "^2.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.1",
"@nomiclabs/hardhat-web3": "^2.0.0",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"decache": "^4.5.1",
"ethereum-waffle": "^3.4.0",
"ethers": "^5.5.3",
"hardhat": "^2.22.2",
"hardhat-gas-reporter": "^1.0.1",
"nyc": "^14.1.1",
"solc": "0.8.24"
"solc": "0.8.24",
"viem": "^2.9.9"
},
"peerDependencies": {
"hardhat": "^2.11.0"

@ -1,7 +1,7 @@
const path = require('path');
const PluginUI = require('./resources/nomiclabs.ui');
const { task, types } = require("hardhat/config");
const { extendConfig, task, types } = require("hardhat/config");
const { HardhatPluginError } = require("hardhat/plugins")
const {HARDHAT_NETWORK_RESET_EVENT} = require("hardhat/internal/constants");
const {
@ -21,6 +21,24 @@ let optimizerDetails;
// UI for the task flags...
const ui = new PluginUI();
// Workaround for hardhat-viem-plugin and other provider redefinition conflicts
extendConfig((config, userConfig) => {
if (Boolean(process.env.SOLIDITY_COVERAGE)) {
const { cloneDeep } = require("lodash");
const { configureHardhatEVMGas } = require('./resources/nomiclabs.utils');
const API = require('./../lib/api');
const api = new API({});
let hardhatNetworkForCoverage = {};
if (userConfig.networks && userConfig.networks.hardhat) {
hardhatNetworkForCoverage = cloneDeep(userConfig.networks.hardhat);
};
configureHardhatEVMGas(hardhatNetworkForCoverage, api);
config.networks.hardhat = Object.assign(config.networks.hardhat, hardhatNetworkForCoverage);
}
});
subtask(TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT).setAction(async (_, { config }, runSuper) => {
const solcInput = await runSuper();
if (measureCoverage) {
@ -133,6 +151,12 @@ task("coverage", "Generates a code coverage report for tests")
// Catch interrupt signals
process.on("SIGINT", nomiclabsUtils.finish.bind(null, config, api, true));
// Warn about hardhat-viem plugin if present and config hasn't happened
if (env.viem !== undefined && nomiclabsUtils.requiresEVMConfiguration(env.network.config, api)) {
ui.report('hardhat-viem', []);
throw new Error(ui.generate('hardhat-viem'));
}
// Version Info
ui.report('hardhat-versions', [pkg.version]);
@ -208,7 +232,13 @@ task("coverage", "Generates a code coverage report for tests")
// ==============
// Server launch
// ==============
let network = await nomiclabsUtils.setupHardhatNetwork(env, api, ui);
let network
if (nomiclabsUtils.requiresEVMConfiguration(env.network.config, api)) {
network = await nomiclabsUtils.setupHardhatNetwork(env, api, ui);
} else {
network = env.network;
}
accounts = await utils.getAccountsHardhat(network.provider);
nodeInfo = await utils.getNodeInfoHardhat(network.provider);

@ -54,6 +54,12 @@ class PluginUI extends UI {
`${ct} ${c.bold('HardhatEVM')}: v${args[0]}\n` +
`${ct} ${c.bold('network')}: ${args[1]}\n`,
'hardhat-viem': `\n${w}${c.red(" Coverage requires a special environment variable when used with 'hardhat-viem' ")}${w}` +
`\n${c.red( "====================================================================================")}` +
`\n${c.bold( "Please run the coverage command as:" )}` +
`\n${c( "SOLIDITY_COVERAGE=true npx hardhat coverage")}` +
`\n${c.red( "====================================================================================")}`
,
}
this._write(kinds[kind]);
@ -81,12 +87,14 @@ class PluginUI extends UI {
'tests-fail': `${x} ${c.bold(args[0])} ${c.red('test(s) failed under coverage.')}`,
'hardhat-viem': "'hardhat-viem' requires an environment variable to be set when used with the solidity-coverage plugin"
}
return this._format(kinds[kind])
}
}
module.exports = PluginUI;
module.exports = PluginUI;

@ -104,7 +104,7 @@ async function setupHardhatNetwork(env, api, ui){
// after 2.15.0, the internal createProvider function has a different signature
const newCreateProviderSignature = semver.satisfies(hardhatPackage.version, "^2.15.0");
let provider, networkName, networkConfig;
let provider, networkConfig;
// HardhatEVM
networkConfig = env.network.config;
@ -133,6 +133,16 @@ async function setupHardhatNetwork(env, api, ui){
)
}
function requiresEVMConfiguration(networkConfig, api) {
return (
networkConfig.allowUnlimitedContractSize !== true ||
networkConfig.blockGasLimit !== api.gasLimitNumber ||
networkConfig.gas !== api.gasLimit ||
networkConfig.gasPrice !== api.gasPrice ||
networkConfig.initialBaseFeePerGas !== 0
)
}
function configureHardhatEVMGas(networkConfig, api){
networkConfig.allowUnlimitedContractSize = true;
networkConfig.blockGasLimit = api.gasLimitNumber;
@ -249,6 +259,8 @@ async function finish(config, api, shouldKill){
}
module.exports = {
configureHardhatEVMGas,
requiresEVMConfiguration,
normalizeConfig,
finish,
tempCacheDir,

@ -167,4 +167,21 @@ describe('Hardhat Plugin: error cases', function() {
verify.coverageNotGenerated(hardhatConfig);
})
it('viem plugin (when SOLIDITY_COVERAGE is undefined)', async function(){
mock.installFullProject('viem');
mock.hardhatSetupEnv(this);
try {
await this.env.run("coverage");
assert.fail()
} catch(err){
assert(
err.message.includes('requires an environment variable'),
`Should error when viem plugin is used without env variable:: ${err.message}`
);
}
verify.coverageNotGenerated(hardhatConfig);
});
})

@ -481,4 +481,22 @@ describe('Hardhat Plugin: standard use cases', function() {
verify.branchCoverage(expected);
});
it('viem plugin (when SOLIDITY_COVERAGE="true")', async function(){
process.env.SOLIDITY_COVERAGE = "true";
mock.installFullProject('viem');
mock.hardhatSetupEnv(this);
await this.env.run("coverage");
const expected = [
{
file: mock.pathToContract(hardhatConfig, 'Lock.sol'),
pct: 100
}
];
verify.branchCoverage(expected);
});
})

@ -0,0 +1,5 @@
module.exports = {
silent: process.env.SILENT ? true : false,
skipFiles: [],
istanbulReporter: ['json-summary', 'text']
}

@ -0,0 +1,31 @@
/* SPDX-License-Identifier: MIT */
pragma solidity >=0.8.0 <0.9.0;
contract Lock {
uint public unlockTime;
address payable public owner;
event Withdrawal(uint amount, uint when);
constructor(uint _unlockTime) payable {
require(
block.timestamp < _unlockTime,
"Unlock time should be in the future"
);
unlockTime = _unlockTime;
owner = payable(msg.sender);
}
function withdraw() public {
// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);
require(block.timestamp >= unlockTime, "You can't withdraw yet");
require(msg.sender == owner, "You aren't the owner");
emit Withdrawal(address(this).balance, block.timestamp);
owner.transfer(address(this).balance);
}
}

@ -0,0 +1,20 @@
require(__dirname + "/../plugins/nomiclabs.plugin");
require("@nomicfoundation/hardhat-viem");
module.exports = {
networks: {
hardhat: {
gasPrice: 50_000_000_000
}
},
solidity: {
version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
},
logger: process.env.SILENT ? { log: () => {} } : console,
};

@ -0,0 +1,137 @@
const {
time,
loadFixture,
} = require("@nomicfoundation/hardhat-network-helpers");
const { expect, use } = require ("chai");
const chaiAsPromised = require("chai-as-promised");
const hre = require("hardhat");
const { getAddress, parseGwei } = require("viem");
use(chaiAsPromised);
describe("Lock", function () {
// We define a fixture to reuse the same setup in every test.
// We use loadFixture to run this setup once, snapshot that state,
// and reset Hardhat Network to that snapshot in every test.
async function deployOneYearLockFixture() {
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
const lockedAmount = parseGwei("1");
const unlockTime = BigInt((await time.latest()) + ONE_YEAR_IN_SECS);
// Contracts are deployed using the first signer/account by default
const [owner, otherAccount] = await hre.viem.getWalletClients();
const lock = await hre.viem.deployContract("Lock", [unlockTime], {
value: lockedAmount,
});
const publicClient = await hre.viem.getPublicClient();
return {
lock,
unlockTime,
lockedAmount,
owner,
otherAccount,
publicClient,
};
}
describe("Deployment", function () {
it("Should set the right unlockTime", async function () {
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
expect(await lock.read.unlockTime()).to.equal(unlockTime);
});
it("Should set the right owner", async function () {
const { lock, owner } = await loadFixture(deployOneYearLockFixture);
expect(await lock.read.owner()).to.equal(
getAddress(owner.account.address)
);
});
it("Should receive and store the funds to lock", async function () {
const { lock, lockedAmount, publicClient } = await loadFixture(
deployOneYearLockFixture
);
expect(
await publicClient.getBalance({
address: lock.address,
})
).to.equal(lockedAmount);
});
it("Should fail if the unlockTime is not in the future", async function () {
// We don't use the fixture here because we want a different deployment
const latestTime = BigInt(await time.latest());
await expect(
hre.viem.deployContract("Lock", [latestTime], {
value: 1n,
})
).to.be.rejectedWith("Unlock time should be in the future");
});
});
describe("Withdrawals", function () {
describe("Validations", function () {
it("Should revert with the right error if called too soon", async function () {
const { lock } = await loadFixture(deployOneYearLockFixture);
await expect(lock.write.withdraw()).to.be.rejectedWith(
"You can't withdraw yet"
);
});
it("Should revert with the right error if called from another account", async function () {
const { lock, unlockTime, otherAccount } = await loadFixture(
deployOneYearLockFixture
);
// We can increase the time in Hardhat Network
await time.increaseTo(unlockTime);
// We retrieve the contract with a different account to send a transaction
const lockAsOtherAccount = await hre.viem.getContractAt(
"Lock",
lock.address,
{ client: { wallet: otherAccount } }
);
await expect(lockAsOtherAccount.write.withdraw()).to.be.rejectedWith(
"You aren't the owner"
);
});
it("Shouldn't fail if the unlockTime has arrived and the owner calls it", async function () {
const { lock, unlockTime } = await loadFixture(
deployOneYearLockFixture
);
// Transactions are sent using the first signer by default
await time.increaseTo(unlockTime);
await expect(lock.write.withdraw()).to.be.fulfilled;
});
});
describe("Events", function () {
it("Should emit an event on withdrawals", async function () {
const { lock, unlockTime, lockedAmount, publicClient } =
await loadFixture(deployOneYearLockFixture);
await time.increaseTo(unlockTime);
const hash = await lock.write.withdraw();
await publicClient.waitForTransactionReceipt({ hash });
// get the withdrawal events in the latest block
const withdrawalEvents = await lock.getEvents.Withdrawal();
expect(withdrawalEvents).to.have.lengthOf(1);
expect(withdrawalEvents[0].args.amount).to.equal(lockedAmount);
});
});
});
});

@ -0,0 +1,9 @@
pragma solidity >=0.8.0 <0.9.0;
contract Test {
function a(uint x) public {
require(true);
require(true) ;
require(true) ;
}
}

@ -85,6 +85,11 @@ describe('generic statements', () => {
util.report(info.solcOutput.errors);
});
it('should instrument require statements when semi-colon is separated by spaces', () => {
const info = util.instrumentAndCompile('statements/require');
util.report(info.solcOutput.errors);
});
it('should cover an emitted event statement', async function() {
const contract = await util.bootstrapCoverage('statements/emit-coverage', api, this.provider);
coverage.addContract(contract.instrumented, util.filePath);

@ -2,6 +2,11 @@
# yarn lockfile v1
"@adraffy/ens-normalize@1.10.0":
version "1.10.0"
resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7"
integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==
"@babel/code-frame@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
@ -511,10 +516,27 @@
tweetnacl "^1.0.3"
tweetnacl-util "^0.15.1"
"@noble/curves@1.2.0", "@noble/curves@~1.2.0":
version "1.2.0"
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35"
integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==
dependencies:
"@noble/hashes" "1.3.2"
"@noble/hashes@1.0.0", "@noble/hashes@~1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.0.0.tgz#d5e38bfbdaba174805a4e649f13be9a9ed3351ae"
"@noble/hashes@1.3.2":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39"
integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==
"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.2":
version "1.3.3"
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699"
integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==
"@noble/secp256k1@1.5.5", "@noble/secp256k1@~1.5.2":
version "1.5.5"
resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.5.5.tgz#315ab5745509d1a8c8e90d0bdf59823ccf9bcfc3"
@ -627,6 +649,21 @@
"@nomicfoundation/ethereumjs-rlp" "5.0.4"
ethereum-cryptography "0.1.3"
"@nomicfoundation/hardhat-network-helpers@^1.0.10":
version "1.0.10"
resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.10.tgz#c61042ceb104fdd6c10017859fdef6529c1d6585"
integrity sha512-R35/BMBlx7tWN5V6d/8/19QCwEmIdbnA4ZrsuXgvs8i2qFx5i7h6mH5pBS4Pwi4WigLH+upl6faYusrNPuzMrQ==
dependencies:
ethereumjs-util "^7.1.4"
"@nomicfoundation/hardhat-viem@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-viem/-/hardhat-viem-2.0.0.tgz#4f5de792028a5607984ea9fd1e17727a71e3cdb8"
integrity sha512-ilXQKTc1jWHqJ66fAN6TIyCRyormoChOn1yQTCGoBQ+G6QcVCu5FTaGL2r0KUOY4IkTohtphK+UXQrKcxQX5Yw==
dependencies:
abitype "^0.9.8"
lodash.memoize "^4.1.2"
"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.1.tgz#4c858096b1c17fe58a474fe81b46815f93645c15"
@ -760,6 +797,11 @@
version "1.0.0"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.0.0.tgz#109fb595021de285f05a7db6806f2f48296fcee7"
"@scure/base@~1.1.0", "@scure/base@~1.1.2":
version "1.1.6"
resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.6.tgz#8ce5d304b436e4c84f896e0550c83e4d88cb917d"
integrity sha512-ok9AWwhcgYuGG3Zfhyqg+zwl+Wn5uE+dwC0NV/2qQkx4dABbb/bx96vWu8NSj+BNjjSjno+JRYRjle1jV08k3g==
"@scure/bip32@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.0.1.tgz#1409bdf9f07f0aec99006bb0d5827693418d3aa5"
@ -768,6 +810,15 @@
"@noble/secp256k1" "~1.5.2"
"@scure/base" "~1.0.0"
"@scure/bip32@1.3.2":
version "1.3.2"
resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.2.tgz#90e78c027d5e30f0b22c1f8d50ff12f3fb7559f8"
integrity sha512-N1ZhksgwD3OBlwTv3R6KFEcPojl/W4ElJOeCZdi+vuI5QmTFwLq3OFf2zd2ROpKvxFdgZ6hUpb0dx9bVNEwYCA==
dependencies:
"@noble/curves" "~1.2.0"
"@noble/hashes" "~1.3.2"
"@scure/base" "~1.1.2"
"@scure/bip39@1.0.0":
version "1.0.0"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.0.0.tgz#47504e58de9a56a4bbed95159d2d6829fa491bb0"
@ -775,6 +826,14 @@
"@noble/hashes" "~1.0.0"
"@scure/base" "~1.0.0"
"@scure/bip39@1.2.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a"
integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==
dependencies:
"@noble/hashes" "~1.3.0"
"@scure/base" "~1.1.0"
"@sentry/core@5.30.0":
version "5.30.0"
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3"
@ -1082,6 +1141,16 @@ abbrev@1.0.x:
version "1.0.9"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"
abitype@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.0.0.tgz#237176dace81d90d018bebf3a45cb42f2a2d9e97"
integrity sha512-NMeMah//6bJ56H5XRj8QCV4AwuW6hB6zqz2LnhhLdcWVQOsXki6/Pn3APeqxCma62nXIcmZWdu1DlHWS74umVQ==
abitype@^0.9.8:
version "0.9.10"
resolved "https://registry.yarnpkg.com/abitype/-/abitype-0.9.10.tgz#fa6fa30a6465da98736f98b6c601a02ed49f6eec"
integrity sha512-FIS7U4n7qwAT58KibwYig5iFG4K61rbhAqaQh/UWj8v1Y8mjX3F8TC9gd8cz9yT1TYel9f8nS5NO5kZp2RW0jQ==
abstract-leveldown@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz#5cb89f958a44f526779d740d1440e743e0c30a57"
@ -2211,6 +2280,13 @@ caseless@^0.12.0, caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
chai-as-promised@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0"
integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==
dependencies:
check-error "^1.0.2"
chai@^4.2.0, chai@^4.3.4:
version "4.3.6"
resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.6.tgz#ffe4ba2d9fa9d6680cc0b370adae709ec9011e9c"
@ -4837,6 +4913,11 @@ isobject@^3.0.0, isobject@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
isows@1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/isows/-/isows-1.0.3.tgz#93c1cf0575daf56e7120bab5c8c448b0809d0d74"
integrity sha512-2cKei4vlmg2cxEjm3wVSqn8pcoRF/LX/wpifuuNquFO4SQmPwarClT+SUCA2lt+l581tTeZIPIZuIDo2jWN1fg==
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@ -5277,6 +5358,11 @@ lodash.flattendeep@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
@ -7918,6 +8004,20 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
viem@^2.9.9:
version "2.9.9"
resolved "https://registry.yarnpkg.com/viem/-/viem-2.9.9.tgz#c89e6f402ae06601579a7e3069de76eb08c60adb"
integrity sha512-SUIHBL6M5IIlqDCMEQwAAvHzeglaM4FEqM6bCI+srLXtFYmrpV4tWhnpobQRNwh4f7HIksmKLLZ+cytv8FfnJQ==
dependencies:
"@adraffy/ens-normalize" "1.10.0"
"@noble/curves" "1.2.0"
"@noble/hashes" "1.3.2"
"@scure/bip32" "1.3.2"
"@scure/bip39" "1.2.1"
abitype "1.0.0"
isows "1.0.3"
ws "8.13.0"
web3-bzz@1.2.11:
version "1.2.11"
resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.2.11.tgz#41bc19a77444bd5365744596d778b811880f707f"
@ -8751,6 +8851,11 @@ ws@7.4.6:
version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
ws@8.13.0:
version "8.13.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"
integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==
ws@^3.0.0:
version "3.3.3"
resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2"

Loading…
Cancel
Save