Enable coverage when `viaIR` compiler flag is true (#854)

pull/856/head
cgewecke 10 months ago committed by GitHub
parent d3a5b379a4
commit 4f007c7583
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 10
      .circleci/config.yml
  2. 3
      lib/api.js
  3. 50
      lib/collector.js
  4. 52
      lib/injector.js
  5. 2
      lib/instrumenter.js
  6. 5
      package.json
  7. 11
      plugins/hardhat.plugin.js
  8. 21
      plugins/resources/nomiclabs.utils.js
  9. 4
      plugins/resources/plugin.utils.js
  10. 8
      scripts/ci.sh
  11. 3
      scripts/integration.sh
  12. 3
      scripts/unit.sh
  13. 1
      scripts/zeppelin.sh
  14. 25
      test/integration/standard.js
  15. 8
      test/sources/projects/contract-subfolders/hardhat.config.js
  16. 2
      test/sources/projects/hardhat-compile-config/contracts/ContractA1.sol
  17. 2
      test/sources/projects/hardhat-compile-config/contracts/ContractB1.sol
  18. 2
      test/sources/projects/hardhat-compile-config/contracts/ContractC1.sol
  19. 18
      test/sources/projects/hardhat-compile-config/hardhat.config.js
  20. 8
      test/sources/projects/hardhat-gas-reporter/hardhat.config.js
  21. 8
      test/sources/projects/hardhat-mine/hardhat.config.js
  22. 8
      test/sources/projects/hardhat-reset/hardhat.config.js
  23. 8
      test/sources/projects/import-paths/hardhat.config.js
  24. 8
      test/sources/projects/libraries/hardhat.config.js
  25. 8
      test/sources/projects/matrix/hardhat.config.js
  26. 2
      test/sources/projects/modifiers/contracts/ModifiersA.sol
  27. 2
      test/sources/projects/modifiers/contracts/ModifiersB.sol
  28. 2
      test/sources/projects/modifiers/contracts/ModifiersC.sol
  29. 8
      test/sources/projects/modifiers/hardhat.config.js
  30. 8
      test/sources/projects/multiple-suites/hardhat.config.js
  31. 8
      test/sources/projects/no-sources/hardhat.config.js
  32. 4
      test/sources/projects/overrides-viaIR/.solcover.js
  33. 17
      test/sources/projects/overrides-viaIR/contracts/ContractOverA2.sol
  34. 17
      test/sources/projects/overrides-viaIR/contracts/ContractOverB2.sol
  35. 17
      test/sources/projects/overrides-viaIR/contracts/ContractOverC2.sol
  36. 29
      test/sources/projects/overrides-viaIR/hardhat.config.js
  37. 11
      test/sources/projects/overrides-viaIR/test/contract_over_a2.js
  38. 15
      test/sources/projects/overrides-viaIR/test/contract_over_b2.js
  39. 20
      test/sources/projects/overrides-viaIR/test/contract_over_c2.js
  40. 8
      test/sources/projects/skipping/hardhat.config.js
  41. 8
      test/sources/projects/solc-8/hardhat.config.js
  42. 8
      test/sources/projects/task-hooks/hardhat.config.js
  43. 8
      test/sources/projects/ternary-and-logical-or/hardhat.config.js
  44. 8
      test/sources/projects/test-files/hardhat.config.js
  45. 8
      test/sources/projects/tests-folder/hardhat.config.js
  46. 7
      test/units/statements.js
  47. 8
      test/util/integration.js
  48. 6
      test/util/util.js

@ -12,11 +12,9 @@ step_install_nvm: &step_install_nvm
set +e set +e
export NVM_DIR="/opt/circleci/.nvm" export NVM_DIR="/opt/circleci/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
nvm install v14.19.0 nvm install v18
nvm alias default v14.19.0
echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV
echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV
jobs: jobs:
unit-test: unit-test:
docker: docker:
@ -32,9 +30,13 @@ jobs:
command: | command: |
yarn yarn
- run: - run:
name: Run tests name: Tests ( optimizer.enabled=false )
command: | command: |
npm run test:ci npm run test:ci
- run:
name: Tests ( viaIR=true )
command: |
npm run test:ci:viaIR
- run: - run:
name: Upload coverage name: Upload coverage
command: | command: |

@ -54,6 +54,7 @@ class API {
this.istanbulFolder = config.istanbulFolder || false; this.istanbulFolder = config.istanbulFolder || false;
this.istanbulReporter = config.istanbulReporter || ['html', 'lcov', 'text', 'json']; this.istanbulReporter = config.istanbulReporter || ['html', 'lcov', 'text', 'json'];
this.viaIR = config.viaIR;
this.solcOptimizerDetails = config.solcOptimizerDetails; this.solcOptimizerDetails = config.solcOptimizerDetails;
this.setLoggingLevel(config.silent); this.setLoggingLevel(config.silent);
@ -176,7 +177,7 @@ class API {
// Hardhat // Hardhat
async attachToHardhatVM(provider){ async attachToHardhatVM(provider){
const self = this; const self = this;
this.collector = new DataCollector(this.instrumenter.instrumentationData); this.collector = new DataCollector(this.instrumenter.instrumentationData, this.viaIR);
if ('init' in provider) { if ('init' in provider) {
// Newer versions of Hardhat initialize the provider lazily, so we need to // Newer versions of Hardhat initialize the provider lazily, so we need to

@ -3,12 +3,31 @@
* coverage map constructed by the Instrumenter. * coverage map constructed by the Instrumenter.
*/ */
class DataCollector { class DataCollector {
constructor(instrumentationData={}){ constructor(instrumentationData={}, viaIR){
this.instrumentationData = instrumentationData; this.instrumentationData = instrumentationData;
this.validOpcodes = { this.validOpcodes = {
"PUSH1": true, "PUSH1": true,
"DUP1": viaIR,
"DUP2": viaIR,
"DUP3": viaIR,
"DUP4": viaIR,
"DUP5": viaIR,
"DUP6": viaIR,
"DUP7": viaIR,
"DUP8": viaIR,
"DUP9": viaIR,
"DUP10": viaIR,
"DUP11": viaIR,
"DUP12": viaIR,
"DUP13": viaIR,
"DUP14": viaIR,
"DUP15": viaIR,
"DUP16": viaIR,
} }
this.lastHash = null;
this.viaIR = viaIR;
} }
/** /**
@ -46,7 +65,26 @@ class DataCollector {
hash = this._normalizeHash(hash); hash = this._normalizeHash(hash);
if(this.instrumentationData[hash]){ if(this.instrumentationData[hash]){
this.instrumentationData[hash].hits++; // abi.encode (used to circumvent viaIR) sometimes puts the hash on the stack twice
if (this.lastHash !== hash) {
this.lastHash = hash;
this.instrumentationData[hash].hits++
}
return;
}
// Detect and recover from viaIR mangled hashes by left-padding single `0`
if(this.viaIR && hash.length === 18) {
hash = hash.slice(2);
hash = '0' + hash;
hash = hash.slice(0,16);
hash = '0x' + hash;
if(this.instrumentationData[hash]){
if (this.lastHash !== hash) {
this.lastHash = hash;
this.instrumentationData[hash].hits++
}
}
} }
} }
@ -56,10 +94,14 @@ class DataCollector {
* but prevents left-padding shorter irrelevant hashes * but prevents left-padding shorter irrelevant hashes
* *
* @param {String} hash data hash from evm stack. * @param {String} hash data hash from evm stack.
* @return {String} 0x prefixed hash of length 66. * @return {String} 0x prefixed hash of length 18.
*/ */
_normalizeHash(hash){ _normalizeHash(hash){
if (hash.length < 18 && hash.length > 11){ // viaIR sometimes right-pads the hashes out to 32 bytes
// but it doesn't preserve leading zeroes when it does this
if (this.viaIR && hash.length >= 18) {
hash = hash.slice(0,18);
} else if (hash.length < 18 && hash.length > 11){
hash = hash.slice(2); hash = hash.slice(2);
while(hash.length < 16) hash = '0' + hash; while(hash.length < 16) hash = '0' + hash;
hash = '0x' + hash hash = '0x' + hash

@ -1,7 +1,8 @@
const web3Utils = require("web3-utils"); const web3Utils = require("web3-utils");
class Injector { class Injector {
constructor(){ constructor(viaIR){
this.viaIR = viaIR;
this.hashCounter = 0; this.hashCounter = 0;
this.modifierCounter = 0; this.modifierCounter = 0;
this.modifiers = {}; this.modifiers = {};
@ -23,7 +24,9 @@ class Injector {
case 'modifier': case 'modifier':
return ` ${this._getModifierIdentifier(id)} `; return ` ${this._getModifierIdentifier(id)} `;
default: default:
return `${this._getDefaultMethodIdentifier(id)}(${hash}); /* ${type} */ \n`; return (this.viaIR)
? `${this._getAbiEncodeStatementHash(hash)} /* ${type} */ \n`
: `${this._getDefaultMethodIdentifier(id)}(${hash}); /* ${type} */ \n`;
} }
} }
@ -51,6 +54,16 @@ class Injector {
return `c_mod${web3Utils.keccak256(id).slice(2,10)}` return `c_mod${web3Utils.keccak256(id).slice(2,10)}`
} }
// Way to get hash on the stack with viaIR (which seems to ignore abi.encode builtin)
// Tested with v0.8.17, v0.8.24
_getAbiEncodeStatementHash(hash){
return `abi.encode(${hash}); `
}
_getAbiEncodeStatementVar(hash){
return `abi.encode(c__${hash}); `
}
_getInjectionComponents(contract, injectionPoint, id, type){ _getInjectionComponents(contract, injectionPoint, id, type){
const { start, end } = this._split(contract, injectionPoint); const { start, end } = this._split(contract, injectionPoint);
const hash = this._getHash(id) const hash = this._getHash(id)
@ -73,7 +86,10 @@ class Injector {
_getDefaultMethodDefinition(id){ _getDefaultMethodDefinition(id){
const hash = web3Utils.keccak256(id).slice(2,10); const hash = web3Utils.keccak256(id).slice(2,10);
const method = this._getDefaultMethodIdentifier(id); const method = this._getDefaultMethodIdentifier(id);
return `\nfunction ${method}(bytes8 c__${hash}) internal pure {}\n`;
return (this.viaIR)
? ``
: `\nfunction ${method}(bytes8 c__${hash}) internal pure {}\n`;
} }
/** /**
@ -85,7 +101,11 @@ class Injector {
_getFileScopedHashMethodDefinition(id, contract){ _getFileScopedHashMethodDefinition(id, contract){
const hash = web3Utils.keccak256(id).slice(2,10); const hash = web3Utils.keccak256(id).slice(2,10);
const method = this._getDefaultMethodIdentifier(id); const method = this._getDefaultMethodIdentifier(id);
return `\nfunction ${method}(bytes8 c__${hash}) pure {}\n`; const abi = this._getAbiEncodeStatementVar(hash);
return (this.viaIR)
? `\nfunction ${method}(bytes8 c__${hash}) pure { ${abi} }\n`
: `\nfunction ${method}(bytes8 c__${hash}) pure {}\n`;
} }
/** /**
@ -97,7 +117,11 @@ class Injector {
_getTrueMethodDefinition(id){ _getTrueMethodDefinition(id){
const hash = web3Utils.keccak256(id).slice(2,10); const hash = web3Utils.keccak256(id).slice(2,10);
const method = this._getTrueMethodIdentifier(id); const method = this._getTrueMethodIdentifier(id);
return `function ${method}(bytes8 c__${hash}) internal pure returns (bool){ return true; }\n`; const abi = this._getAbiEncodeStatementVar(hash);
return (this.viaIR)
? `function ${method}(bytes8 c__${hash}) internal pure returns (bool){ ${abi} return true; }\n`
: `function ${method}(bytes8 c__${hash}) internal pure returns (bool){ return true; }\n`;
} }
/** /**
@ -110,7 +134,11 @@ class Injector {
_getFileScopeTrueMethodDefinition(id){ _getFileScopeTrueMethodDefinition(id){
const hash = web3Utils.keccak256(id).slice(2,10); const hash = web3Utils.keccak256(id).slice(2,10);
const method = this._getTrueMethodIdentifier(id); const method = this._getTrueMethodIdentifier(id);
return `function ${method}(bytes8 c__${hash}) pure returns (bool){ return true; }\n`; const abi = this._getAbiEncodeStatementVar(hash);
return (this.viaIR)
? `function ${method}(bytes8 c__${hash}) pure returns (bool){ ${abi} return true; }\n`
: `function ${method}(bytes8 c__${hash}) pure returns (bool){ return true; }\n`;
} }
/** /**
@ -122,7 +150,11 @@ class Injector {
_getFalseMethodDefinition(id){ _getFalseMethodDefinition(id){
const hash = web3Utils.keccak256(id).slice(2,10); const hash = web3Utils.keccak256(id).slice(2,10);
const method = this._getFalseMethodIdentifier(id); const method = this._getFalseMethodIdentifier(id);
return `function ${method}(bytes8 c__${hash}) internal pure returns (bool){ return false; }\n`; const abi = this._getAbiEncodeStatementVar(hash);
return (this.viaIR)
? `function ${method}(bytes8 c__${hash}) internal pure returns (bool){ ${abi} return false; }\n`
: `function ${method}(bytes8 c__${hash}) internal pure returns (bool){ return false; }\n`;
} }
/** /**
@ -135,7 +167,11 @@ class Injector {
_getFileScopedFalseMethodDefinition(id){ _getFileScopedFalseMethodDefinition(id){
const hash = web3Utils.keccak256(id).slice(2,10); const hash = web3Utils.keccak256(id).slice(2,10);
const method = this._getFalseMethodIdentifier(id); const method = this._getFalseMethodIdentifier(id);
return `function ${method}(bytes8 c__${hash}) pure returns (bool){ return false; }\n`; const abi = this._getAbiEncodeStatementVar(hash);
return (this.viaIR)
? `function ${method}(bytes8 c__${hash}) pure returns (bool){ ${abi} return false; }\n`
: `function ${method}(bytes8 c__${hash}) pure returns (bool){ return false; }\n`;
} }
_getModifierDefinitions(contractId, instrumentation){ _getModifierDefinitions(contractId, instrumentation){

@ -14,7 +14,7 @@ class Instrumenter {
constructor(config={}){ constructor(config={}){
this.instrumentationData = {}; this.instrumentationData = {};
this.injector = new Injector(); this.injector = new Injector(config.viaIR);
this.modifierWhitelist = config.modifierWhitelist || []; this.modifierWhitelist = config.modifierWhitelist || [];
this.enabled = { this.enabled = {
statements: (config.measureStatementCoverage === false) ? false : true, statements: (config.measureStatementCoverage === false) ? false : true,

@ -12,7 +12,10 @@
"scripts": { "scripts": {
"test:unit": "./scripts/unit.sh", "test:unit": "./scripts/unit.sh",
"test:integration": "./scripts/integration.sh", "test:integration": "./scripts/integration.sh",
"test:ci": "./scripts/ci.sh" "test:ci": "./scripts/ci.sh",
"test:uint:viaIR": "VIA_IR=true ./scripts/unit.sh",
"test:integration:viaIR": "VIA_IR=true ./scripts/integration.sh",
"test:ci:viaIR": "VIA_IR=true ./scripts/ci.sh"
}, },
"homepage": "https://github.com/sc-forks/solidity-coverage", "homepage": "https://github.com/sc-forks/solidity-coverage",
"repository": { "repository": {

@ -54,11 +54,14 @@ subtask(TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE).setAction(async (_,
} }
// Unset useLiteralContent due to solc metadata size restriction // Unset useLiteralContent due to solc metadata size restriction
settings.metadata.useLiteralContent = false; settings.metadata.useLiteralContent = false;
// Override optimizer settings for all compilers
settings.optimizer.enabled = false;
// This is fixes a stack too deep bug in ABIEncoderV2 // Beginning with v0.8.7, we let the optimizer run if viaIR is true and
// Experimental because not sure this works as expected across versions.... // instrument using `abi.encode(bytes8 covHash)`. Otherwise turn the optimizer off.
if (!settings.viaIR) settings.optimizer.enabled = false;
// This sometimes fixed a stack-too-deep bug in ABIEncoderV2 for coverage plugin versions up to 0.8.6
// Although issue should be fixed in 0.8.7, am leaving this option in because it may still be necessary
// to configure optimizer details in some cases.
if (configureYulOptimizer) { if (configureYulOptimizer) {
if (optimizerDetails === undefined) { if (optimizerDetails === undefined) {
settings.optimizer.details = { settings.optimizer.details = {

@ -36,6 +36,10 @@ function normalizeConfig(config, args={}){
? sources = path.join(config.paths.sources, args.sources) ? sources = path.join(config.paths.sources, args.sources)
: sources = config.paths.sources; : sources = config.paths.sources;
if (config.solidity && config.solidity.compilers.length) {
config.viaIR = isUsingViaIR(config.solidity);
}
config.workingDir = config.paths.root; config.workingDir = config.paths.root;
config.contractsDir = sources; config.contractsDir = sources;
config.testDir = config.paths.tests; config.testDir = config.paths.tests;
@ -55,6 +59,23 @@ function normalizeConfig(config, args={}){
return config; return config;
} }
function isUsingViaIR(solidity) {
for (compiler of solidity.compilers) {
if (compiler.settings && compiler.settings.viaIR) {
return true;
}
}
if (solidity.overrides) {
for (key of Object.keys(solidity.overrides)){
if (solidity.overrides[key].settings && solidity.overrides[key].settings.viaIR) {
return true;
}
}
}
return false;
}
async function setupHardhatNetwork(env, api, ui){ async function setupHardhatNetwork(env, api, ui){
const hardhatPackage = require('hardhat/package.json'); const hardhatPackage = require('hardhat/package.json');
const { createProvider } = require("hardhat/internal/core/providers/construction"); const { createProvider } = require("hardhat/internal/core/providers/construction");

@ -227,7 +227,9 @@ function loadSolcoverJS(config={}){
coverageConfig = {}; coverageConfig = {};
} }
// Truffle writes to coverage config // viaIR is eval'd in `nomiclab.utils.normalizeConfig`
coverageConfig.viaIR = config.viaIR;
coverageConfig.log = log; coverageConfig.log = log;
coverageConfig.cwd = config.workingDir; coverageConfig.cwd = config.workingDir;
coverageConfig.originalContractsDir = config.contractsDir; coverageConfig.originalContractsDir = config.contractsDir;

@ -1,6 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
SILENT=true node --max-old-space-size=4096 \ # Toggles optimizer on/off
VIAR_IR=$VIA_IR
# Minimize integration test output
SILENT=true
node --max-old-space-size=4096 \
./node_modules/.bin/nyc \ ./node_modules/.bin/nyc \
--reporter=lcov \ --reporter=lcov \
--exclude '**/sc_temp/**' \ --exclude '**/sc_temp/**' \

@ -1,5 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Toggles optimizer on/off
VIA_IR=$VIA_IR
node --max-old-space-size=4096 \ node --max-old-space-size=4096 \
./node_modules/.bin/nyc \ ./node_modules/.bin/nyc \
--exclude '**/sc_temp/**' \ --exclude '**/sc_temp/**' \

@ -1,5 +1,8 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Toggles optimizer on/off
VIAR_IR=$VIA_IR
node --max-old-space-size=4096 \ node --max-old-space-size=4096 \
./node_modules/.bin/nyc \ ./node_modules/.bin/nyc \
--exclude '**/sc_temp/**' \ --exclude '**/sc_temp/**' \

@ -8,6 +8,7 @@ set -o errexit
# Get rid of any caches # Get rid of any caches
sudo rm -rf node_modules sudo rm -rf node_modules
echo "NVM CURRENT >>>>>" && nvm current echo "NVM CURRENT >>>>>" && nvm current
nvm use 18
# Use PR env variables (for forks) or fallback on local if PR not available # Use PR env variables (for forks) or fallback on local if PR not available
SED_REGEX="s/git@github.com:/https:\/\/github.com\//" SED_REGEX="s/git@github.com:/https:\/\/github.com\//"

@ -348,6 +348,31 @@ describe('Hardhat Plugin: standard use cases', function() {
verify.lineCoverage(expected); verify.lineCoverage(expected);
}) })
it('detects viaIR when specified in config overrides only', async function(){
mock.installFullProject('overrides-viaIR');
mock.hardhatSetupEnv(this);
await this.env.run("coverage");
const expected = [
{
file: mock.pathToContract(hardhatConfig, 'ContractOverA2.sol'),
pct: 33.33
},
{
file: mock.pathToContract(hardhatConfig, 'ContractOverB2.sol'),
pct: 100,
},
{
file: mock.pathToContract(hardhatConfig, 'ContractOverC2.sol'),
pct: 100,
},
];
verify.lineCoverage(expected);
})
it('locates .coverage_contracts correctly when dir is subfolder', async function(){ it('locates .coverage_contracts correctly when dir is subfolder', async function(){
mock.installFullProject('contract-subfolders'); mock.installFullProject('contract-subfolders');
mock.hardhatSetupEnv(this); mock.hardhatSetupEnv(this);

@ -8,7 +8,13 @@ module.exports={
} }
}, },
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
paths: { paths: {
sources: './contracts/A' sources: './contracts/A'

@ -1,4 +1,4 @@
pragma solidity ^0.5.5; pragma solidity >=0.8.0 <0.9.0;
contract ContractA { contract ContractA {

@ -1,4 +1,4 @@
pragma solidity ^0.5.0; pragma solidity >=0.8.0 <0.9.0;
contract ContractB { contract ContractB {

@ -1,4 +1,4 @@
pragma solidity ^0.6.0; pragma solidity >=0.8.0 <0.9.0;
contract ContractC { contract ContractC {

@ -5,14 +5,20 @@ module.exports={
solidity: { solidity: {
compilers: [ compilers: [
{ {
version: "0.5.5" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
{ {
version: "0.5.7" version: "0.8.19"
}, },
// Make sure optimizer gets disabled // Make sure optimizer gets disabled
{ {
version: "0.6.7", version: "0.8.12",
settings: { settings: {
optimizer: { optimizer: {
enabled: true, enabled: true,
@ -23,11 +29,13 @@ module.exports={
], ],
overrides: { overrides: {
"contracts/ContractA.sol": { "contracts/ContractA.sol": {
version: "0.5.5", version: "0.8.24",
settings: { settings: {
optimizer: { optimizer: {
enabled: true, enabled: true,
runs: 200 runs: 200,
viaIR: process.env.VIA_IR === "true",
evmVersion: 'paris'
} }
} }
} }

@ -4,7 +4,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -4,7 +4,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -10,7 +10,13 @@ if (!process.env.ALCHEMY_TOKEN){
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
networks: { networks: {
hardhat: { hardhat: {

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports={ module.exports={
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -1,4 +1,4 @@
pragma solidity ^0.6.0; pragma solidity >=0.8.0 <0.9.0;
import "./ModifiersB.sol"; import "./ModifiersB.sol";

@ -1,4 +1,4 @@
pragma solidity ^0.6.0; pragma solidity >=0.8.0 <0.9.0;
contract ModifiersB { contract ModifiersB {

@ -1,4 +1,4 @@
pragma solidity ^0.6.0; pragma solidity >=0.8.0 <0.9.0;
import "./ModifiersB.sol"; import "./ModifiersB.sol";

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.6.7" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -8,7 +8,13 @@ module.exports={
} }
}, },
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -0,0 +1,4 @@
module.exports = {
"silent": false,
"istanbulReporter": [ "json-summary", "text"]
}

@ -0,0 +1,17 @@
pragma solidity >=0.8.0 <0.9.0;
contract ContractA {
uint x;
constructor() public {
}
function sendFn() public {
x = 5;
}
function callFn() public pure returns (uint){
uint y = 5;
return y;
}
}

@ -0,0 +1,17 @@
pragma solidity >=0.8.0 <0.9.0;
contract ContractB {
uint x;
constructor() public {
}
function sendFn() public {
x = 5;
}
function callFn() public pure returns (uint){
uint y = 5;
return y;
}
}

@ -0,0 +1,17 @@
pragma solidity >=0.8.0 <0.9.0;
contract ContractC {
uint x;
constructor() public {
}
function sendFn() public {
x = 5;
}
function callFn() public pure returns (uint){
uint y = 5;
return y;
}
}

@ -0,0 +1,29 @@
require("@nomiclabs/hardhat-truffle5");
require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports={
solidity: {
compilers: [
{
version: "0.8.17",
},
{
version: "0.8.19"
},
],
overrides: {
"contracts/ContractA.sol": {
version: "0.8.24",
settings: {
optimizer: {
enabled: true,
runs: 200,
viaIR: process.env.VIA_IR === "true",
evmVersion: 'paris'
}
}
}
}
},
logger: process.env.SILENT ? { log: () => {} } : console,
};

@ -0,0 +1,11 @@
const ContractA = artifacts.require("ContractA");
contract("contracta", function(accounts) {
let instance;
before(async () => instance = await ContractA.new())
it('sends', async function(){
await instance.sendFn();
});
});

@ -0,0 +1,15 @@
const ContractB = artifacts.require("ContractB");
contract("contractB", function(accounts) {
let instance;
before(async () => instance = await ContractB.new())
it('sends', async function(){
await instance.sendFn();
});
it('calls', async function(){
await instance.callFn();
})
});

@ -0,0 +1,20 @@
const ContractC = artifacts.require("ContractC");
contract("contractc", function(accounts) {
let instance;
before(async () => instance = await ContractC.new())
it('sends', async function(){
await instance.sendFn();
});
it('calls', async function(){
await instance.callFn();
})
it('sends', async function(){
await instance.sendFn();
});
});

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.21" version: "0.8.21",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.24",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -3,7 +3,13 @@ require(__dirname + "/../plugins/nomiclabs.plugin");
module.exports = { module.exports = {
solidity: { solidity: {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
}, },
logger: process.env.SILENT ? { log: () => {} } : console, logger: process.env.SILENT ? { log: () => {} } : console,
}; };

@ -51,8 +51,11 @@ describe('generic statements', () => {
util.report(info.solcOutput.errors); util.report(info.solcOutput.errors);
}); });
// FAILING WITH 0.8.x ... unskip when viaIR work is done it('should instrument without triggering stack-too-deep', () => {
it.skip('should instrument without triggering stack-too-deep', () => { // Only compiles if compiler.settings.viaIR = true
// Tests run with optimizer turned on/off to validate both instrumentation techniques
if (!process.env.VIA_IR) return;
const info = util.instrumentAndCompile('statements/stack-too-deep'); const info = util.instrumentAndCompile('statements/stack-too-deep');
util.report(info.solcOutput.errors); util.report(info.solcOutput.errors);
}); });

@ -114,7 +114,13 @@ function getDefaultHardhatConfig() {
const config = getDefaultNomicLabsConfig() const config = getDefaultNomicLabsConfig()
config.defaultNetwork = HARDHAT_NETWORK_NAME; config.defaultNetwork = HARDHAT_NETWORK_NAME;
config.solidity = { config.solidity = {
version: "0.8.17" version: "0.8.17",
settings: {
optimizer: {
enabled: true
},
viaIR: process.env.VIA_IR === "true"
}
} }
return config; return config;
} }

@ -61,7 +61,8 @@ function codeToCompilerInput(code) {
sources: { 'test.sol': { content: code } }, sources: { 'test.sol': { content: code } },
settings: { settings: {
outputSelection: {'*': { '*': [ '*' ] }}, outputSelection: {'*': { '*': [ '*' ] }},
evmVersion: "paris" evmVersion: "paris",
viaIR: process.env.VIA_IR === "true"
} }
}); });
} }
@ -89,7 +90,8 @@ function getDiffABIs(sourceName, testFile="test.sol", original="Old", current="N
// ============================ // ============================
// Instrumentation Correctness // Instrumentation Correctness
// ============================ // ============================
function instrumentAndCompile(sourceName, api={}) { function instrumentAndCompile(sourceName, api={ config: {} }) {
api.config.viaIR = process.env.VIA_IR === "true";
const contract = getCode(`${sourceName}.sol`) const contract = getCode(`${sourceName}.sol`)
const instrumenter = new Instrumenter(api.config); const instrumenter = new Instrumenter(api.config);
const instrumented = instrumenter.instrument(contract, filePath); const instrumented = instrumenter.instrument(contract, filePath);

Loading…
Cancel
Save