Skip to content

Commit

Permalink
Add extendConfig logic for hardhat-viem plugin (#883)
Browse files Browse the repository at this point in the history
  • Loading branch information
cgewecke authored Apr 5, 2024
1 parent 011ee40 commit 09a7c83
Show file tree
Hide file tree
Showing 11 changed files with 394 additions and 7 deletions.
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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"
Expand Down
34 changes: 32 additions & 2 deletions plugins/hardhat.plugin.js
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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) {
Expand Down Expand Up @@ -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]);

Expand Down Expand Up @@ -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);
Expand Down
12 changes: 10 additions & 2 deletions plugins/resources/nomiclabs.ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
Expand Down Expand Up @@ -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;
14 changes: 13 additions & 1 deletion plugins/resources/nomiclabs.utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -249,6 +259,8 @@ async function finish(config, api, shouldKill){
}

module.exports = {
configureHardhatEVMGas,
requiresEVMConfiguration,
normalizeConfig,
finish,
tempCacheDir,
Expand Down
17 changes: 17 additions & 0 deletions test/integration/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
})
18 changes: 18 additions & 0 deletions test/integration/standard.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
})
5 changes: 5 additions & 0 deletions test/sources/projects/viem/.solcover.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = {
silent: process.env.SILENT ? true : false,
skipFiles: [],
istanbulReporter: ['json-summary', 'text']
}
31 changes: 31 additions & 0 deletions test/sources/projects/viem/contracts/Lock.sol
Original file line number Diff line number Diff line change
@@ -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);
}
}
20 changes: 20 additions & 0 deletions test/sources/projects/viem/hardhat.config.js
Original file line number Diff line number Diff line change
@@ -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,
};
Loading

0 comments on commit 09a7c83

Please sign in to comment.