Skip to content

Commit 09a7c83

Browse files
authored
Add extendConfig logic for hardhat-viem plugin (#883)
1 parent 011ee40 commit 09a7c83

File tree

11 files changed

+394
-7
lines changed

11 files changed

+394
-7
lines changed

package.json

+6-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"global-modules": "^2.0.0",
3636
"globby": "^10.0.1",
3737
"jsonschema": "^1.2.4",
38-
"lodash": "^4.17.15",
38+
"lodash": "^4.17.21",
3939
"mocha": "^10.2.0",
4040
"node-emoji": "^1.10.0",
4141
"pify": "^4.0.1",
@@ -46,18 +46,22 @@
4646
"web3-utils": "^1.3.6"
4747
},
4848
"devDependencies": {
49+
"@nomicfoundation/hardhat-network-helpers": "^1.0.10",
50+
"@nomicfoundation/hardhat-viem": "^2.0.0",
4951
"@nomiclabs/hardhat-ethers": "^2.0.4",
5052
"@nomiclabs/hardhat-truffle5": "^2.0.0",
5153
"@nomiclabs/hardhat-waffle": "^2.0.1",
5254
"@nomiclabs/hardhat-web3": "^2.0.0",
5355
"chai": "^4.3.4",
56+
"chai-as-promised": "^7.1.1",
5457
"decache": "^4.5.1",
5558
"ethereum-waffle": "^3.4.0",
5659
"ethers": "^5.5.3",
5760
"hardhat": "^2.22.2",
5861
"hardhat-gas-reporter": "^1.0.1",
5962
"nyc": "^14.1.1",
60-
"solc": "0.8.24"
63+
"solc": "0.8.24",
64+
"viem": "^2.9.9"
6165
},
6266
"peerDependencies": {
6367
"hardhat": "^2.11.0"

plugins/hardhat.plugin.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const path = require('path');
22
const PluginUI = require('./resources/nomiclabs.ui');
33

4-
const { task, types } = require("hardhat/config");
4+
const { extendConfig, task, types } = require("hardhat/config");
55
const { HardhatPluginError } = require("hardhat/plugins")
66
const {HARDHAT_NETWORK_RESET_EVENT} = require("hardhat/internal/constants");
77
const {
@@ -21,6 +21,24 @@ let optimizerDetails;
2121
// UI for the task flags...
2222
const ui = new PluginUI();
2323

24+
// Workaround for hardhat-viem-plugin and other provider redefinition conflicts
25+
extendConfig((config, userConfig) => {
26+
if (Boolean(process.env.SOLIDITY_COVERAGE)) {
27+
const { cloneDeep } = require("lodash");
28+
const { configureHardhatEVMGas } = require('./resources/nomiclabs.utils');
29+
const API = require('./../lib/api');
30+
const api = new API({});
31+
32+
let hardhatNetworkForCoverage = {};
33+
if (userConfig.networks && userConfig.networks.hardhat) {
34+
hardhatNetworkForCoverage = cloneDeep(userConfig.networks.hardhat);
35+
};
36+
37+
configureHardhatEVMGas(hardhatNetworkForCoverage, api);
38+
config.networks.hardhat = Object.assign(config.networks.hardhat, hardhatNetworkForCoverage);
39+
}
40+
});
41+
2442
subtask(TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT).setAction(async (_, { config }, runSuper) => {
2543
const solcInput = await runSuper();
2644
if (measureCoverage) {
@@ -133,6 +151,12 @@ task("coverage", "Generates a code coverage report for tests")
133151
// Catch interrupt signals
134152
process.on("SIGINT", nomiclabsUtils.finish.bind(null, config, api, true));
135153

154+
// Warn about hardhat-viem plugin if present and config hasn't happened
155+
if (env.viem !== undefined && nomiclabsUtils.requiresEVMConfiguration(env.network.config, api)) {
156+
ui.report('hardhat-viem', []);
157+
throw new Error(ui.generate('hardhat-viem'));
158+
}
159+
136160
// Version Info
137161
ui.report('hardhat-versions', [pkg.version]);
138162

@@ -208,7 +232,13 @@ task("coverage", "Generates a code coverage report for tests")
208232
// ==============
209233
// Server launch
210234
// ==============
211-
let network = await nomiclabsUtils.setupHardhatNetwork(env, api, ui);
235+
let network
236+
237+
if (nomiclabsUtils.requiresEVMConfiguration(env.network.config, api)) {
238+
network = await nomiclabsUtils.setupHardhatNetwork(env, api, ui);
239+
} else {
240+
network = env.network;
241+
}
212242

213243
accounts = await utils.getAccountsHardhat(network.provider);
214244
nodeInfo = await utils.getNodeInfoHardhat(network.provider);

plugins/resources/nomiclabs.ui.js

+10-2
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ class PluginUI extends UI {
5454
`${ct} ${c.bold('HardhatEVM')}: v${args[0]}\n` +
5555
`${ct} ${c.bold('network')}: ${args[1]}\n`,
5656

57+
'hardhat-viem': `\n${w}${c.red(" Coverage requires a special environment variable when used with 'hardhat-viem' ")}${w}` +
58+
`\n${c.red( "====================================================================================")}` +
59+
`\n${c.bold( "Please run the coverage command as:" )}` +
60+
`\n${c( "SOLIDITY_COVERAGE=true npx hardhat coverage")}` +
61+
`\n${c.red( "====================================================================================")}`
62+
,
5763
}
5864

5965
this._write(kinds[kind]);
@@ -81,12 +87,14 @@ class PluginUI extends UI {
8187

8288
'tests-fail': `${x} ${c.bold(args[0])} ${c.red('test(s) failed under coverage.')}`,
8389

84-
90+
'hardhat-viem': "'hardhat-viem' requires an environment variable to be set when used with the solidity-coverage plugin"
8591
}
8692

8793

8894
return this._format(kinds[kind])
8995
}
96+
97+
9098
}
9199

92-
module.exports = PluginUI;
100+
module.exports = PluginUI;

plugins/resources/nomiclabs.utils.js

+13-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ async function setupHardhatNetwork(env, api, ui){
104104
// after 2.15.0, the internal createProvider function has a different signature
105105
const newCreateProviderSignature = semver.satisfies(hardhatPackage.version, "^2.15.0");
106106

107-
let provider, networkName, networkConfig;
107+
let provider, networkConfig;
108108

109109
// HardhatEVM
110110
networkConfig = env.network.config;
@@ -133,6 +133,16 @@ async function setupHardhatNetwork(env, api, ui){
133133
)
134134
}
135135

136+
function requiresEVMConfiguration(networkConfig, api) {
137+
return (
138+
networkConfig.allowUnlimitedContractSize !== true ||
139+
networkConfig.blockGasLimit !== api.gasLimitNumber ||
140+
networkConfig.gas !== api.gasLimit ||
141+
networkConfig.gasPrice !== api.gasPrice ||
142+
networkConfig.initialBaseFeePerGas !== 0
143+
)
144+
}
145+
136146
function configureHardhatEVMGas(networkConfig, api){
137147
networkConfig.allowUnlimitedContractSize = true;
138148
networkConfig.blockGasLimit = api.gasLimitNumber;
@@ -249,6 +259,8 @@ async function finish(config, api, shouldKill){
249259
}
250260

251261
module.exports = {
262+
configureHardhatEVMGas,
263+
requiresEVMConfiguration,
252264
normalizeConfig,
253265
finish,
254266
tempCacheDir,

test/integration/errors.js

+17
Original file line numberDiff line numberDiff line change
@@ -167,4 +167,21 @@ describe('Hardhat Plugin: error cases', function() {
167167

168168
verify.coverageNotGenerated(hardhatConfig);
169169
})
170+
171+
it('viem plugin (when SOLIDITY_COVERAGE is undefined)', async function(){
172+
mock.installFullProject('viem');
173+
mock.hardhatSetupEnv(this);
174+
175+
try {
176+
await this.env.run("coverage");
177+
assert.fail()
178+
} catch(err){
179+
assert(
180+
err.message.includes('requires an environment variable'),
181+
`Should error when viem plugin is used without env variable:: ${err.message}`
182+
);
183+
}
184+
185+
verify.coverageNotGenerated(hardhatConfig);
186+
});
170187
})

test/integration/standard.js

+18
Original file line numberDiff line numberDiff line change
@@ -481,4 +481,22 @@ describe('Hardhat Plugin: standard use cases', function() {
481481

482482
verify.branchCoverage(expected);
483483
});
484+
485+
it('viem plugin (when SOLIDITY_COVERAGE="true")', async function(){
486+
process.env.SOLIDITY_COVERAGE = "true";
487+
488+
mock.installFullProject('viem');
489+
mock.hardhatSetupEnv(this);
490+
491+
await this.env.run("coverage");
492+
493+
const expected = [
494+
{
495+
file: mock.pathToContract(hardhatConfig, 'Lock.sol'),
496+
pct: 100
497+
}
498+
];
499+
500+
verify.branchCoverage(expected);
501+
});
484502
})
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module.exports = {
2+
silent: process.env.SILENT ? true : false,
3+
skipFiles: [],
4+
istanbulReporter: ['json-summary', 'text']
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* SPDX-License-Identifier: MIT */
2+
pragma solidity >=0.8.0 <0.9.0;
3+
4+
contract Lock {
5+
uint public unlockTime;
6+
address payable public owner;
7+
8+
event Withdrawal(uint amount, uint when);
9+
10+
constructor(uint _unlockTime) payable {
11+
require(
12+
block.timestamp < _unlockTime,
13+
"Unlock time should be in the future"
14+
);
15+
16+
unlockTime = _unlockTime;
17+
owner = payable(msg.sender);
18+
}
19+
20+
function withdraw() public {
21+
// Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal
22+
// console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp);
23+
24+
require(block.timestamp >= unlockTime, "You can't withdraw yet");
25+
require(msg.sender == owner, "You aren't the owner");
26+
27+
emit Withdrawal(address(this).balance, block.timestamp);
28+
29+
owner.transfer(address(this).balance);
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
require(__dirname + "/../plugins/nomiclabs.plugin");
2+
require("@nomicfoundation/hardhat-viem");
3+
4+
module.exports = {
5+
networks: {
6+
hardhat: {
7+
gasPrice: 50_000_000_000
8+
}
9+
},
10+
solidity: {
11+
version: "0.8.17",
12+
settings: {
13+
optimizer: {
14+
enabled: true
15+
},
16+
viaIR: process.env.VIA_IR === "true"
17+
}
18+
},
19+
logger: process.env.SILENT ? { log: () => {} } : console,
20+
};

0 commit comments

Comments
 (0)