├── .circleci └── config.yml ├── .github └── dependabot.yaml ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── FUNDING.json ├── LICENSE ├── README.md ├── api.js ├── docs ├── advanced.md ├── api.md ├── faq.md └── matrix.md ├── lib ├── abi.js ├── api.js ├── collector.js ├── coverage.js ├── injector.js ├── instrumenter.js ├── parse.js ├── preprocessor.js ├── registrar.js ├── ui.js └── validator.js ├── package.json ├── plugins ├── bin.js ├── hardhat.plugin.js ├── nomiclabs.plugin.js └── resources │ ├── matrix.js │ ├── nomiclabs.ui.js │ ├── nomiclabs.utils.js │ ├── plugin.ui.js │ └── plugin.utils.js ├── scripts ├── ci.sh ├── integration.sh ├── nomiclabs.sh ├── unit.sh └── zeppelin.sh ├── test ├── integration │ ├── errors.js │ ├── flags.js │ └── standard.js ├── sources │ ├── generic │ │ ├── assets │ │ │ ├── SimpleError.sol │ │ │ └── asset.js │ │ ├── contracts │ │ │ └── .marker │ │ └── test │ │ │ └── .marker │ ├── js │ │ ├── account-one.js │ │ ├── account-zero.js │ │ ├── block-gas-limit.js │ │ ├── empty.js │ │ ├── inheritance.js │ │ ├── modified.js │ │ ├── only-call.js │ │ ├── oraclize.js │ │ ├── pureview.js │ │ ├── simple.js │ │ ├── testrpc-options.js │ │ ├── totallyPure.js │ │ ├── truffle-crash.js │ │ ├── truffle-test-fail.js │ │ └── wallet.js │ ├── projects │ │ ├── bad-solcoverjs │ │ │ ├── .solcover.js │ │ │ └── hardhat.config.js │ │ ├── contract-subfolders │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── A │ │ │ │ │ └── ContractA2.sol │ │ │ │ └── B │ │ │ │ │ └── ContractB2.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── contracta2.js │ │ ├── file-level-functions │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── FunctionA.sol │ │ │ │ ├── FunctionB.sol │ │ │ │ └── UsesFunctions.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── usesFunctions.js │ │ ├── hardhat-compile-config │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── ContractA1.sol │ │ │ │ ├── ContractB1.sol │ │ │ │ ├── ContractC1.sol │ │ │ │ └── ContractD1.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ ├── contracta1.js │ │ │ │ ├── contractb1.js │ │ │ │ ├── contractc1.js │ │ │ │ └── contractd1.js │ │ ├── hardhat-gas-reporter │ │ │ ├── contracts │ │ │ │ └── ContractA.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── test.js │ │ ├── hardhat-mine │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ └── Setter.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── testMine.js │ │ ├── hardhat-reset │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ └── ContractAReset.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── testReset.js │ │ ├── import-paths │ │ │ ├── .gitignore │ │ │ ├── .solcover.js │ │ │ ├── assets │ │ │ │ └── RelativePathImport.sol │ │ │ ├── contracts │ │ │ │ ├── OnlyUsesImports.sol │ │ │ │ └── UsesImports.sol │ │ │ ├── hardhat.config.js │ │ │ ├── node_modules │ │ │ │ └── package │ │ │ │ │ ├── AnotherImport.sol │ │ │ │ │ ├── NodeModulesImport.sol │ │ │ │ │ └── package.json │ │ │ └── test │ │ │ │ └── uses_imports.js │ │ ├── irMinimum │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ └── IRMinimum.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── test_irMinimum.js │ │ ├── libraries │ │ │ ├── contracts │ │ │ │ ├── CLibrary.sol │ │ │ │ ├── Migrations.sol │ │ │ │ ├── PureView.sol │ │ │ │ ├── UsesPure.sol │ │ │ │ └── _Interface.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── libraries.js │ │ ├── matrix │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── MatrixA.sol │ │ │ │ └── MatrixB.sol │ │ │ ├── expectedMochaOutput.json │ │ │ ├── expectedTestMatrixHardhat.json │ │ │ ├── expectedTestMatrixTruffle.json │ │ │ ├── hardhat.config.js │ │ │ ├── test │ │ │ │ ├── matrix_a.js │ │ │ │ └── matrix_a_b.js │ │ │ └── truffle-config.js │ │ ├── modifiers │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── ModifiersA.sol │ │ │ │ ├── ModifiersB.sol │ │ │ │ ├── ModifiersC.sol │ │ │ │ └── ModifiersD.sol │ │ │ ├── external │ │ │ │ ├── Context.sol │ │ │ │ └── Ownable.sol │ │ │ ├── hardhat.config.js │ │ │ ├── test │ │ │ │ └── modifiers.js │ │ │ └── truffle-config.js │ │ ├── multiple-suites │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── ContractA.sol │ │ │ │ ├── ContractB.sol │ │ │ │ └── ContractC.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ ├── contracta.js │ │ │ │ ├── contractb.js │ │ │ │ └── contractc.js │ │ ├── no-sources │ │ │ └── hardhat.config.js │ │ ├── overrides-viaIR │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── ContractOverA2.sol │ │ │ │ ├── ContractOverB2.sol │ │ │ │ └── ContractOverC2.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ ├── contract_over_a2.js │ │ │ │ ├── contract_over_b2.js │ │ │ │ └── contract_over_c2.js │ │ ├── parallel │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ └── ContractA.sol │ │ │ └── hardhat.config.js │ │ ├── skipping │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── ContractA.sol │ │ │ │ └── skipped-folder │ │ │ │ │ └── ContractB.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── contract.js │ │ ├── solc-8 │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── Abstract_solc8.sol │ │ │ │ ├── Contract_solc8.sol │ │ │ │ └── Library_solc8.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── test_solc8.js │ │ ├── task-hooks │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ └── Hooks.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ └── hooks.js │ │ ├── ternary-and-logical-or │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── Contract_OR.sol │ │ │ │ └── Contract_ternary.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ ├── test_or.js │ │ │ │ └── test_ternary.js │ │ ├── test-files │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── ContractA.sol │ │ │ │ ├── ContractB.sol │ │ │ │ ├── ContractC.sol │ │ │ │ └── otherContracts │ │ │ │ │ └── OtherContractA.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ ├── globby_b.js │ │ │ │ ├── globby_c.js │ │ │ │ ├── other_contract_a.js │ │ │ │ └── specific_a.js │ │ ├── tests-folder │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ │ ├── ContractA.sol │ │ │ │ ├── ContractB.sol │ │ │ │ └── ContractC.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ │ ├── contracta.js │ │ │ │ └── folder │ │ │ │ ├── contractb.js │ │ │ │ └── contractc.js │ │ └── viem │ │ │ ├── .solcover.js │ │ │ ├── contracts │ │ │ └── Lock.sol │ │ │ ├── hardhat.config.js │ │ │ └── test │ │ │ └── lock.js │ └── solidity │ │ ├── contracts │ │ ├── app │ │ │ ├── Empty.sol │ │ │ ├── Events.sol │ │ │ ├── Expensive.sol │ │ │ ├── Migrations.sol │ │ │ ├── Modified.sol │ │ │ ├── OnlyCall.sol │ │ │ ├── Oraclize.sol │ │ │ ├── Owned.sol │ │ │ ├── Proxy.sol │ │ │ ├── Simple.sol │ │ │ ├── SimpleError.sol │ │ │ ├── Unparseable.sol │ │ │ ├── Wallet.sol │ │ │ └── auction.vy │ │ ├── assembly │ │ │ ├── if.sol │ │ │ └── spaces-in-function.sol │ │ ├── assert │ │ │ ├── Assert.sol │ │ │ ├── Require-fn-reason.sol │ │ │ ├── Require-fn.sol │ │ │ └── RequireMultiline.sol │ │ ├── comments │ │ │ ├── postContractComment.sol │ │ │ ├── postFunctionDeclarationComment.sol │ │ │ ├── postIfStatementComment.sol │ │ │ └── postLineComment.sol │ │ ├── conditional │ │ │ ├── and-condition.sol │ │ │ ├── chained-multiline.sol │ │ │ ├── chained-singleline.sol │ │ │ ├── chained-true.sol │ │ │ ├── chained-with-parens.sol │ │ │ ├── declarative-exp-assignment-alternate.sol │ │ │ ├── identifier-assignment-alternate.sol │ │ │ ├── mapping-assignment.sol │ │ │ ├── multiline-alternate.sol │ │ │ ├── multiline-consequent.sol │ │ │ ├── or-always-false-condition.sol │ │ │ ├── or-condition.sol │ │ │ ├── sameline-alternate.sol │ │ │ ├── sameline-consequent.sol │ │ │ ├── ternary-with-unbracketed-else.sol │ │ │ ├── unbracketed-condition.sol │ │ │ ├── unbracketed-or-condition.sol │ │ │ └── variable-decl-assignment-alternate.sol │ │ ├── diff │ │ │ ├── addition.sol │ │ │ ├── events.sol │ │ │ ├── no-change.sol │ │ │ ├── param-change.sol │ │ │ ├── removal.sol │ │ │ ├── reorder.sol │ │ │ ├── return-sig.sol │ │ │ └── state-mod-change.sol │ │ ├── expressions │ │ │ ├── new-expression.sol │ │ │ └── single-binary-expression.sol │ │ ├── function │ │ │ ├── abstract.sol │ │ │ ├── empty-body.sol │ │ │ ├── function-call.sol │ │ │ ├── function.sol │ │ │ ├── modifier.sol │ │ │ └── multiple.sol │ │ ├── if │ │ │ ├── else-if-unbracketed-multi.sol │ │ │ ├── else-if-without-brackets.sol │ │ │ ├── else-with-brackets.sol │ │ │ ├── else-without-brackets.sol │ │ │ ├── if-else-no-brackets.sol │ │ │ ├── if-elseif-else.sol │ │ │ ├── if-no-brackets-multiline.sol │ │ │ ├── if-no-brackets.sol │ │ │ ├── if-with-brackets-multiline.sol │ │ │ ├── if-with-brackets.sol │ │ │ └── nested-if-missing-else.sol │ │ ├── loops │ │ │ ├── for-no-brackets.sol │ │ │ ├── for-with-brackets.sol │ │ │ ├── while-no-brackets.sol │ │ │ └── while-with-brackets.sol │ │ ├── modifiers │ │ │ ├── both-branches.sol │ │ │ ├── constructor.sol │ │ │ ├── duplicate-mods-same-fn.sol │ │ │ ├── listed-modifiers.sol │ │ │ ├── multiple-fns-same-mod.sol │ │ │ ├── multiple-mods-same-fn.sol │ │ │ ├── override-function.sol │ │ │ ├── postconditions.sol │ │ │ ├── reverting-fn.sol │ │ │ ├── reverting-neighbor.sol │ │ │ ├── same-contract-fail.sol │ │ │ └── same-contract-pass.sol │ │ ├── or │ │ │ ├── and-or-brackets.sol │ │ │ ├── and-or.sol │ │ │ ├── bzx-or.sol │ │ │ ├── if-or.sol │ │ │ ├── multi-or.sol │ │ │ ├── require-multiline-or.sol │ │ │ ├── require-or.sol │ │ │ ├── return-or.sol │ │ │ └── while-or.sol │ │ ├── return │ │ │ ├── empty-return.sol │ │ │ ├── return.sol │ │ │ └── ternary-return.sol │ │ ├── statements │ │ │ ├── emit-coverage.sol │ │ │ ├── emit-instrument.sol │ │ │ ├── empty-contract-ala-melonport.sol │ │ │ ├── empty-contract-body.sol │ │ │ ├── fn-argument-multiline.sol │ │ │ ├── fn-argument.sol │ │ │ ├── fn-struct.sol │ │ │ ├── interface.sol │ │ │ ├── interpolation.sol │ │ │ ├── library.sol │ │ │ ├── multi-contract-flattened.sol │ │ │ ├── multiple.sol │ │ │ ├── post-close-brace.sol │ │ │ ├── require.sol │ │ │ ├── single.sol │ │ │ ├── stack-too-deep.sol │ │ │ ├── tuple.sol │ │ │ ├── type-keyword.sol │ │ │ └── unary.sol │ │ └── try │ │ │ ├── try-catch-empty-blocks.sol │ │ │ ├── try-error-block.sol │ │ │ ├── try-multi-block.sol │ │ │ ├── try-panic-block.sol │ │ │ └── try-revert-block.sol │ │ └── external │ │ ├── CLibrary.sol │ │ ├── Face.sol │ │ └── PureView.sol ├── units │ ├── api.js │ ├── assembly.js │ ├── assert.js │ ├── comments.js │ ├── conditional.js │ ├── diff.js │ ├── expressions.js │ ├── function.js │ ├── if.js │ ├── loops.js │ ├── modifiers.js │ ├── options.js │ ├── or.js │ ├── statements.js │ ├── try.js │ └── validator.js └── util │ ├── integration.js │ ├── mochaRootHook.js │ ├── util.js │ └── verifiers.js ├── utils.js └── yarn.lock /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | win: circleci/windows@2.2.0 5 | 6 | # Necessary for running in machine mode, 7 | # which is necessary to execute the E2E scripts 8 | step_install_nvm: &step_install_nvm 9 | run: 10 | name: "Install nvm for machine" 11 | command: | 12 | set +e 13 | export NVM_DIR="/opt/circleci/.nvm" 14 | [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" 15 | nvm install v18 16 | echo 'export NVM_DIR="/opt/circleci/.nvm"' >> $BASH_ENV 17 | echo "[ -s \"$NVM_DIR/nvm.sh\" ] && . \"$NVM_DIR/nvm.sh\"" >> $BASH_ENV 18 | 19 | step_install_foundry: &step_install_foundry 20 | run: 21 | name: "Install Foundry" 22 | working_directory: ~/ 23 | environment: 24 | SHELL: /bin/bash 25 | command: |- 26 | export PATH="$PATH:$HOME/.foundry/bin" 27 | echo 'export PATH=$PATH:$HOME/.foundry/bin' >> $BASH_ENV 28 | curl -L https://foundry.paradigm.xyz | bash 29 | foundryup 30 | 31 | jobs: 32 | unit-test: 33 | docker: 34 | - image: cimg/node:20.11.0 35 | steps: 36 | - checkout 37 | - run: 38 | name: Delete any old node_modules 39 | command: | 40 | rm -rf node_modules/ 41 | - run: 42 | name: Install dependencies 43 | command: | 44 | yarn 45 | - run: 46 | name: Tests ( optimizer.enabled=false ) 47 | command: | 48 | npm run test:ci 49 | - run: 50 | name: Tests ( viaIR=true ) 51 | command: | 52 | npm run test:ci:viaIR 53 | - run: 54 | name: Upload coverage 55 | command: | 56 | bash <(curl -s https://codecov.io/bash) 57 | e2e-zeppelin: 58 | machine: 59 | image: ubuntu-2204:2024.01.1 60 | resource_class: large 61 | environment: 62 | NODE_OPTIONS: --max_old_space_size=8192 63 | steps: 64 | - checkout 65 | - <<: *step_install_nvm 66 | - run: 67 | name: Zeppelin E2E 68 | command: | 69 | ./scripts/zeppelin.sh 70 | e2e-nomiclabs: 71 | machine: true 72 | steps: 73 | - checkout 74 | - <<: *step_install_nvm 75 | - <<: *step_install_foundry 76 | - run: 77 | name: Hardhat E2E 78 | command: | 79 | ./scripts/nomiclabs.sh 80 | workflows: 81 | version: 2 82 | build: 83 | jobs: 84 | - unit-test 85 | - e2e-zeppelin 86 | - e2e-nomiclabs 87 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 2 | --- 3 | version: 2 4 | updates: 5 | - package-ecosystem: npm 6 | directory: / 7 | open-pull-requests-limit: 5 8 | schedule: 9 | interval: daily 10 | time: "9:00" 11 | timezone: MST 12 | commit-message: 13 | prefix: build 14 | include: scope 15 | assignees: 16 | - cgewecke 17 | labels: 18 | - build 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage.json 2 | coverage/ 3 | node_modules/ 4 | .changelog 5 | .DS_Store 6 | test/artifacts 7 | test/cache 8 | temp 9 | .nyc_output/ 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | .circleci/ 3 | docs/ 4 | .nyc_output/ 5 | -------------------------------------------------------------------------------- /FUNDING.json: -------------------------------------------------------------------------------- 1 | { 2 | "drips": { 3 | "ethereum": { 4 | "ownedBy": "0xaA4c632684180bf781108c84E7a294B483D12053" 5 | } 6 | }, 7 | "opRetro": { 8 | "projectId": "0x2bb095e1f297c71da8bd4ee15097abad3b99e299fe14cd6aa704df3f36d0ae22" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Alex Rea 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /api.js: -------------------------------------------------------------------------------- 1 | // For require('solidity-coverage/api'); 2 | const api = require('./lib/api'); 3 | 4 | module.exports = api; 5 | -------------------------------------------------------------------------------- /lib/abi.js: -------------------------------------------------------------------------------- 1 | const ethersABI = require("@ethersproject/abi"); 2 | const difflib = require('difflib'); 3 | 4 | class AbiUtils { 5 | 6 | diff(orig={}, cur={}){ 7 | let plus = 0; 8 | let minus = 0; 9 | 10 | const unifiedDiff = difflib.unifiedDiff( 11 | orig.humanReadableAbiList, 12 | cur.humanReadableAbiList, 13 | { 14 | fromfile: orig.contractName, 15 | tofile: cur.contractName, 16 | fromfiledate: `sha: ${orig.sha}`, 17 | tofiledate: `sha: ${cur.sha}`, 18 | lineterm: '' 19 | } 20 | ); 21 | 22 | // Count changes (unified diff always has a plus & minus in header); 23 | if (unifiedDiff.length){ 24 | plus = -1; 25 | minus = -1; 26 | } 27 | 28 | unifiedDiff.forEach(line => { 29 | if (line[0] === `+`) plus++; 30 | if (line[0] === `-`) minus++; 31 | }) 32 | 33 | return { 34 | plus, 35 | minus, 36 | unifiedDiff 37 | } 38 | } 39 | 40 | toHumanReadableFunctions(contract){ 41 | const human = []; 42 | const ethersOutput = new ethersABI.Interface(contract.abi).functions; 43 | const signatures = Object.keys(ethersOutput); 44 | 45 | for (const sig of signatures){ 46 | const method = ethersOutput[sig]; 47 | let returns = ''; 48 | 49 | method.outputs.forEach(output => { 50 | (returns.length) 51 | ? returns += `, ${output.type}` 52 | : returns += output.type; 53 | }); 54 | 55 | let readable = `${method.type} ${sig} ${method.stateMutability}`; 56 | 57 | if (returns.length){ 58 | readable += ` returns (${returns})` 59 | } 60 | 61 | human.push(readable); 62 | } 63 | 64 | return human; 65 | } 66 | 67 | toHumanReadableEvents(contract){ 68 | const human = []; 69 | const ethersOutput = new ethersABI.Interface(contract.abi).events; 70 | const signatures = Object.keys(ethersOutput); 71 | 72 | for (const sig of signatures){ 73 | const method = ethersOutput[sig]; 74 | const readable = `${ethersOutput[sig].type} ${sig}`; 75 | human.push(readable); 76 | } 77 | 78 | return human; 79 | } 80 | 81 | generateHumanReadableAbiList(_artifacts, sha){ 82 | const list = []; 83 | if (_artifacts.length){ 84 | for (const item of _artifacts){ 85 | const fns = this.toHumanReadableFunctions(item); 86 | const evts = this.toHumanReadableEvents(item); 87 | const all = fns.concat(evts); 88 | list.push({ 89 | contractName: item.contractName, 90 | sha: sha, 91 | humanReadableAbiList: all 92 | }) 93 | } 94 | } 95 | return list; 96 | } 97 | } 98 | 99 | module.exports = AbiUtils; -------------------------------------------------------------------------------- /lib/collector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Writes data from the VM step to the in-memory 3 | * coverage map constructed by the Instrumenter. 4 | */ 5 | class DataCollector { 6 | constructor(instrumentationData={}, viaIR){ 7 | this.instrumentationData = instrumentationData; 8 | 9 | this.validOpcodes = this._getOpcodes(viaIR); 10 | this.lastHash = null; 11 | this.viaIR = viaIR; 12 | this.pcZeroCounter = 0; 13 | this.lastPcZeroCount = 0; 14 | } 15 | 16 | /** 17 | * VM step event handler. Detects instrumentation hashes when they are pushed to the 18 | * top of the stack. This runs millions of times - trying to keep it fast. 19 | * @param {Object} info vm step info 20 | */ 21 | step(info){ 22 | if (info.pc === 0) this.pcZeroCounter++; 23 | 24 | try { 25 | if (this.validOpcodes[info.opcode.name] && info.stack.length > 0){ 26 | const idx = info.stack.length - 1; 27 | let hash = '0x' + info.stack[idx].toString(16); 28 | this._registerHash(hash); 29 | } 30 | } catch (err) { /*Ignore*/ }; 31 | } 32 | 33 | /** 34 | * Normalizes has string and marks hit. 35 | * @param {String} hash bytes32 hash 36 | */ 37 | _registerHash(hash){ 38 | hash = this._normalizeHash(hash); 39 | 40 | if(this.instrumentationData[hash]){ 41 | // abi.encode (used to circumvent viaIR) sometimes puts the hash on the stack twice 42 | // We should only skip duplicate hashes *within* a transaction (see issue #863) 43 | if (this.lastHash !== hash || this.lastPcZeroCount !== this.pcZeroCounter) { 44 | this.lastHash = hash; 45 | this.lastPcZeroCount = this.pcZeroCounter; 46 | this.instrumentationData[hash].hits++ 47 | } 48 | return; 49 | } 50 | } 51 | 52 | /** 53 | * Left-pads zero prefixed bytes8 hashes to length 18. The '11' in the 54 | * comparison below is arbitrary. It provides a margin for recurring zeros 55 | * but prevents left-padding shorter irrelevant hashes 56 | * 57 | * @param {String} hash data hash from evm stack. 58 | * @return {String} 0x prefixed hash of length 18. 59 | */ 60 | _normalizeHash(hash){ 61 | // viaIR sometimes right-pads the hashes out to 32 bytes 62 | // but it doesn't preserve leading zeroes when it does this 63 | if (this.viaIR && hash.length >= 18) { 64 | hash = hash.slice(0,18); 65 | 66 | // Detect and recover from viaIR mangled hashes by left-padding single `0` 67 | if(!this.instrumentationData[hash]) { 68 | hash = hash.slice(2); 69 | hash = '0' + hash; 70 | hash = hash.slice(0,16); 71 | hash = '0x' + hash; 72 | } 73 | 74 | } else if (hash.length < 18 && hash.length > 11){ 75 | hash = hash.slice(2); 76 | while(hash.length < 16) hash = '0' + hash; 77 | hash = '0x' + hash 78 | } 79 | return hash; 80 | } 81 | 82 | /** 83 | * Generates a list of all the opcodes to inspect for instrumentation hashes 84 | * When viaIR is true, it includes all DUPs and PUSHs, so things are a little slower. 85 | * @param {boolean} viaIR 86 | */ 87 | _getOpcodes(viaIR) { 88 | let opcodes = { 89 | "PUSH1": true 90 | }; 91 | 92 | if (!viaIR) return opcodes; 93 | 94 | for (let i = 2; i <= 32; i++) { 95 | const key = "PUSH" + i; 96 | opcodes[key] = viaIR; 97 | }; 98 | 99 | for (let i = 1; i <= 16; i++ ) { 100 | const key = "DUP" + i; 101 | opcodes[key] = viaIR; 102 | } 103 | 104 | for (let i = 1; i <= 16; i++ ) { 105 | const key = "SWAP" + i; 106 | opcodes[key] = viaIR; 107 | } 108 | 109 | return opcodes; 110 | } 111 | 112 | /** 113 | * Unit test helper 114 | * @param {Object} data Instrumenter.instrumentationData 115 | */ 116 | _setInstrumentationData(data){ 117 | this.instrumentationData = data; 118 | } 119 | } 120 | 121 | module.exports = DataCollector; 122 | -------------------------------------------------------------------------------- /lib/coverage.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Converts instrumentation data accumulated a the vm steps to an instanbul spec coverage object. 3 | * @type {Coverage} 4 | */ 5 | 6 | const util = require('util'); 7 | 8 | class Coverage { 9 | 10 | constructor() { 11 | this.data = {}; 12 | this.requireData = {}; 13 | } 14 | 15 | /** 16 | * Initializes an entry in the coverage map for an instrumented contract. Tracks by 17 | * its canonical contract path, e.g. *not* by its location in the temp folder. 18 | * @param {Object} info 'info = instrumenter.instrument(contract, fileName, true)' 19 | * @param {String} contractPath canonical path to contract file 20 | */ 21 | 22 | addContract(info, contractPath) { 23 | this.data[contractPath] = { 24 | l: {}, 25 | path: contractPath, 26 | s: {}, 27 | b: {}, 28 | f: {}, 29 | fnMap: {}, 30 | statementMap: {}, 31 | branchMap: {}, 32 | }; 33 | this.requireData[contractPath] = { }; 34 | 35 | info.runnableLines.forEach((item, idx) => { 36 | this.data[contractPath].l[info.runnableLines[idx]] = 0; 37 | }); 38 | 39 | this.data[contractPath].fnMap = info.fnMap; 40 | for (let x = 1; x <= Object.keys(info.fnMap).length; x++) { 41 | this.data[contractPath].f[x] = 0; 42 | } 43 | 44 | this.data[contractPath].branchMap = info.branchMap; 45 | for (let x = 1; x <= Object.keys(info.branchMap).length; x++) { 46 | this.data[contractPath].b[x] = [0, 0]; 47 | this.requireData[contractPath][x] = { 48 | preEvents: 0, 49 | postEvents: 0, 50 | }; 51 | } 52 | 53 | this.data[contractPath].statementMap = info.statementMap; 54 | for (let x = 1; x <= Object.keys(info.statementMap).length; x++) { 55 | this.data[contractPath].s[x] = 0; 56 | } 57 | } 58 | 59 | /** 60 | * Populates an empty coverage map with values derived from a hash map of 61 | * data collected as the instrumented contracts are tested 62 | * @param {Object} map of collected instrumentation data 63 | * @return {Object} coverage map. 64 | */ 65 | generate(collectedData) { 66 | const hashes = Object.keys(collectedData); 67 | 68 | for (let hash of hashes){ 69 | const data = collectedData[hash]; 70 | const contractPath = collectedData[hash].contractPath; 71 | const id = collectedData[hash].id; 72 | 73 | // NB: Any branch using the injected fn which returns boolean will have artificially 74 | // doubled hits (because of something internal to Solidity about how the stack is managed) 75 | const hits = collectedData[hash].hits; 76 | 77 | switch(collectedData[hash].type){ 78 | case 'line': this.data[contractPath].l[id] = hits; break; 79 | case 'function': this.data[contractPath].f[id] = hits; break; 80 | case 'statement': this.data[contractPath].s[id] = hits; break; 81 | case 'branch': this.data[contractPath].b[id][data.locationIdx] = hits; break; 82 | case 'and-true': this.data[contractPath].b[id][data.locationIdx] = hits; break; 83 | case 'or-false': this.data[contractPath].b[id][data.locationIdx] = hits; break; 84 | case 'requirePre': this.requireData[contractPath][id].preEvents = hits; break; 85 | case 'requirePost': this.requireData[contractPath][id].postEvents = hits; break; 86 | } 87 | } 88 | 89 | // Finally, interpret the assert pre/post events 90 | const contractPaths = Object.keys(this.requireData); 91 | 92 | for (let contractPath of contractPaths){ 93 | const contract = this.data[contractPath]; 94 | 95 | for (let i = 1; i <= Object.keys(contract.b).length; i++) { 96 | const branch = this.requireData[contractPath][i]; 97 | 98 | // Was it an assert branch? 99 | if (branch && branch.preEvents > 0){ 100 | this.data[contractPath].b[i] = [ 101 | branch.postEvents, 102 | branch.preEvents - branch.postEvents 103 | ] 104 | } 105 | } 106 | } 107 | 108 | return Object.assign({}, this.data); 109 | } 110 | }; 111 | 112 | module.exports = Coverage; 113 | -------------------------------------------------------------------------------- /lib/preprocessor.js: -------------------------------------------------------------------------------- 1 | const SolidityParser = require('@solidity-parser/parser'); 2 | 3 | const crRegex = /[\r\n ]+$/g; 4 | const OPEN = '{'; 5 | const CLOSE = '}'; 6 | 7 | /** 8 | * Inserts an open or close brace e.g. `{` or `}` at specified position in solidity source 9 | * 10 | * @param {String} contract solidity source 11 | * @param {Object} item AST node to bracket 12 | * @param {Number} offset tracks the number of previously inserted braces 13 | * @return {String} contract 14 | */ 15 | function insertBrace(contract, item, offset) { 16 | return contract.slice(0,item.pos + offset) + item.type + contract.slice(item.pos + offset) 17 | } 18 | 19 | /** 20 | * Locates unbracketed singleton statements attached to if, else, for and while statements 21 | * and brackets them. Instrumenter needs to inject events at these locations and having 22 | * them pre-bracketed simplifies the process. 23 | * 24 | * @param {String} contract solidity source code 25 | * @return {String} modified solidity source code 26 | */ 27 | function preprocess(contract) { 28 | 29 | try { 30 | const ast = SolidityParser.parse(contract, { range: true }); 31 | insertions = []; 32 | 33 | SolidityParser.visit(ast, { 34 | IfStatement: function(node) { 35 | if (node.trueBody.type !== 'Block') { 36 | insertions.push({type: OPEN, pos: node.trueBody.range[0]}); 37 | insertions.push({type: CLOSE, pos: node.trueBody.range[1] + 1}); 38 | } 39 | if ( node.falseBody && node.falseBody.type !== 'Block' ) { 40 | insertions.push({type: OPEN, pos: node.falseBody.range[0]}); 41 | insertions.push({type: CLOSE, pos: node.falseBody.range[1] + 1}); 42 | } 43 | }, 44 | ForStatement: function(node){ 45 | if (node.body.type !== 'Block'){ 46 | insertions.push({type: OPEN, pos: node.body.range[0]}); 47 | insertions.push({type: CLOSE, pos: node.body.range[1] + 1}); 48 | } 49 | }, 50 | WhileStatement: function(node){ 51 | if (node.body.type !== 'Block'){ 52 | insertions.push({type: OPEN, pos: node.body.range[0]}); 53 | insertions.push({type: CLOSE, pos: node.body.range[1] + 1}); 54 | } 55 | } 56 | }) 57 | 58 | // Sort the insertion points. 59 | insertions.sort((a,b) => a.pos - b.pos); 60 | insertions.forEach((item, idx) => contract = insertBrace(contract, item, idx)); 61 | 62 | } catch (err) { 63 | contract = err; 64 | } 65 | return contract; 66 | }; 67 | 68 | 69 | module.exports = preprocess; 70 | -------------------------------------------------------------------------------- /lib/ui.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | const emoji = require('node-emoji'); 3 | 4 | /** 5 | * Coverage tool output formatters. These classes support any the logging solidity-coverage API 6 | * (or plugins which consume it) do on their own behalf. NB, most output is generated by the host 7 | * dev stack (ex: the hardhat compile command, or istanbul). 8 | */ 9 | class UI { 10 | constructor(log){ 11 | this.log = log || console.log; 12 | this.chalk = chalk; 13 | } 14 | 15 | /** 16 | * Writes a formatted message 17 | * @param {String} kind message selector 18 | * @param {String[]} args info to inject into template 19 | */ 20 | report(kind, args=[]){} 21 | 22 | /** 23 | * Returns a formatted message. Useful for error messages. 24 | * @param {String} kind message selector 25 | * @param {String[]} args info to inject into template 26 | * @return {String} message 27 | */ 28 | generate(kind, args=[]){} 29 | 30 | _write(msg){ 31 | this.log(this._format(msg)) 32 | } 33 | 34 | _format(msg){ 35 | return emoji.emojify(msg) 36 | } 37 | } 38 | 39 | /** 40 | * UI for solidity-coverage/lib/app.js 41 | */ 42 | class AppUI extends UI { 43 | constructor(log){ 44 | super(log); 45 | } 46 | 47 | /** 48 | * Writes a formatted message via log 49 | * @param {String} kind message selector 50 | * @param {String[]} args info to inject into template 51 | */ 52 | report(kind, args=[]){ 53 | const c = this.chalk; 54 | const ct = c.bold.green('>'); 55 | const ds = c.bold.yellow('>'); 56 | const w = ":warning:"; 57 | 58 | const kinds = { 59 | 60 | 'instr-start': `\n${c.bold('Instrumenting for coverage...')}` + 61 | `\n${c.bold('=============================')}\n`, 62 | 63 | 'instr-item': `${ct} ${args[0]}`, 64 | 65 | 'istanbul': `${ct} ${c.grey('Istanbul reports written to')} ./coverage/ ` + 66 | `${c.grey('and')} ./coverage.json`, 67 | 68 | 'command': `\n${w} ${c.red.bold('solidity-coverage >= 0.7.0 is no longer a shell command.')} ${w}\n` + 69 | `${c.bold('=============================================================')}\n\n` + 70 | `Instead, you should use the plugin produced for your development stack\n` + 71 | `(like Hardhat) or design a custom workflow using the package API\n\n` + 72 | `> See https://github.com/sc-forks/solidity-coverage for help with configuration.\n\n` + 73 | `${c.green.bold('Thanks! - sc-forks')}\n`, 74 | }; 75 | 76 | this._write(kinds[kind]); 77 | } 78 | 79 | /** 80 | * Returns a formatted message. Useful for error message. 81 | * @param {String} kind message selector 82 | * @param {String[]} args info to inject into template 83 | * @return {String} message 84 | */ 85 | generate(kind, args=[]){ 86 | const c = this.chalk; 87 | 88 | const kinds = { 89 | 'config-fail':`${c.red('A config option (.solcover.js) is incorrectly formatted: ')}` + 90 | `${c.red(args[0])}.`, 91 | 92 | 'instr-fail': `${c.red('Could not instrument:')} ${args[0]}. ` + 93 | `${c.red('(Please verify solc can compile this file without errors.) ')}`, 94 | 95 | 'istanbul-fail': `${c.red('Istanbul coverage reports could not be generated. ')}`, 96 | 97 | 'sources-fail': `${c.red('Cannot locate expected contract sources folder: ')} ${args[0]}`, 98 | } 99 | 100 | return this._format(kinds[kind]) 101 | } 102 | } 103 | 104 | module.exports = { 105 | AppUI: AppUI, 106 | UI: UI 107 | }; 108 | -------------------------------------------------------------------------------- /lib/validator.js: -------------------------------------------------------------------------------- 1 | const Validator = require('jsonschema').Validator; 2 | const AppUI = require('./ui').AppUI; 3 | const util = require('util') 4 | 5 | Validator.prototype.customFormats.isFunction = function(input) { 6 | return typeof input === "function" 7 | }; 8 | 9 | const configSchema = { 10 | id: "/solcoverjs", 11 | type: "object", 12 | properties: { 13 | 14 | client: {type: "object"}, 15 | cwd: {type: "string"}, 16 | host: {type: "string"}, 17 | abiOutputPath: {type: "string"}, 18 | matrixOutputPath: {type: "string"}, 19 | matrixReporterPath: {type: "string"}, 20 | port: {type: "number"}, 21 | providerOptions: {type: "object"}, 22 | silent: {type: "boolean"}, 23 | autoLaunchServer: {type: "boolean"}, 24 | istanbulFolder: {type: "string"}, 25 | measureStatementCoverage: {type: "boolean"}, 26 | measureFunctionCoverage: {type: "boolean"}, 27 | measureModifierCoverage: {type: "boolean"}, 28 | measureLineCoverage: {type: "boolean"}, 29 | measureBranchCoverage: {type: "boolean"}, 30 | 31 | // Hooks: 32 | onServerReady: {type: "function", format: "isFunction"}, 33 | onCompileComplete: {type: "function", format: "isFunction"}, 34 | onTestComplete: {type: "function", format: "isFunction"}, 35 | onIstanbulComplete: {type: "function", format: "isFunction"}, 36 | 37 | // Arrays 38 | skipFiles: { 39 | type: "array", 40 | items: {type: "string"} 41 | }, 42 | 43 | istanbulReporter: { 44 | type: "array", 45 | items: {type: "string"} 46 | }, 47 | 48 | modifierWhitelist: { 49 | type: "array", 50 | items: {type: "string"} 51 | } 52 | }, 53 | }; 54 | 55 | class ConfigValidator { 56 | constructor(){ 57 | this.validator = new Validator(); 58 | this.validator.addSchema(configSchema); 59 | this.ui = new AppUI(); 60 | } 61 | 62 | validate(config){ 63 | let result = this.validator.validate(config, configSchema); 64 | 65 | if (result.errors.length){ 66 | let msg; 67 | const option = `"${result.errors[0].property.replace('instance.', '')}"`; 68 | 69 | (result.errors[0].argument === 'isFunction') 70 | ? msg = `${option} is not a function` 71 | : msg = `${option} ${result.errors[0].message}`; 72 | 73 | throw new Error(this.ui.generate('config-fail', [msg])); 74 | } 75 | 76 | return true; 77 | } 78 | } 79 | 80 | module.exports = ConfigValidator; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "solidity-coverage", 3 | "version": "0.8.16", 4 | "description": "Code coverage for Solidity testing", 5 | "main": "plugins/nomiclabs.plugin.js", 6 | "bin": { 7 | "solidity-coverage": "./plugins/bin.js" 8 | }, 9 | "directories": { 10 | "test": "test" 11 | }, 12 | "scripts": { 13 | "test:unit": "./scripts/unit.sh", 14 | "test:integration": "./scripts/integration.sh", 15 | "test:ci": "./scripts/ci.sh", 16 | "test:unit:viaIR": "VIA_IR=true ./scripts/unit.sh", 17 | "test:integration:viaIR": "VIA_IR=true ./scripts/integration.sh", 18 | "test:ci:viaIR": "VIA_IR=true ./scripts/ci.sh" 19 | }, 20 | "homepage": "https://github.com/sc-forks/solidity-coverage", 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/sc-forks/solidity-coverage.git" 24 | }, 25 | "author": "", 26 | "license": "ISC", 27 | "dependencies": { 28 | "@ethersproject/abi": "^5.0.9", 29 | "@solidity-parser/parser": "^0.20.1", 30 | "chalk": "^2.4.2", 31 | "death": "^1.1.0", 32 | "difflib": "^0.2.4", 33 | "fs-extra": "^8.1.0", 34 | "ghost-testrpc": "^0.0.2", 35 | "global-modules": "^2.0.0", 36 | "globby": "^10.0.1", 37 | "jsonschema": "^1.2.4", 38 | "lodash": "^4.17.21", 39 | "mocha": "^10.2.0", 40 | "node-emoji": "^1.10.0", 41 | "pify": "^4.0.1", 42 | "recursive-readdir": "^2.2.2", 43 | "sc-istanbul": "^0.4.5", 44 | "semver": "^7.3.4", 45 | "shelljs": "^0.8.3", 46 | "web3-utils": "^1.3.6" 47 | }, 48 | "devDependencies": { 49 | "@nomicfoundation/hardhat-network-helpers": "^1.0.10", 50 | "@nomicfoundation/hardhat-viem": "^2.0.0", 51 | "@nomiclabs/hardhat-ethers": "^2.0.4", 52 | "@nomiclabs/hardhat-truffle5": "^2.0.0", 53 | "@nomiclabs/hardhat-waffle": "^2.0.1", 54 | "@nomiclabs/hardhat-web3": "^2.0.0", 55 | "chai": "^4.3.4", 56 | "chai-as-promised": "^7.1.1", 57 | "decache": "^4.5.1", 58 | "ethereum-waffle": "^3.4.0", 59 | "ethers": "^5.5.3", 60 | "hardhat": "^2.22.2", 61 | "hardhat-gas-reporter": "^1.0.1", 62 | "nyc": "^14.1.1", 63 | "solc": "0.8.24", 64 | "viem": "^2.9.9" 65 | }, 66 | "peerDependencies": { 67 | "hardhat": "^2.11.0" 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /plugins/bin.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* 4 | Logs a warning / informational message when user tries to 5 | invoke 'solidity-coverage' as a shell command. This file 6 | is listed as the package.json "bin". 7 | */ 8 | const AppUI = require('../lib/ui').AppUI; 9 | 10 | (new AppUI()).report('command'); 11 | -------------------------------------------------------------------------------- /plugins/nomiclabs.plugin.js: -------------------------------------------------------------------------------- 1 | require("./hardhat.plugin"); -------------------------------------------------------------------------------- /plugins/resources/matrix.js: -------------------------------------------------------------------------------- 1 | const mocha = require("mocha"); 2 | const inherits = require("util").inherits; 3 | const Spec = mocha.reporters.Spec; 4 | const path = require('path'); 5 | 6 | /** 7 | * This file adapted from mocha's stats-collector 8 | * https://github.com/mochajs/mocha/blob/54475eb4ca35a2c9044a1b8c59a60f09c73e6c01/lib/stats-collector.js#L1-L83 9 | */ 10 | const Date = global.Date; 11 | 12 | /** 13 | * Provides stats such as test duration, number of tests passed / failed etc., by 14 | * listening for events emitted by `runner`. 15 | */ 16 | function mochaStats(runner) { 17 | const stats = { 18 | suites: 0, 19 | tests: 0, 20 | passes: 0, 21 | pending: 0, 22 | failures: 0 23 | }; 24 | 25 | if (!runner) throw new Error("Missing runner argument"); 26 | 27 | runner.stats = stats; 28 | 29 | runner.on("pass", () => stats.passes++); 30 | runner.on("fail", () => stats.failures++); 31 | runner.on("pending", () => stats.pending++); 32 | runner.on("test end", () => stats.tests++); 33 | 34 | runner.once("start", () => (stats.start = new Date())); 35 | 36 | runner.once("end", function() { 37 | stats.end = new Date(); 38 | stats.duration = stats.end - stats.start; 39 | }); 40 | } 41 | 42 | /** 43 | * Based on the Mocha 'Spec' reporter. 44 | * 45 | * Watches an Ethereum test suite run and collects data about which tests hit 46 | * which lines of code. This "test matrix" can be used as an input to fault localization tools 47 | * like: https://github.com/JoranHonig/tarantula 48 | * 49 | * Mocha's JSON reporter output is also generated and saved to a separate file 50 | * 51 | * @param {Object} runner mocha's runner 52 | * @param {Object} options reporter.options (see README example usage) 53 | */ 54 | function Matrix(runner, options) { 55 | // Spec reporter 56 | Spec.call(this, runner, options); 57 | 58 | const self = this; 59 | const tests = []; 60 | const failures = []; 61 | const passes = []; 62 | 63 | // Initialize stats for Mocha 6+ epilogue 64 | if (!runner.stats) { 65 | mochaStats(runner); 66 | this.stats = runner.stats; 67 | } 68 | 69 | runner.on("test end", (info) => { 70 | options.reporterOptions.collectTestMatrixData(info); 71 | tests.push(info); 72 | }); 73 | 74 | runner.on('pass', function(info) { 75 | passes.push(info) 76 | }) 77 | runner.on('fail', function(info) { 78 | failures.push(info) 79 | }); 80 | 81 | runner.once('end', function() { 82 | delete self.stats.start; 83 | delete self.stats.end; 84 | delete self.stats.duration; 85 | 86 | var obj = { 87 | stats: self.stats, 88 | tests: tests.map(clean), 89 | failures: failures.map(clean), 90 | passes: passes.map(clean) 91 | }; 92 | runner.testResults = obj; 93 | options.reporterOptions.saveMochaJsonOutput(obj) 94 | }); 95 | 96 | // >>>>>>>>>>>>>>>>>>>>>>>>> 97 | // Mocha JSON Reporter Utils 98 | // Code taken from: 99 | // https://mochajs.org/api/reporters_json.js.html 100 | // >>>>>>>>>>>>>>>>>>>>>>>>> 101 | function clean(info) { 102 | var err = info.err || {}; 103 | if (err instanceof Error) { 104 | err = errorJSON(err); 105 | } 106 | return { 107 | title: info.title, 108 | fullTitle: info.fullTitle(), 109 | file: path.relative(options.reporterOptions.cwd, info.file), 110 | currentRetry: info.currentRetry(), 111 | err: cleanCycles(err) 112 | }; 113 | } 114 | 115 | function cleanCycles(obj) { 116 | var cache = []; 117 | return JSON.parse( 118 | JSON.stringify(obj, function(key, value) { 119 | if (typeof value === 'object' && value !== null) { 120 | if (cache.indexOf(value) !== -1) { 121 | // Instead of going in a circle, we'll print [object Object] 122 | return '' + value; 123 | } 124 | cache.push(value); 125 | } 126 | return value; 127 | }) 128 | ); 129 | } 130 | 131 | function errorJSON(err) { 132 | var res = {}; 133 | Object.getOwnPropertyNames(err).forEach(function(key) { 134 | res[key] = err[key]; 135 | }, err); 136 | return res; 137 | } 138 | } 139 | 140 | /** 141 | * Inherit from `Base.prototype`. 142 | */ 143 | inherits(Matrix, Spec); 144 | 145 | module.exports = Matrix; -------------------------------------------------------------------------------- /plugins/resources/nomiclabs.ui.js: -------------------------------------------------------------------------------- 1 | const UI = require('./../../lib/ui').UI; 2 | 3 | /** 4 | * Nomiclabs Plugin logging 5 | */ 6 | class PluginUI extends UI { 7 | constructor(log){ 8 | super(log); 9 | 10 | this.flags = { 11 | testfiles: `Path (or glob) defining a subset of tests to run`, 12 | 13 | testMatrix: `Generate a json object which maps which unit tests hit which lines of code.`, 14 | 15 | abi: `Generate a json object which can be used to produce a unified diff of your ` + 16 | `contracts public interface between two commits.`, 17 | 18 | solcoverjs: `Relative path from working directory to config. ` + 19 | `Useful for monorepo packages that share settings.`, 20 | 21 | temp: `Path to a disposable folder to store compilation artifacts in. ` + 22 | `Useful when your test setup scripts include hard-coded paths to ` + 23 | `a build directory.`, 24 | } 25 | } 26 | 27 | /** 28 | * Writes a formatted message via log 29 | * @param {String} kind message selector 30 | * @param {String[]} args info to inject into template 31 | */ 32 | report(kind, args=[]){ 33 | const c = this.chalk; 34 | const ct = c.bold.green('>'); 35 | const ds = c.bold.yellow('>'); 36 | const w = ":warning:"; 37 | 38 | const kinds = { 39 | 40 | 'instr-skip': `\n${c.bold('Coverage skipped for:')}` + 41 | `\n${c.bold('=====================')}\n`, 42 | 43 | 'compilation': `\n${c.bold('Compilation:')}` + 44 | `\n${c.bold('============')}\n`, 45 | 46 | 'instr-skipped': `${ds} ${c.grey(args[0])}`, 47 | 48 | 'hardhat-versions': `\n${c.bold('Version')}` + 49 | `\n${c.bold('=======')}\n` + 50 | `${ct} ${c.bold('solidity-coverage')}: v${args[0]}`, 51 | 52 | 'hardhat-network': `\n${c.bold('Network Info')}` + 53 | `\n${c.bold('============')}\n` + 54 | `${ct} ${c.bold('HardhatEVM')}: v${args[0]}\n` + 55 | `${ct} ${c.bold('network')}: ${args[1]}\n`, 56 | 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 | , 63 | } 64 | 65 | this._write(kinds[kind]); 66 | } 67 | 68 | /** 69 | * Returns a formatted message. Useful for error message. 70 | * @param {String} kind message selector 71 | * @param {String[]} args info to inject into template 72 | * @return {String} message 73 | */ 74 | generate(kind, args=[]){ 75 | const c = this.chalk; 76 | const x = ":x:"; 77 | 78 | const kinds = { 79 | 'network-fail': `${c.red('--network cli flag is not supported for the coverage task. ')}` + 80 | `${c.red('Beginning with v0.8.7, coverage must use the default "hardhat" network.')}`, 81 | 82 | 'sources-fail': `${c.red('Cannot locate expected contract sources folder: ')} ${args[0]}`, 83 | 84 | 'solcoverjs-fail': `${c.red('Could not load .solcover.js config file. ')}` + 85 | `${c.red('This can happen if it has a syntax error or ')}` + 86 | `${c.red('the path you specified for it is wrong.')}`, 87 | 88 | 'tests-fail': `${x} ${c.bold(args[0])} ${c.red('test(s) failed under coverage.')}`, 89 | 90 | 'hardhat-viem': "'hardhat-viem' requires an environment variable to be set when used with the solidity-coverage plugin" 91 | } 92 | 93 | 94 | return this._format(kinds[kind]) 95 | } 96 | 97 | 98 | } 99 | 100 | module.exports = PluginUI; 101 | -------------------------------------------------------------------------------- /plugins/resources/plugin.ui.js: -------------------------------------------------------------------------------- 1 | const UI = require('./../../lib/ui').UI; 2 | 3 | /** 4 | * Plugin logging 5 | */ 6 | class PluginUI extends UI { 7 | constructor(log){ 8 | super(log); 9 | } 10 | 11 | /** 12 | * Writes a formatted message via log 13 | * @param {String} kind message selector 14 | * @param {String[]} args info to inject into template 15 | */ 16 | report(kind, args=[]){ 17 | const c = this.chalk; 18 | const ct = c.bold.green('>'); 19 | const ds = c.bold.yellow('>'); 20 | const w = ":warning:"; 21 | 22 | const kinds = { 23 | 24 | 'instr-skip': `\n${c.bold('Coverage skipped for:')}` + 25 | `\n${c.bold('=====================')}\n`, 26 | 27 | 'instr-skipped': `${ds} ${c.grey(args[0])}`, 28 | 29 | 'network': `\n${c.bold('Network Info')}` + 30 | `\n${c.bold('============')}\n` + 31 | `${ct} ${c.bold('id')}: ${args[1]}\n` + 32 | `${ct} ${c.bold('port')}: ${args[2]}\n` + 33 | `${ct} ${c.bold('network')}: ${args[0]}\n`, 34 | 35 | } 36 | 37 | this._write(kinds[kind]); 38 | } 39 | 40 | /** 41 | * Returns a formatted message. Useful for error message. 42 | * @param {String} kind message selector 43 | * @param {String[]} args info to inject into template 44 | * @return {String} message 45 | */ 46 | generate(kind, args=[]){ 47 | const c = this.chalk; 48 | const x = ":x:"; 49 | 50 | const kinds = { 51 | 52 | 'sources-fail': `${c.red('Cannot locate expected contract sources folder: ')} ${args[0]}`, 53 | 54 | 'solcoverjs-fail': `${c.red('Could not load .solcover.js config file. ')}` + 55 | `${c.red('This can happen if it has a syntax error or ')}` + 56 | `${c.red('the path you specified for it is wrong.')}`, 57 | 58 | 'tests-fail': `${x} ${c.bold(args[0])} ${c.red('test(s) failed under coverage.')}`, 59 | 60 | 'mocha-parallel-fail': `${c.red('Coverage cannot be run in mocha parallel mode. ')}` + 61 | `${c.red('Set \`mocha: { parallel: false }\` in .solcover.js ')}` + 62 | `${c.red('to disable the option for the coverage task. ')}` + 63 | `${c.red('See the solidity-coverage README FAQ for info on parallelizing coverage in CI.')}`, 64 | } 65 | 66 | 67 | return this._format(kinds[kind]) 68 | } 69 | } 70 | 71 | module.exports = PluginUI; -------------------------------------------------------------------------------- /scripts/ci.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Toggles optimizer on/off 4 | VIAR_IR=$VIA_IR 5 | 6 | # Minimize integration test output 7 | SILENT=true 8 | 9 | node --max-old-space-size=4096 \ 10 | ./node_modules/.bin/nyc \ 11 | --reporter=lcov \ 12 | --exclude '**/sc_temp/**' \ 13 | --exclude '**/test/**/' \ 14 | --exclude 'plugins/resources/matrix.js' \ 15 | -- \ 16 | mocha \ 17 | test/units/* test/integration/* \ 18 | --require "test/util/mochaRootHook.js" \ 19 | --timeout 100000 \ 20 | --no-warnings \ 21 | --exit \ 22 | -------------------------------------------------------------------------------- /scripts/integration.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Toggles optimizer on/off 4 | VIA_IR=$VIA_IR 5 | 6 | node --max-old-space-size=4096 \ 7 | ./node_modules/.bin/nyc \ 8 | --exclude '**/sc_temp/**' \ 9 | --exclude '**/test/**/' \ 10 | -- \ 11 | mocha test/integration/* \ 12 | --timeout 100000 \ 13 | --no-warnings \ 14 | --exit 15 | -------------------------------------------------------------------------------- /scripts/nomiclabs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # E2E CI: installs PR candidate on sc-forks/hardhat-e2e (a simple example, 4 | # similar to Metacoin) and runs coverage 5 | # 6 | 7 | set -o errexit 8 | 9 | function verifyCoverageExists { 10 | if [ ! -d "coverage" ]; then 11 | echo "ERROR: no coverage folder was created." 12 | exit 1 13 | fi 14 | } 15 | 16 | function verifyMatrixExists { 17 | if [ ! -f "testMatrix.json" ]; then 18 | echo "ERROR: no matrix file was created." 19 | exit 1 20 | fi 21 | } 22 | 23 | # Get rid of any caches 24 | sudo rm -rf node_modules 25 | echo "NVM CURRENT >>>>>" && nvm current 26 | 27 | # Use PR env variables (for forks) or fallback on local if PR not available 28 | SED_REGEX="s/git@github.com:/https:\/\/github.com\//" 29 | 30 | if [[ -v CIRCLE_PR_REPONAME ]]; then 31 | PR_PATH="https://github.com/$CIRCLE_PR_USERNAME/$CIRCLE_PR_REPONAME#$CIRCLE_SHA1" 32 | else 33 | PR_PATH=$(echo "$CIRCLE_REPOSITORY_URL#$CIRCLE_SHA1" | sudo sed "$SED_REGEX") 34 | fi 35 | 36 | echo "PR_PATH >>>>> $PR_PATH" 37 | 38 | echo "" 39 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 40 | echo "Simple hardhat/hardhat-trufflev5 " 41 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 42 | echo "" 43 | 44 | # Install hardhat-e2e (HardhatEVM) 45 | git clone https://github.com/sc-forks/hardhat-e2e.git 46 | cd hardhat-e2e 47 | npm install --silent 48 | 49 | # Install and run solidity-coverage @ PR 50 | npm install --save-dev --silent $PR_PATH 51 | cat package.json 52 | 53 | npx hardhat init-foundry 54 | cat foundry.toml 55 | 56 | npx hardhat coverage 57 | 58 | verifyCoverageExists 59 | 60 | npx hardhat coverage --matrix 61 | 62 | verifyMatrixExists 63 | 64 | cat testMatrix.json 65 | 66 | echo "" 67 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 68 | echo "wighawag/hardhat-deploy " 69 | echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" 70 | echo "" 71 | cd .. 72 | npm install -g yarn 73 | git clone https://github.com/cgewecke/template-ethereum-contracts.git 74 | cd template-ethereum-contracts 75 | yarn 76 | yarn add $PR_PATH --dev 77 | cat package.json 78 | 79 | # Here we want to make sure that HH cache triggers a 80 | # complete recompile after coverage runs by verifying 81 | # that gas consumption is same in both runs. 82 | yarn run gas 83 | yarn run coverage 84 | yarn run gas 85 | 86 | verifyCoverageExists 87 | -------------------------------------------------------------------------------- /scripts/unit.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Toggles optimizer on/off 4 | VIAR_IR=$VIA_IR 5 | 6 | node --max-old-space-size=4096 \ 7 | ./node_modules/.bin/nyc \ 8 | --exclude '**/sc_temp/**' \ 9 | --exclude '**/test/**/' \ 10 | -- \ 11 | mocha test/units/* \ 12 | --require "test/util/mochaRootHook.js" \ 13 | --timeout 100000 \ 14 | --no-warnings \ 15 | --exit 16 | -------------------------------------------------------------------------------- /scripts/zeppelin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # E2E CI: installs PR candidate on openzeppelin-contracts and runs coverage 4 | # 5 | 6 | # TODO: uncomment this when zeppelin job gets fixed 7 | # set -o errexit 8 | 9 | # Get rid of any caches 10 | sudo rm -rf node_modules 11 | echo "NVM CURRENT >>>>>" && nvm current 12 | nvm use 20 13 | 14 | # Use PR env variables (for forks) or fallback on local if PR not available 15 | SED_REGEX="s/git@github.com:/https:\/\/github.com\//" 16 | 17 | if [[ -v CIRCLE_PR_REPONAME ]]; then 18 | PR_PATH="https://github.com/$CIRCLE_PR_USERNAME/$CIRCLE_PR_REPONAME#$CIRCLE_SHA1" 19 | else 20 | PR_PATH=$(echo "$CIRCLE_REPOSITORY_URL#$CIRCLE_SHA1" | sudo sed "$SED_REGEX") 21 | fi 22 | 23 | echo "PR_PATH >>>>> $PR_PATH" 24 | 25 | # Install Zeppelin 26 | git clone https://github.com/OpenZeppelin/openzeppelin-contracts.git 27 | cd openzeppelin-contracts 28 | 29 | # Swap installed coverage for PR branch version 30 | echo ">>>>> npm install" 31 | npm install 32 | 33 | # Use HH latest 34 | npm install hardhat@latest --save-dev 35 | 36 | echo ">>>>> npm uninstall solidity-coverage --save-dev" 37 | npm uninstall solidity-coverage --save-dev 38 | 39 | echo ">>>>> npm add $PR_PATH --dev" 40 | npm install "$PR_PATH" --save-dev 41 | 42 | echo ">>>>> cat package.json" 43 | cat package.json 44 | 45 | # Track perf 46 | CI=false npm run coverage 47 | 48 | # TODO: remove EXIT 0 when zeppelin job is fixed - currently failing for time-related reasons in circleci 49 | # TODO: uncomment set command at top of this file 50 | exit 0 -------------------------------------------------------------------------------- /test/sources/generic/assets/SimpleError.sol: -------------------------------------------------------------------------------- 1 | // This contract should throw a parse error in instrumentSolidity.js 2 | pragma solidity >=0.8.0 <0.9.0; 3 | 4 | contract SimpleError { 5 | uint x = 0; 6 | 7 | function test(uint val) public { 8 | x = x + val // <-- no semi-colon 9 | } 10 | 11 | function getX() public returns (uint){ 12 | return x; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sources/generic/assets/asset.js: -------------------------------------------------------------------------------- 1 | module.exports = { value: true }; 2 | -------------------------------------------------------------------------------- /test/sources/generic/contracts/.marker: -------------------------------------------------------------------------------- 1 | // because circle won't copy the folder w/out contents 2 | -------------------------------------------------------------------------------- /test/sources/generic/test/.marker: -------------------------------------------------------------------------------- 1 | // because circle won't copy the folder w/out contents -------------------------------------------------------------------------------- /test/sources/js/account-one.js: -------------------------------------------------------------------------------- 1 | const Simple = artifacts.require('Simple'); 2 | 3 | contract('Simple', () => { 4 | it('should use 0xe7a46b209a65baadc11bf973c0f4d5f19465ae83', async function(){ 5 | const simple = await Simple.new() 6 | const result = await simple.test(5); 7 | assert.equal(result.receipt.from, "0xe7a46b209a65baadc11bf973c0f4d5f19465ae83") 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/sources/js/account-zero.js: -------------------------------------------------------------------------------- 1 | const Simple = artifacts.require('Simple'); 2 | 3 | contract('Simple', () => { 4 | it('should use 0x42ecc9ab31d7c0240532992682ee3533421dd7f5', async function(){ 5 | const simple = await Simple.new() 6 | const result = await simple.test(5); 7 | assert.equal(result.receipt.from, "0x42ecc9ab31d7c0240532992682ee3533421dd7f5") 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/sources/js/block-gas-limit.js: -------------------------------------------------------------------------------- 1 | const Expensive = artifacts.require('Expensive'); 2 | 3 | contract('Expensive', () => { 4 | it('should deploy', async function() { 5 | const instance = await Expensive.new() 6 | const hash = instance.transactionHash; 7 | const receipt = await web3.eth.getTransactionReceipt(hash); 8 | assert(receipt.gasUsed > 20000000) 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/sources/js/empty.js: -------------------------------------------------------------------------------- 1 | const Empty = artifacts.require('Empty'); 2 | 3 | contract('Empty', function() { 4 | it('should deploy', async function (){ 5 | await Empty.new() 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/sources/js/inheritance.js: -------------------------------------------------------------------------------- 1 | const Owned = artifacts.require('Owned'); 2 | const Proxy = artifacts.require('Proxy'); 3 | 4 | contract('Proxy', accounts => { 5 | it('when one contract inherits from another', async function(){ 6 | const owned = await Owned.new(); 7 | const proxy = await Proxy.new(); 8 | const val = await proxy.isOwner({from: accounts[0]}); 9 | assert.equal(val, true); 10 | }) 11 | }); 12 | -------------------------------------------------------------------------------- /test/sources/js/modified.js: -------------------------------------------------------------------------------- 1 | const Modified = artifacts.require('Modified'); 2 | 3 | contract('Modified', () => { 4 | it('should set counter', async function(){ 5 | const m = await Modified.new() 6 | await m.set(5); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/sources/js/only-call.js: -------------------------------------------------------------------------------- 1 | const OnlyCall = artifacts.require('OnlyCall'); 2 | 3 | contract('OnlyCall', accounts => { 4 | it('should return val + 2', async function(){ 5 | const onlycall = await OnlyCall.new(); 6 | const val = await onlycall.addTwo(5); 7 | assert.equal(val.toNumber(), 7); 8 | }) 9 | }); 10 | -------------------------------------------------------------------------------- /test/sources/js/oraclize.js: -------------------------------------------------------------------------------- 1 | const usingOraclize = artifacts.require('usingOraclize'); 2 | 3 | contract('Oraclize', function(accounts){ 4 | it('oraclize', async function(){ 5 | const ora = await usingOraclize.new(); 6 | await ora.test(); 7 | }); 8 | }); 9 | 10 | -------------------------------------------------------------------------------- /test/sources/js/pureview.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node, mocha */ 2 | /* global artifacts, contract, assert */ 3 | 4 | const PureView = artifacts.require('PureView'); 5 | 6 | contract('PureView', accounts => { 7 | 8 | it('calls a pure function', async function(){ 9 | const instance = await PureView.new(); 10 | const value = await instance.isPure(4,5); 11 | }); 12 | 13 | it('calls a view function', async function(){ 14 | const instance = await PureView.new(); 15 | const value = await instance.isView(); 16 | }) 17 | }); -------------------------------------------------------------------------------- /test/sources/js/simple.js: -------------------------------------------------------------------------------- 1 | const Simple = artifacts.require('Simple'); 2 | 3 | contract('Simple', () => { 4 | it('should set x to 5', async function(){ 5 | const simple = await Simple.new() 6 | await simple.test(5); 7 | const val = await simple.getX.call(); 8 | assert.equal(val.toNumber(), 5); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/sources/js/testrpc-options.js: -------------------------------------------------------------------------------- 1 | const Simple = artifacts.require('Simple'); 2 | 3 | contract('Simple', accounts => { 4 | 5 | it('should load with ~ expected balance', async function(){ 6 | let balance = await web3.eth.getBalance(accounts[0]); 7 | balance = web3.utils.fromWei(balance); 8 | assert(parseInt(balance) >= 776) 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/sources/js/totallyPure.js: -------------------------------------------------------------------------------- 1 | const UsesPure = artifacts.require('UsesPure'); 2 | 3 | contract('UsesPure', accounts => { 4 | it('calls imported, inherited pure/view functions within its own function', async () => { 5 | const instance = await UsesPure.new(); 6 | await instance.usesThem(); 7 | }); 8 | 9 | it('calls an imported, inherited pure function', async () => { 10 | const instance = await UsesPure.new(); 11 | const value = await instance.isPure(4, 5); 12 | assert.equal(value.toNumber(), 20); 13 | }); 14 | 15 | it('calls an imported, inherited view function', async () => { 16 | const instance = await UsesPure.new(); 17 | const value = await instance.isView(); 18 | assert.equal(value.toNumber(), 5); 19 | }); 20 | 21 | it('overrides an imported, inherited abstract pure function', async () => { 22 | const instance = await UsesPure.new(); 23 | const value = await instance.bePure(4, 5); 24 | assert.equal(value.toNumber(), 9); 25 | }); 26 | 27 | it('overrides an imported, inherited abstract view function', async () => { 28 | const instance = await UsesPure.new(); 29 | const value = await instance.beView(); 30 | assert.equal(value.toNumber(), 99); 31 | }); 32 | 33 | it('calls a pure method implemented in an inherited class', async() => { 34 | const instance = await UsesPure.new(); 35 | const value = await instance.inheritedPure(4, 5); 36 | assert.equal(value.toNumber(), 9); 37 | }); 38 | 39 | it('calls a view method implemented in an inherited class', async () => { 40 | const instance = await UsesPure.new(); 41 | const value = await instance.inheritedView(); 42 | assert.equal(value.toNumber(), 5); 43 | }); 44 | 45 | it('calls a view method whose modifiers span lines', async () => { 46 | const instance = await UsesPure.new(); 47 | const value = await instance.multiline(5, 7) 48 | assert.equal(value.toNumber(), 99); 49 | }); 50 | 51 | it('calls a method who signature is defined by an interface', async () => { 52 | const instance = await UsesPure.new(); 53 | await instance.cry(); 54 | }); 55 | }); -------------------------------------------------------------------------------- /test/sources/js/truffle-crash.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node, mocha */ 2 | /* global artifacts, contract */ 3 | 4 | var Simple = artifacts.require('Simple'); 5 | 6 | // This test should break truffle because it has a syntax error. 7 | contract('Simple', () => { 8 | it('should crash', function(){ 9 | return Simple.new().then.why. 10 | }) 11 | }) -------------------------------------------------------------------------------- /test/sources/js/truffle-test-fail.js: -------------------------------------------------------------------------------- 1 | /* eslint-env node, mocha */ 2 | /* global artifacts, contract, assert */ 3 | 4 | const Simple = artifacts.require('Simple'); 5 | 6 | contract('Simple', () => { 7 | it('should set x to 5', async function() { 8 | let simple = await Simple.new(); 9 | await simple.test(5); 10 | const val = await simple.getX(); 11 | assert.equal(val.toNumber(), 4) // <-- Wrong result: test fails 12 | }); 13 | 14 | it('should set x to 2', async function() { 15 | let simple = await Simple.new(); 16 | await simple.test(5); 17 | const val = await simple.getX(); 18 | assert.equal(val.toNumber(), 2) // <-- Wrong result: test fails 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/sources/js/wallet.js: -------------------------------------------------------------------------------- 1 | const Wallet = artifacts.require('Wallet'); 2 | 3 | contract('Wallet', accounts => { 4 | it('should should allow transfers and sends', async () => { 5 | const walletA = await Wallet.new(); 6 | const walletB = await Wallet.new(); 7 | 8 | await walletA.sendTransaction({ 9 | value: web3.utils.toBN(500), from: accounts[0], 10 | }); 11 | 12 | await walletA.sendPayment(50, walletB.address, { 13 | from: accounts[0], 14 | }); 15 | 16 | await walletA.transferPayment(50, walletB.address, { 17 | from: accounts[0], 18 | }); 19 | }); 20 | }); -------------------------------------------------------------------------------- /test/sources/projects/bad-solcoverjs/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | wrong, noooooo oh noooooooo.!!!!! 3 | } 4 | -------------------------------------------------------------------------------- /test/sources/projects/bad-solcoverjs/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports={ 5 | logger: process.env.SILENT ? { log: () => {} } : console, 6 | }; 7 | -------------------------------------------------------------------------------- /test/sources/projects/contract-subfolders/.solcover.js: -------------------------------------------------------------------------------- 1 | // Testing hooks 2 | const fn = (msg, config) => config.logger.log(msg); 3 | 4 | module.exports = { 5 | skipFiles: ['Migrations.sol'], 6 | silent: process.env.SILENT ? true : false, 7 | istanbulReporter: ['json-summary', 'text'], 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/projects/contract-subfolders/contracts/A/ContractA2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | import "./../B/ContractB2.sol"; 4 | 5 | contract ContractA is ContractB { 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/contract-subfolders/contracts/B/ContractB2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractB { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFnB() public { 10 | x = 5; 11 | } 12 | 13 | function callFnB() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/contract-subfolders/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports={ 5 | networks: { 6 | hardhat: { 7 | gasPrice: 2 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 | paths: { 20 | sources: './contracts/A' 21 | }, 22 | logger: process.env.SILENT ? { log: () => {} } : console, 23 | }; 24 | -------------------------------------------------------------------------------- /test/sources/projects/contract-subfolders/test/contracta2.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractA.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | await instance.sendFnB(); 11 | }); 12 | 13 | it('calls', async function(){ 14 | await instance.callFn(); 15 | await instance.callFnB(); 16 | }) 17 | }); 18 | -------------------------------------------------------------------------------- /test/sources/projects/file-level-functions/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | silent: process.env.SILENT ? true : false, 3 | skipFiles: [], 4 | istanbulReporter: ['json-summary', 'text'] 5 | } 6 | -------------------------------------------------------------------------------- /test/sources/projects/file-level-functions/contracts/FunctionA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | function functionA(bool x) returns (bool) { 4 | bool a = false; 5 | if (a || x) return x; 6 | } 7 | -------------------------------------------------------------------------------- /test/sources/projects/file-level-functions/contracts/FunctionB.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | function functionB(bool x) returns (bool) { 4 | bool a = false; 5 | if (a || x) return x; 6 | } 7 | -------------------------------------------------------------------------------- /test/sources/projects/file-level-functions/contracts/UsesFunctions.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | import "./FunctionA.sol"; 4 | import "./FunctionB.sol"; 5 | 6 | contract UsesFunctions { 7 | bool a; 8 | 9 | constructor() public {} 10 | 11 | function useLocalFunction(bool x) public { 12 | a = x; 13 | } 14 | 15 | function useImportedFunctions(bool x) public { 16 | a = functionA(x); 17 | a = functionB(x); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/sources/projects/file-level-functions/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/file-level-functions/test/usesFunctions.js: -------------------------------------------------------------------------------- 1 | const UsesFunctions = artifacts.require("UsesFunctions"); 2 | 3 | contract("contracts", function(accounts) { 4 | let instance; 5 | 6 | before(async () => { 7 | instance = await UsesFunctions.new(); 8 | }); 9 | 10 | it('when false', async function(){ 11 | await instance.useLocalFunction(false); 12 | await instance.useImportedFunctions(false); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/.solcover.js: -------------------------------------------------------------------------------- 1 | // solc v0.4.21 will not compile using instrumentation technique for viaIR 2 | const skipFiles = process.env.VIA_IR ? ["ContractD1.sol"] : []; 3 | 4 | module.exports = { 5 | "silent": false, 6 | "istanbulReporter": [ "json-summary", "text"], 7 | "skipFiles": skipFiles 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/contracts/ContractA1.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/contracts/ContractB1.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractB { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/contracts/ContractC1.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractC { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/contracts/ContractD1.sol: -------------------------------------------------------------------------------- 1 | pragma solidity 0.4.21; 2 | 3 | 4 | contract ContractD { 5 | uint x; 6 | 7 | function sendFn() public { 8 | x = 5; 9 | } 10 | 11 | function callFn() public pure returns (uint){ 12 | uint y = 5; 13 | return y; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports={ 5 | solidity: { 6 | compilers: [ 7 | { 8 | version: "0.4.21", 9 | settings: { 10 | optimizer: { 11 | enabled: true 12 | } 13 | }, 14 | }, 15 | { 16 | version: "0.8.17", 17 | settings: { 18 | optimizer: { 19 | enabled: true 20 | }, 21 | viaIR: process.env.VIA_IR === "true" 22 | } 23 | }, 24 | { 25 | version: "0.8.19" 26 | }, 27 | // Make sure optimizer gets disabled 28 | { 29 | version: "0.8.12", 30 | settings: { 31 | optimizer: { 32 | enabled: true, 33 | runs: 200 34 | } 35 | } 36 | } 37 | ], 38 | overrides: { 39 | "contracts/ContractA.sol": { 40 | version: "0.8.24", 41 | settings: { 42 | optimizer: { 43 | enabled: true, 44 | runs: 200, 45 | evmVersion: 'paris' 46 | }, 47 | viaIR: process.env.VIA_IR === "true", 48 | } 49 | } 50 | } 51 | }, 52 | logger: process.env.SILENT ? { log: () => {} } : console, 53 | }; 54 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/test/contracta1.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractA.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/test/contractb1.js: -------------------------------------------------------------------------------- 1 | const ContractB = artifacts.require("ContractB"); 2 | 3 | contract("contractB", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractB.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/test/contractc1.js: -------------------------------------------------------------------------------- 1 | const ContractC = artifacts.require("ContractC"); 2 | 3 | contract("contractc", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractC.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | 16 | it('sends', async function(){ 17 | await instance.sendFn(); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-compile-config/test/contractd1.js: -------------------------------------------------------------------------------- 1 | const ContractD = artifacts.require("ContractD"); 2 | 3 | contract("contractd", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractD.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | 16 | it('sends', async function(){ 17 | await instance.sendFn(); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-gas-reporter/contracts/ContractA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-gas-reporter/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("hardhat-gas-reporter"); 2 | require("@nomiclabs/hardhat-truffle5"); 3 | require(__dirname + "/../plugins/nomiclabs.plugin"); 4 | 5 | module.exports = { 6 | solidity: { 7 | version: "0.8.17", 8 | settings: { 9 | optimizer: { 10 | enabled: true 11 | }, 12 | viaIR: process.env.VIA_IR === "true" 13 | } 14 | }, 15 | logger: process.env.SILENT ? { log: () => {} } : console, 16 | }; 17 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-gas-reporter/test/test.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractA.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-mine/.solcover.js: -------------------------------------------------------------------------------- 1 | // Testing hooks 2 | const fn = (msg, config) => config.logger.log(msg); 3 | 4 | module.exports = { 5 | silent: process.env.SILENT ? true : false, 6 | istanbulReporter: ['json-summary', 'text'], 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-mine/contracts/Setter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract Setter { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function set() public { 10 | x = 1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-mine/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | require("@nomiclabs/hardhat-ethers"); 3 | require(__dirname + "/../plugins/nomiclabs.plugin"); 4 | 5 | module.exports = { 6 | solidity: { 7 | version: "0.8.17", 8 | settings: { 9 | optimizer: { 10 | enabled: true 11 | }, 12 | viaIR: process.env.VIA_IR === "true" 13 | } 14 | }, 15 | logger: process.env.SILENT ? { log: () => {} } : console, 16 | }; 17 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-mine/test/testMine.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const { ethers } = require("hardhat"); 3 | 4 | describe("Setter", function() { 5 | let instance; 6 | 7 | before(async () => { 8 | const factory = await ethers.getContractFactory("Setter"); 9 | instance = await factory.deploy(); 10 | }); 11 | 12 | it('sets at the beginning', async function(){ 13 | await instance.set(); 14 | }); 15 | 16 | it('sets at the end', async function(){ 17 | // Mine about 50K blocks 18 | await hre.network.provider.send('hardhat_mine', ['0xCCCC']) 19 | await instance.set(); 20 | }); 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-reset/.solcover.js: -------------------------------------------------------------------------------- 1 | // Testing hooks 2 | const fn = (msg, config) => config.logger.log(msg); 3 | 4 | module.exports = { 5 | skipFiles: ['Migrations.sol'], 6 | silent: process.env.SILENT ? true : false, 7 | istanbulReporter: ['json-summary', 'text'], 8 | } -------------------------------------------------------------------------------- /test/sources/projects/hardhat-reset/contracts/ContractAReset.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 1; 11 | } 12 | 13 | function sendFn2() public { 14 | x = 2; 15 | } 16 | 17 | function callFn() public pure returns (uint){ 18 | uint y = 5; 19 | return y; 20 | } 21 | 22 | function callFn2() public pure returns (uint){ 23 | uint y = 5; 24 | return y; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-reset/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | require("@nomiclabs/hardhat-ethers"); 3 | require(__dirname + "/../plugins/nomiclabs.plugin"); 4 | 5 | if (!process.env.ALCHEMY_TOKEN){ 6 | throw new Error( 7 | "This test requires that you set ALCHEMY_TOKEN to a valid token in your development env" 8 | ); 9 | } 10 | 11 | module.exports = { 12 | solidity: { 13 | version: "0.8.17", 14 | settings: { 15 | optimizer: { 16 | enabled: true 17 | }, 18 | viaIR: process.env.VIA_IR === "true" 19 | } 20 | }, 21 | networks: { 22 | hardhat: { 23 | timeout: 100000, 24 | forking: { 25 | url: `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_TOKEN}`, 26 | blockNumber: 14000000, 27 | } 28 | } 29 | }, 30 | mocha: { 31 | timeout: 100000 32 | }, 33 | logger: process.env.SILENT ? { log: () => {} } : console, 34 | }; 35 | -------------------------------------------------------------------------------- /test/sources/projects/hardhat-reset/test/testReset.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const { ethers } = require("hardhat"); 3 | 4 | describe("contractA", function() { 5 | let instance; 6 | let startBlockNumber; 7 | 8 | beforeEach(async () => { 9 | startBlockNumber = await ethers.provider.getBlockNumber(); 10 | 11 | await hre.network.provider.request({ 12 | method: "hardhat_reset", 13 | params: [ 14 | { 15 | forking: { 16 | jsonRpcUrl: `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_TOKEN}`, 17 | blockNumber: startBlockNumber, 18 | }, 19 | }, 20 | ], 21 | }); 22 | 23 | const factory = await ethers.getContractFactory("ContractA"); 24 | instance = await factory.deploy(); 25 | }); 26 | 27 | it('sends', async function(){ 28 | await instance.sendFn(); 29 | }); 30 | 31 | it('sends 2', async function(){ 32 | await instance.sendFn2(); 33 | }); 34 | 35 | it('calls', async function(){ 36 | await instance.callFn(); 37 | }); 38 | 39 | it('calls 2', async function(){ 40 | await instance.callFn2(); 41 | }); 42 | }); 43 | 44 | -------------------------------------------------------------------------------- /test/sources/projects/import-paths/.gitignore: -------------------------------------------------------------------------------- 1 | !node_modules -------------------------------------------------------------------------------- /test/sources/projects/import-paths/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | silent: process.env.SILENT ? true : false, 3 | istanbulReporter: ['json-summary', 'text'] 4 | } 5 | -------------------------------------------------------------------------------- /test/sources/projects/import-paths/assets/RelativePathImport.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.8.0; 2 | 3 | contract RelativePathImport { 4 | uint r; 5 | constructor() public {} 6 | 7 | function isRelativePathMethod() public { 8 | r = 5; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/projects/import-paths/contracts/OnlyUsesImports.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.8.0; 2 | 3 | import "package/AnotherImport.sol"; 4 | -------------------------------------------------------------------------------- /test/sources/projects/import-paths/contracts/UsesImports.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.8.0; 2 | 3 | import "../assets/RelativePathImport.sol"; 4 | import "package/NodeModulesImport.sol"; 5 | 6 | contract UsesImports is RelativePathImport, NodeModulesImport { 7 | 8 | constructor() public {} 9 | 10 | function wrapsRelativePathMethod() public { 11 | isRelativePathMethod(); 12 | } 13 | 14 | function wrapsNodeModulesMethod() public { 15 | isNodeModulesMethod(); 16 | } 17 | } -------------------------------------------------------------------------------- /test/sources/projects/import-paths/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/import-paths/node_modules/package/AnotherImport.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.8.0; 2 | 3 | contract AnotherImport { 4 | uint x; 5 | constructor() public {} 6 | 7 | function isNodeModulesMethod() public { 8 | x = 5; 9 | } 10 | } -------------------------------------------------------------------------------- /test/sources/projects/import-paths/node_modules/package/NodeModulesImport.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.8.0; 2 | 3 | contract NodeModulesImport { 4 | uint x; 5 | constructor() public {} 6 | 7 | function isNodeModulesMethod() public { 8 | x = 5; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/projects/import-paths/node_modules/package/package.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /test/sources/projects/import-paths/test/uses_imports.js: -------------------------------------------------------------------------------- 1 | var UsesImports = artifacts.require("UsesImports"); 2 | 3 | contract("UsesImports", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await UsesImports.new()); 7 | 8 | it('uses a method from a relative import', async () => { 9 | await instance.wrapsRelativePathMethod(); 10 | }) 11 | 12 | it('uses an import from node_modules', async () => { 13 | await instance.wrapsNodeModulesMethod(); 14 | }) 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /test/sources/projects/irMinimum/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | silent: process.env.SILENT ? true : false, 3 | istanbulReporter: ['json-summary', 'text'], 4 | irMinimum: true, 5 | } 6 | -------------------------------------------------------------------------------- /test/sources/projects/irMinimum/contracts/IRMinimum.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract ContractA { 4 | // 15 fn args + 1 local variable assignment 5 | // will trigger stack too deep error when optimizer is off. 6 | function stackTooDeep( 7 | uint _a, 8 | uint _b, 9 | uint _c, 10 | uint _d, 11 | uint _e, 12 | uint _f, 13 | uint _g, 14 | uint _h, 15 | uint _i, 16 | uint _j, 17 | uint _k, 18 | uint _l, 19 | uint _m, 20 | uint _n, 21 | uint _o 22 | ) public { 23 | uint x = _a; 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/sources/projects/irMinimum/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.28", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | evmVersion: "cancun", 12 | viaIR: true 13 | } 14 | }, 15 | logger: process.env.SILENT ? { log: () => {} } : console, 16 | }; 17 | -------------------------------------------------------------------------------- /test/sources/projects/irMinimum/test/test_irMinimum.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let a,b; 5 | 6 | before(async () => { 7 | a = await ContractA.new(); 8 | }) 9 | 10 | it('a:stackTooDeep', async function(){ 11 | await a.stackTooDeep( 12 | 1, 13 | 2, 14 | 3, 15 | 4, 16 | 5, 17 | 6, 18 | 7, 19 | 8, 20 | 9, 21 | 10, 22 | 11, 23 | 12, 24 | 13, 25 | 14, 26 | 15 27 | ); 28 | }) 29 | }); 30 | -------------------------------------------------------------------------------- /test/sources/projects/libraries/contracts/CLibrary.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | library CLibrary { 4 | uint constant x = 1; 5 | function a() public view returns (uint) { 6 | return x; 7 | } 8 | } -------------------------------------------------------------------------------- /test/sources/projects/libraries/contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.8.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/sources/projects/libraries/contracts/PureView.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract PureView { 4 | 5 | // Make sure we aren't corrupting anything with the replace 6 | uint notpureview = 5; 7 | 8 | function inheritedPure(uint a, uint b) public pure returns(uint){ 9 | return a + b; 10 | } 11 | 12 | function inheritedView() public view returns (uint){ 13 | return notpureview; 14 | } 15 | } -------------------------------------------------------------------------------- /test/sources/projects/libraries/contracts/UsesPure.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | import "./_Interface.sol"; 4 | import "./PureView.sol"; 5 | import "./CLibrary.sol"; 6 | 7 | contract UsesPure is PureView, _Interface { 8 | uint onehundred = 99; 9 | 10 | function usesThem() public view { 11 | uint y = isPure(1,2); 12 | uint z = isView(); 13 | } 14 | 15 | function isPure(uint a, uint b) public pure returns (uint){ 16 | return a * b; 17 | } 18 | 19 | function isView() public view returns (uint){ 20 | return notpureview; 21 | } 22 | 23 | function isConstant() public view returns (uint){ 24 | return onehundred; 25 | } 26 | 27 | function bePure(uint a, uint b) public pure returns (uint) { 28 | return a + b; 29 | } 30 | 31 | function beView() public view returns (uint){ 32 | return onehundred; 33 | } 34 | 35 | function usesLibrary() public view returns (uint){ 36 | return CLibrary.a(); 37 | } 38 | 39 | function multiline(uint x, 40 | uint y) 41 | public 42 | view 43 | returns (uint) 44 | { 45 | return onehundred; 46 | } 47 | 48 | function stare(uint a, uint b) external override { 49 | uint z = a + b; 50 | } 51 | 52 | function cry() external override { 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /test/sources/projects/libraries/contracts/_Interface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | interface _Interface { 4 | function stare(uint a, uint b) external; 5 | function cry() external; 6 | } -------------------------------------------------------------------------------- /test/sources/projects/libraries/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/libraries/test/libraries.js: -------------------------------------------------------------------------------- 1 | const UsesPure = artifacts.require('UsesPure'); 2 | 3 | contract('UsesPure', accounts => { 4 | it('calls imported, inherited pure/view functions within its own function', async () => { 5 | const instance = await UsesPure.new(); 6 | await instance.usesThem(); 7 | }); 8 | 9 | it('calls a library method', async() => { 10 | const instance = await UsesPure.new(); 11 | const value = await instance.usesLibrary(); 12 | assert.equal(value.toNumber(), 1); 13 | }); 14 | 15 | it('calls an imported, inherited pure function', async () => { 16 | const instance = await UsesPure.new(); 17 | const value = await instance.isPure(4, 5); 18 | assert.equal(value.toNumber(), 20); 19 | }); 20 | 21 | it('calls an imported, inherited view function', async () => { 22 | const instance = await UsesPure.new(); 23 | const value = await instance.isView(); 24 | assert.equal(value.toNumber(), 5); 25 | }); 26 | 27 | it('overrides an imported, inherited abstract pure function', async () => { 28 | const instance = await UsesPure.new(); 29 | const value = await instance.bePure(4, 5); 30 | assert.equal(value.toNumber(), 9); 31 | }); 32 | 33 | it('overrides an imported, inherited abstract view function', async () => { 34 | const instance = await UsesPure.new(); 35 | const value = await instance.beView(); 36 | assert.equal(value.toNumber(), 99); 37 | }); 38 | 39 | it('calls a pure method implemented in an inherited class', async() => { 40 | const instance = await UsesPure.new(); 41 | const value = await instance.inheritedPure(4, 5); 42 | assert.equal(value.toNumber(), 9); 43 | }); 44 | 45 | it('calls a view method implemented in an inherited class', async () => { 46 | const instance = await UsesPure.new(); 47 | const value = await instance.inheritedView(); 48 | assert.equal(value.toNumber(), 5); 49 | }); 50 | 51 | it('calls a view method whose modifiers span lines', async () => { 52 | const instance = await UsesPure.new(); 53 | const value = await instance.multiline(5, 7) 54 | assert.equal(value.toNumber(), 99); 55 | }); 56 | 57 | it('calls a method who signature is defined by an interface', async () => { 58 | const instance = await UsesPure.new(); 59 | await instance.cry(); 60 | }); 61 | 62 | 63 | 64 | }); -------------------------------------------------------------------------------- /test/sources/projects/matrix/.solcover.js: -------------------------------------------------------------------------------- 1 | // Testing hooks 2 | const fn = (msg, config) => config.logger.log(msg); 3 | const reporterPath = (process.env.TRUFFLE_TEST) 4 | ? "./plugins/resources/matrix.js" 5 | : "../plugins/resources/matrix.js"; 6 | 7 | module.exports = { 8 | // This is loaded directly from `./plugins` during unit tests. The default val is 9 | // "solidity-coverage/plugins/resources/matrix.js" 10 | matrixReporterPath: reporterPath, 11 | matrixOutputPath: "alternateTestMatrix.json", 12 | mochaJsonOutputPath: "alternateMochaOutput.json", 13 | 14 | skipFiles: ['Migrations.sol'], 15 | silent: process.env.SILENT ? true : false, 16 | istanbulReporter: ['json-summary', 'text'], 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/matrix/contracts/MatrixA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract MatrixA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | 18 | function unhit() public { 19 | uint z = 7; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/sources/projects/matrix/contracts/MatrixB.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract MatrixB { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/matrix/expectedMochaOutput.json: -------------------------------------------------------------------------------- 1 | { 2 | "stats": { 3 | "suites": 2, 4 | "tests": 6, 5 | "passes": 6, 6 | "pending": 0, 7 | "failures": 0 8 | }, 9 | "tests": [ 10 | { 11 | "title": "sends", 12 | "fullTitle": "Contract: MatrixA sends", 13 | "file": "test/matrix_a.js", 14 | "currentRetry": 0, 15 | "err": {} 16 | }, 17 | { 18 | "title": "calls", 19 | "fullTitle": "Contract: MatrixA calls", 20 | "file": "test/matrix_a.js", 21 | "currentRetry": 0, 22 | "err": {} 23 | }, 24 | { 25 | "title": "sends to A", 26 | "fullTitle": "Contract: Matrix A and B sends to A", 27 | "file": "test/matrix_a_b.js", 28 | "currentRetry": 0, 29 | "err": {} 30 | }, 31 | { 32 | "title": "sends to A", 33 | "fullTitle": "Contract: Matrix A and B sends to A", 34 | "file": "test/matrix_a_b.js", 35 | "currentRetry": 0, 36 | "err": {} 37 | }, 38 | { 39 | "title": "calls B", 40 | "fullTitle": "Contract: Matrix A and B calls B", 41 | "file": "test/matrix_a_b.js", 42 | "currentRetry": 0, 43 | "err": {} 44 | }, 45 | { 46 | "title": "sends to B", 47 | "fullTitle": "Contract: Matrix A and B sends to B", 48 | "file": "test/matrix_a_b.js", 49 | "currentRetry": 0, 50 | "err": {} 51 | } 52 | ], 53 | "failures": [], 54 | "passes": [ 55 | { 56 | "title": "sends", 57 | "fullTitle": "Contract: MatrixA sends", 58 | "file": "test/matrix_a.js", 59 | "currentRetry": 0, 60 | "err": {} 61 | }, 62 | { 63 | "title": "calls", 64 | "fullTitle": "Contract: MatrixA calls", 65 | "file": "test/matrix_a.js", 66 | "currentRetry": 0, 67 | "err": {} 68 | }, 69 | { 70 | "title": "sends to A", 71 | "fullTitle": "Contract: Matrix A and B sends to A", 72 | "file": "test/matrix_a_b.js", 73 | "currentRetry": 0, 74 | "err": {} 75 | }, 76 | { 77 | "title": "sends to A", 78 | "fullTitle": "Contract: Matrix A and B sends to A", 79 | "file": "test/matrix_a_b.js", 80 | "currentRetry": 0, 81 | "err": {} 82 | }, 83 | { 84 | "title": "calls B", 85 | "fullTitle": "Contract: Matrix A and B calls B", 86 | "file": "test/matrix_a_b.js", 87 | "currentRetry": 0, 88 | "err": {} 89 | }, 90 | { 91 | "title": "sends to B", 92 | "fullTitle": "Contract: Matrix A and B sends to B", 93 | "file": "test/matrix_a_b.js", 94 | "currentRetry": 0, 95 | "err": {} 96 | } 97 | ] 98 | } 99 | 100 | -------------------------------------------------------------------------------- /test/sources/projects/matrix/expectedTestMatrixHardhat.json: -------------------------------------------------------------------------------- 1 | { 2 | "contracts/MatrixA.sol": { 3 | "10": [ 4 | { 5 | "title": "sends", 6 | "file": "test/matrix_a.js" 7 | }, 8 | { 9 | "title": "sends to A", 10 | "file": "test/matrix_a_b.js" 11 | } 12 | ], 13 | "14": [ 14 | { 15 | "title": "calls", 16 | "file": "test/matrix_a.js" 17 | } 18 | ], 19 | "15": [ 20 | { 21 | "title": "calls", 22 | "file": "test/matrix_a.js" 23 | } 24 | ], 25 | "19": [] 26 | }, 27 | "contracts/MatrixB.sol": { 28 | "10": [ 29 | { 30 | "title": "sends to B", 31 | "file": "test/matrix_a_b.js" 32 | } 33 | ], 34 | "14": [ 35 | { 36 | "title": "calls B", 37 | "file": "test/matrix_a_b.js" 38 | } 39 | ], 40 | "15": [ 41 | { 42 | "title": "calls B", 43 | "file": "test/matrix_a_b.js" 44 | } 45 | ] 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /test/sources/projects/matrix/expectedTestMatrixTruffle.json: -------------------------------------------------------------------------------- 1 | { 2 | "contracts/MatrixA.sol": { 3 | "10": [ 4 | { 5 | "title": "sends", 6 | "file": "test/matrix_a.js" 7 | }, 8 | { 9 | "title": "sends to A", 10 | "file": "test/matrix_a_b.js" 11 | } 12 | ], 13 | "14": [ 14 | { 15 | "title": "calls", 16 | "file": "test/matrix_a.js" 17 | } 18 | ], 19 | "15": [ 20 | { 21 | "title": "calls", 22 | "file": "test/matrix_a.js" 23 | } 24 | ] 25 | }, 26 | "contracts/MatrixB.sol": { 27 | "10": [ 28 | { 29 | "title": "sends to B", 30 | "file": "test/matrix_a_b.js" 31 | } 32 | ], 33 | "14": [ 34 | { 35 | "title": "calls B", 36 | "file": "test/matrix_a_b.js" 37 | } 38 | ], 39 | "15": [ 40 | { 41 | "title": "calls B", 42 | "file": "test/matrix_a_b.js" 43 | } 44 | ] 45 | } 46 | } -------------------------------------------------------------------------------- /test/sources/projects/matrix/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports={ 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/matrix/test/matrix_a.js: -------------------------------------------------------------------------------- 1 | const MatrixA = artifacts.require("MatrixA"); 2 | 3 | contract("MatrixA", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await MatrixA.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/matrix/test/matrix_a_b.js: -------------------------------------------------------------------------------- 1 | const MatrixA = artifacts.require("MatrixA"); 2 | const MatrixB = artifacts.require("MatrixB"); 3 | 4 | contract("Matrix A and B", function(accounts) { 5 | let instanceA; 6 | let instanceB; 7 | 8 | before(async () => { 9 | instanceA = await MatrixA.new(); 10 | instanceB = await MatrixB.new(); 11 | }) 12 | 13 | it('sends to A', async function(){ 14 | await instanceA.sendFn(); 15 | }); 16 | 17 | // Duplicate test title and file should *not* be duplicated in the output 18 | it('sends to A', async function(){ 19 | await instanceA.sendFn(); 20 | }) 21 | 22 | it('calls B', async function(){ 23 | await instanceB.callFn(); 24 | }) 25 | 26 | it('sends to B', async function(){ 27 | await instanceB.sendFn(); 28 | }); 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /test/sources/projects/matrix/truffle-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | networks: {}, 3 | mocha: {}, 4 | compilers: { 5 | solc: { 6 | version: "0.8.17" 7 | } 8 | }, 9 | logger: process.env.SILENT ? { log: () => {} } : console, 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/.solcover.js: -------------------------------------------------------------------------------- 1 | // Testing hooks 2 | const fn = (msg, config) => config.logger.log(msg); 3 | 4 | module.exports = { 5 | skipFiles: ['Migrations.sol'], 6 | silent: process.env.SILENT ? true : false, 7 | istanbulReporter: ['json-summary', 'text'], 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/contracts/ModifiersA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | import "./ModifiersB.sol"; 4 | 5 | /** 6 | * New syntaxes in solc 0.6.x 7 | */ 8 | contract ModifiersA is ModifiersB { 9 | uint counter; 10 | bool flag = true; 11 | 12 | modifier flippable { 13 | require(flag); 14 | _; 15 | } 16 | 17 | modifier overridden() override { 18 | require(true); 19 | _; 20 | } 21 | 22 | function flip() public { 23 | flag = !flag; 24 | } 25 | 26 | function simpleSet(uint i) 27 | public 28 | override(ModifiersB) 29 | { 30 | counter = counter + i; 31 | } 32 | 33 | function simpleView(uint i) 34 | view 35 | overridden 36 | external 37 | returns (uint, bool) 38 | { 39 | return (counter + i, true); 40 | } 41 | 42 | function simpleSetFlip(uint i) flippable public { 43 | counter = counter + i; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/contracts/ModifiersB.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ModifiersB { 5 | uint value; 6 | uint b; 7 | 8 | constructor() public { 9 | } 10 | 11 | modifier overridden() virtual { 12 | require(true); 13 | _; 14 | } 15 | 16 | function simpleSet(uint i) public virtual { 17 | value = 5; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/contracts/ModifiersC.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | import "./ModifiersB.sol"; 4 | 5 | /** 6 | * New syntaxes in solc 0.6.x 7 | */ 8 | contract ModifiersC { 9 | uint counter; 10 | address owner; 11 | bool flag = true; 12 | 13 | constructor() public { 14 | owner = msg.sender; 15 | } 16 | 17 | modifier flippable { 18 | require(flag); 19 | _; 20 | } 21 | 22 | function flip() public { 23 | flag = !flag; 24 | } 25 | 26 | function simpleSetFlip(uint i) flippable public { 27 | counter = counter + i; 28 | } 29 | 30 | modifier onlyOwner { 31 | require(msg.sender == owner); 32 | _; 33 | } 34 | 35 | function set(uint i) 36 | onlyOwner 37 | public 38 | payable 39 | virtual 40 | { 41 | counter = counter + i; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/contracts/ModifiersD.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | import "./../external/Ownable.sol"; 4 | 5 | contract ModifiersD is Ownable { 6 | constructor() Ownable(msg.sender) {} 7 | 8 | function a() public onlyOwner { 9 | } 10 | } 11 | 12 | 13 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/external/Context.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) 3 | 4 | pragma solidity >=0.8.0 <0.9.0; 5 | 6 | /** 7 | * @dev Provides information about the current execution context, including the 8 | * sender of the transaction and its data. While these are generally available 9 | * via msg.sender and msg.data, they should not be accessed in such a direct 10 | * manner, since when dealing with meta-transactions the account sending and 11 | * paying for execution may not be the actual sender (as far as an application 12 | * is concerned). 13 | * 14 | * This contract is only required for intermediate, library-like contracts. 15 | */ 16 | abstract contract Context { 17 | function _msgSender() internal view virtual returns (address) { 18 | return msg.sender; 19 | } 20 | 21 | function _msgData() internal view virtual returns (bytes calldata) { 22 | return msg.data; 23 | } 24 | 25 | function _contextSuffixLength() internal view virtual returns (uint256) { 26 | return 0; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/external/Ownable.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) 3 | 4 | pragma solidity >=0.8.0 <0.9.0; 5 | 6 | import {Context} from "./Context.sol"; 7 | 8 | /** 9 | * @dev Contract module which provides a basic access control mechanism, where 10 | * there is an account (an owner) that can be granted exclusive access to 11 | * specific functions. 12 | * 13 | * The initial owner is set to the address provided by the deployer. This can 14 | * later be changed with {transferOwnership}. 15 | * 16 | * This module is used through inheritance. It will make available the modifier 17 | * `onlyOwner`, which can be applied to your functions to restrict their use to 18 | * the owner. 19 | */ 20 | contract Ownable is Context { 21 | address private _owner; 22 | 23 | /** 24 | * @dev The caller account is not authorized to perform an operation. 25 | */ 26 | error OwnableUnauthorizedAccount(address account); 27 | 28 | /** 29 | * @dev The owner is not a valid owner account. (eg. `address(0)`) 30 | */ 31 | error OwnableInvalidOwner(address owner); 32 | 33 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); 34 | 35 | /** 36 | * @dev Initializes the contract setting the address provided by the deployer as the initial owner. 37 | */ 38 | constructor(address initialOwner) { 39 | if (initialOwner == address(0)) { 40 | revert OwnableInvalidOwner(address(0)); 41 | } 42 | _transferOwnership(initialOwner); 43 | } 44 | 45 | /** 46 | * @dev Throws if called by any account other than the owner. 47 | */ 48 | modifier onlyOwner() { 49 | _checkOwner(); 50 | _; 51 | } 52 | 53 | /** 54 | * @dev Returns the address of the current owner. 55 | */ 56 | function owner() public view returns (address) { 57 | return _owner; 58 | } 59 | 60 | /** 61 | * @dev Throws if the sender is not the owner. 62 | */ 63 | function _checkOwner() internal view { 64 | if (owner() != _msgSender()) { 65 | revert OwnableUnauthorizedAccount(_msgSender()); 66 | } 67 | } 68 | 69 | /** 70 | * @dev Leaves the contract without owner. It will not be possible to call 71 | * `onlyOwner` functions. Can only be called by the current owner. 72 | * 73 | * NOTE: Renouncing ownership will leave the contract without an owner, 74 | * thereby disabling any functionality that is only available to the owner. 75 | */ 76 | function renounceOwnership() public onlyOwner { 77 | _transferOwnership(address(0)); 78 | } 79 | 80 | /** 81 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 82 | * Can only be called by the current owner. 83 | */ 84 | function transferOwnership(address newOwner) public onlyOwner { 85 | if (newOwner == address(0)) { 86 | revert OwnableInvalidOwner(address(0)); 87 | } 88 | _transferOwnership(newOwner); 89 | } 90 | 91 | /** 92 | * @dev Transfers ownership of the contract to a new account (`newOwner`). 93 | * Internal function without access restriction. 94 | */ 95 | function _transferOwnership(address newOwner) internal { 96 | address oldOwner = _owner; 97 | _owner = newOwner; 98 | emit OwnershipTransferred(oldOwner, newOwner); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/test/modifiers.js: -------------------------------------------------------------------------------- 1 | const ModifiersA = artifacts.require("ModifiersA"); 2 | const ModifiersC = artifacts.require("ModifiersC"); 3 | const ModifiersD = artifacts.require("ModifiersD"); 4 | 5 | contract("Modifiers", function(accounts) { 6 | let instance; 7 | 8 | before(async () => { 9 | A = await ModifiersA.new(); 10 | C = await ModifiersC.new(); 11 | D = await ModifiersD.new(); 12 | }) 13 | 14 | it('simpleSet (overridden method)', async function(){ 15 | await A.simpleSet(5); 16 | }); 17 | 18 | it('simpleView (overridden modifier)', async function(){ 19 | await A.simpleView(5); 20 | }); 21 | 22 | it('simpleSetFlip (both branches)', async function(){ 23 | await A.simpleSetFlip(5); 24 | await A.flip(); 25 | 26 | try { 27 | await A.simpleSetFlip(5); 28 | } catch (e) { 29 | /* ignore */ 30 | } 31 | }); 32 | 33 | it('simpleSetFlip (false branch + other file)', async function(){ 34 | await C.flip(); 35 | 36 | try { 37 | await C.simpleSetFlip(5); 38 | } catch (e) { 39 | /* ignore */ 40 | } 41 | }); 42 | 43 | it('when false & true branches are hit in immediate succesion by EOA (issue #863)', async function(){ 44 | try { 45 | await D.a({from: accounts[1]}); 46 | } catch (e) { 47 | /* ignore */ 48 | } 49 | 50 | await D.a({from: accounts[0]}); 51 | }) 52 | }); 53 | -------------------------------------------------------------------------------- /test/sources/projects/modifiers/truffle-config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | networks: {}, 3 | mocha: {}, 4 | compilers: { 5 | solc: { 6 | version: "0.6.2" 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/projects/multiple-suites/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "silent": false, 3 | "istanbulReporter": [ "json-summary", "text"] 4 | } 5 | -------------------------------------------------------------------------------- /test/sources/projects/multiple-suites/contracts/ContractA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/multiple-suites/contracts/ContractB.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractB { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/multiple-suites/contracts/ContractC.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractC { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/multiple-suites/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports={ 5 | networks: { 6 | hardhat: { 7 | gasPrice: 2 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 | }; 21 | -------------------------------------------------------------------------------- /test/sources/projects/multiple-suites/test/contracta.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractA.new()) 7 | 8 | it('sends [ @skipForCoverage ]', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls [ @skipForCoverage ]', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/multiple-suites/test/contractb.js: -------------------------------------------------------------------------------- 1 | const ContractB = artifacts.require("ContractB"); 2 | 3 | contract("contractB [ @skipForCoverage ]", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractB.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/multiple-suites/test/contractc.js: -------------------------------------------------------------------------------- 1 | const ContractC = artifacts.require("ContractC"); 2 | 3 | contract("contractc", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractC.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | 16 | it('sends', async function(){ 17 | await instance.sendFn(); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /test/sources/projects/no-sources/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/overrides-viaIR/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "silent": false, 3 | "istanbulReporter": [ "json-summary", "text"] 4 | } 5 | -------------------------------------------------------------------------------- /test/sources/projects/overrides-viaIR/contracts/ContractOverA2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/overrides-viaIR/contracts/ContractOverB2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractB { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/overrides-viaIR/contracts/ContractOverC2.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractC { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/overrides-viaIR/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports={ 5 | solidity: { 6 | compilers: [ 7 | { 8 | version: "0.8.17", 9 | }, 10 | { 11 | version: "0.8.19" 12 | }, 13 | ], 14 | overrides: { 15 | "contracts/ContractA.sol": { 16 | version: "0.8.24", 17 | settings: { 18 | optimizer: { 19 | enabled: true, 20 | runs: 200, 21 | evmVersion: 'paris' 22 | }, 23 | viaIR: process.env.VIA_IR === "true", 24 | } 25 | } 26 | } 27 | }, 28 | logger: process.env.SILENT ? { log: () => {} } : console, 29 | }; 30 | -------------------------------------------------------------------------------- /test/sources/projects/overrides-viaIR/test/contract_over_a2.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractA.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | }); 12 | -------------------------------------------------------------------------------- /test/sources/projects/overrides-viaIR/test/contract_over_b2.js: -------------------------------------------------------------------------------- 1 | const ContractB = artifacts.require("ContractB"); 2 | 3 | contract("contractB", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractB.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/overrides-viaIR/test/contract_over_c2.js: -------------------------------------------------------------------------------- 1 | const ContractC = artifacts.require("ContractC"); 2 | 3 | contract("contractc", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractC.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | 16 | it('sends', async function(){ 17 | await instance.sendFn(); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /test/sources/projects/parallel/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "silent": false, 3 | "istanbulReporter": [ "json-summary", "text"], 4 | "mocha": { 5 | parallel: true // manually tested that setting to false overrides HH config 6 | }, 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/projects/parallel/contracts/ContractA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | 7 | function set() public { 8 | x = 5; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/projects/parallel/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require(__dirname + "/../plugins/nomiclabs.plugin"); 2 | 3 | module.exports = { 4 | mocha: { 5 | parallel: true 6 | }, 7 | logger: process.env.SILENT ? { log: () => {} } : console, 8 | }; 9 | -------------------------------------------------------------------------------- /test/sources/projects/skipping/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | silent: process.env.SILENT ? true : false, 3 | skipFiles: ['skipped-folder'], 4 | istanbulReporter: ['json-summary', 'text'] 5 | } 6 | -------------------------------------------------------------------------------- /test/sources/projects/skipping/contracts/ContractA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/skipping/contracts/skipped-folder/ContractB.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractB { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/skipping/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/skipping/test/contract.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | const ContractB = artifacts.require("ContractB"); 3 | 4 | contract("contracts", function(accounts) { 5 | let instanceA; 6 | let instanceB; 7 | 8 | before(async () => { 9 | instanceA = await ContractA.new(); 10 | instanceB = await ContractB.new(); 11 | }); 12 | 13 | it('A sends', async function(){ 14 | await instanceA.sendFn(); 15 | }); 16 | 17 | it('A calls', async function(){ 18 | await instanceA.callFn(); 19 | }); 20 | 21 | it('B sends', async function(){ 22 | await instanceB.sendFn(); 23 | }); 24 | 25 | it('B calls', async function(){ 26 | await instanceB.callFn(); 27 | }); 28 | 29 | }); 30 | -------------------------------------------------------------------------------- /test/sources/projects/solc-8/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | silent: process.env.SILENT ? true : false, 3 | skipFiles: ['skipped-folder'], 4 | istanbulReporter: ['json-summary', 'text'], 5 | configureYulOptimizer: true, 6 | solcOptimizerDetails: { 7 | peephole: false, 8 | inliner: false, 9 | jumpdestRemover: false, 10 | orderLiterals: true, // <-- TRUE! Stack too deep when false 11 | deduplicate: false, 12 | cse: false, 13 | constantOptimizer: false, 14 | yul: false 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/sources/projects/solc-8/contracts/Abstract_solc8.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | abstract contract ContractB { 4 | modifier onlyOwner() virtual; 5 | } 6 | -------------------------------------------------------------------------------- /test/sources/projects/solc-8/contracts/Contract_solc8.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | pragma abicoder v2; 3 | 4 | import "./Library_solc8.sol"; 5 | 6 | error InvalidSomeAddress(address someAddress); 7 | 8 | using Library_solc8 for uint256; 9 | 10 | contract ContractA { 11 | mapping(bytes32 key => uint256) public authorization; 12 | address public someAddress; 13 | bool transient locked; 14 | 15 | function throwError(address _add) external { 16 | this; 17 | 18 | if (_add == address(0)) { 19 | revert InvalidSomeAddress(_add); 20 | } 21 | 22 | someAddress = _add; 23 | } 24 | 25 | function checkSomething() external { 26 | uint a = 5; 27 | 28 | unchecked { 29 | a++; 30 | } 31 | 32 | unchecked {} 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /test/sources/projects/solc-8/contracts/Library_solc8.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | library Library_solc8 { 4 | uint constant x = 1; 5 | function a() public view returns (uint) { 6 | return x; 7 | } 8 | } -------------------------------------------------------------------------------- /test/sources/projects/solc-8/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.28", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | evmVersion: "cancun", 12 | viaIR: process.env.VIA_IR === "true" 13 | } 14 | }, 15 | logger: process.env.SILENT ? { log: () => {} } : console, 16 | }; 17 | -------------------------------------------------------------------------------- /test/sources/projects/solc-8/test/test_solc8.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let a,b; 5 | 6 | before(async () => { 7 | a = await ContractA.new(); 8 | }) 9 | 10 | it('a:throwError', async function(){ 11 | await a.throwError(a.address); 12 | }); 13 | 14 | it('a:checkSomething', async function(){ 15 | await a.checkSomething(); 16 | }) 17 | }); 18 | -------------------------------------------------------------------------------- /test/sources/projects/task-hooks/.solcover.js: -------------------------------------------------------------------------------- 1 | // Testing hooks 2 | const fn = (msg, config) => config.logger.log(msg); 3 | 4 | module.exports = { 5 | skipFiles: [], 6 | silent: process.env.SILENT ? true : false, 7 | istanbulReporter: ['json-summary', 'text'], 8 | onPreCompile: fn.bind(null, 'running onPreCompile'), 9 | onServerReady: fn.bind(null, 'running onServerReady'), 10 | onTestsComplete: fn.bind(null, 'running onTestsComplete'), 11 | onCompileComplete: fn.bind(null, 'running onCompileComplete'), 12 | onIstanbulComplete: fn.bind(null, 'running onIstanbulComplete') 13 | } 14 | -------------------------------------------------------------------------------- /test/sources/projects/task-hooks/contracts/Hooks.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/task-hooks/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/task-hooks/test/hooks.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractA.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/ternary-and-logical-or/.solcover.js: -------------------------------------------------------------------------------- 1 | // Testing hooks 2 | const fn = (msg, config) => config.logger.log(msg); 3 | 4 | module.exports = { 5 | skipFiles: ['Migrations.sol'], 6 | silent: process.env.SILENT ? true : false, 7 | istanbulReporter: ['json-summary', 'text', 'html'], 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/projects/ternary-and-logical-or/contracts/Contract_OR.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract Contract_OR { 5 | 6 | function _if(uint i) public pure { 7 | if (i == 0 || i > 5){ 8 | /* ignore */ 9 | } 10 | } 11 | 12 | function _if_and(uint i) public pure { 13 | if (i != 0 && (i < 2 || i > 5)){ 14 | /* ignore */ 15 | } 16 | } 17 | 18 | function _return(uint i) public pure returns (bool){ 19 | return (i != 0 && i != 1 ) || 20 | ((i + 1) == 2); 21 | } 22 | 23 | function _while(uint i) public pure returns (bool){ 24 | uint counter; 25 | while( (i == 1 || i == 2) && counter < 2 ){ 26 | counter++; 27 | } 28 | } 29 | 30 | function _require(uint x) public { 31 | require(x == 1 || x == 2); 32 | } 33 | 34 | function _require_multi_line(uint x) public { 35 | require( 36 | (x == 1 || x == 2) || 37 | x == 3 38 | ); 39 | } 40 | 41 | function _if_neither(uint i) public { 42 | if (i == 1 || i == 2){ 43 | /* ignore */ 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/sources/projects/ternary-and-logical-or/contracts/Contract_ternary.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract Contract_ternary { 5 | 6 | // Sameline consequent 7 | function a() public { 8 | bool x = true; 9 | bool y = true; 10 | x && y ? y = false : y = false; 11 | } 12 | 13 | // Multiline consequent 14 | function b() public { 15 | bool x = false; 16 | bool y = false; 17 | (x) 18 | ? y = false 19 | : y = false; 20 | } 21 | 22 | // Sameline w/ logicalOR 23 | function c() public { 24 | bool x = false; 25 | bool y = true; 26 | (x || y) ? y = false : y = false; 27 | } 28 | 29 | // Multiline w/ logicalOR 30 | function d() public { 31 | bool x = false; 32 | bool y = true; 33 | (x || y) 34 | ? y = false 35 | : y = false; 36 | } 37 | 38 | // Sameline alternate 39 | function e() public { 40 | bool x = false; 41 | bool y = false; 42 | (x) ? y = false : y = false; 43 | } 44 | 45 | // Multiline w/ logicalOR (both false) 46 | function f() public { 47 | bool x = false; 48 | bool y = false; 49 | (x || y) 50 | ? y = false 51 | : y = false; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /test/sources/projects/ternary-and-logical-or/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/ternary-and-logical-or/test/test_or.js: -------------------------------------------------------------------------------- 1 | const Contract_OR = artifacts.require("Contract_OR"); 2 | 3 | contract("contract_or", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await Contract_OR.new()) 7 | 8 | it('_if', async function(){ 9 | await instance._if(0); 10 | await instance._if(7); 11 | }); 12 | 13 | it('_if_and', async function(){ 14 | await instance._if_and(1); 15 | }); 16 | 17 | it('_return', async function(){ 18 | await instance._return(4); 19 | }); 20 | 21 | it('_while', async function(){ 22 | await instance._while(1); 23 | }); 24 | 25 | it('_require', async function(){ 26 | await instance._require(2); 27 | }) 28 | 29 | it('_require_multi_line', async function(){ 30 | await instance._require_multi_line(1); 31 | await instance._require_multi_line(3); 32 | }) 33 | 34 | it('_if_neither', async function(){ 35 | await instance._if_neither(3); 36 | }) 37 | }); 38 | -------------------------------------------------------------------------------- /test/sources/projects/ternary-and-logical-or/test/test_ternary.js: -------------------------------------------------------------------------------- 1 | const Contract_ternary = artifacts.require("Contract_ternary"); 2 | 3 | contract("contract_ternary", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await Contract_ternary.new()) 7 | 8 | it('misc ternary conditionals', async function(){ 9 | await instance.a(); 10 | await instance.b(); 11 | await instance.c(); 12 | await instance.d(); 13 | await instance.e(); 14 | await instance.f(); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | skipFiles: [], 3 | silent: process.env.SILENT ? true : false, 4 | istanbulReporter: ['json-summary', 'text'] 5 | } 6 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/contracts/ContractA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/contracts/ContractB.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractB { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/contracts/ContractC.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractC { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/contracts/otherContracts/OtherContractA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract OtherContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.24", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/test/globby_b.js: -------------------------------------------------------------------------------- 1 | const ContractB = artifacts.require("ContractB"); 2 | 3 | contract("contractB", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractB.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/test/globby_c.js: -------------------------------------------------------------------------------- 1 | const ContractC = artifacts.require("ContractC"); 2 | 3 | contract("contractc", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractC.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | 16 | it('sends', async function(){ 17 | await instance.sendFn(); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/test/other_contract_a.js: -------------------------------------------------------------------------------- 1 | const OtherContractA = artifacts.require("OtherContractA"); 2 | 3 | contract("otherContractA", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await OtherContractA.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/test-files/test/specific_a.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractA.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/tests-folder/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | "silent": false, 3 | "istanbulReporter": [ "json-summary", "text"] 4 | } 5 | -------------------------------------------------------------------------------- /test/sources/projects/tests-folder/contracts/ContractA.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractA { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/tests-folder/contracts/ContractB.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractB { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/tests-folder/contracts/ContractC.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | 4 | contract ContractC { 5 | uint x; 6 | constructor() public { 7 | } 8 | 9 | function sendFn() public { 10 | x = 5; 11 | } 12 | 13 | function callFn() public pure returns (uint){ 14 | uint y = 5; 15 | return y; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/projects/tests-folder/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-truffle5"); 2 | require(__dirname + "/../plugins/nomiclabs.plugin"); 3 | 4 | module.exports = { 5 | solidity: { 6 | version: "0.8.17", 7 | settings: { 8 | optimizer: { 9 | enabled: true 10 | }, 11 | viaIR: process.env.VIA_IR === "true" 12 | } 13 | }, 14 | logger: process.env.SILENT ? { log: () => {} } : console, 15 | }; 16 | -------------------------------------------------------------------------------- /test/sources/projects/tests-folder/test/contracta.js: -------------------------------------------------------------------------------- 1 | const ContractA = artifacts.require("ContractA"); 2 | 3 | contract("contracta", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractA.new()) 7 | 8 | it('sends [ @skipForCoverage ]', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls [ @skipForCoverage ]', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/tests-folder/test/folder/contractb.js: -------------------------------------------------------------------------------- 1 | const ContractB = artifacts.require("ContractB"); 2 | 3 | contract("contractB [ @skipForCoverage ]", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractB.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | }); 16 | -------------------------------------------------------------------------------- /test/sources/projects/tests-folder/test/folder/contractc.js: -------------------------------------------------------------------------------- 1 | const ContractC = artifacts.require("ContractC"); 2 | 3 | contract("contractc", function(accounts) { 4 | let instance; 5 | 6 | before(async () => instance = await ContractC.new()) 7 | 8 | it('sends', async function(){ 9 | await instance.sendFn(); 10 | }); 11 | 12 | it('calls', async function(){ 13 | await instance.callFn(); 14 | }) 15 | 16 | it('sends', async function(){ 17 | await instance.sendFn(); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /test/sources/projects/viem/.solcover.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | silent: process.env.SILENT ? true : false, 3 | skipFiles: [], 4 | istanbulReporter: ['json-summary', 'text'] 5 | } 6 | -------------------------------------------------------------------------------- /test/sources/projects/viem/contracts/Lock.sol: -------------------------------------------------------------------------------- 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 | } 32 | -------------------------------------------------------------------------------- /test/sources/projects/viem/hardhat.config.js: -------------------------------------------------------------------------------- 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 | }; 21 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Empty.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Empty { 4 | } -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Events.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Events { 4 | uint x = 0; 5 | bool a; 6 | bool b; 7 | event LogEventOne( uint x, address y); 8 | event LogEventTwo( uint x, address y); 9 | 10 | function test(uint val) public { 11 | // Assert / Require events 12 | require(true); 13 | 14 | // Contract Events 15 | emit LogEventOne(100, msg.sender); 16 | x = x + val; 17 | emit LogEventTwo(200, msg.sender); 18 | 19 | // Branch events 20 | if (true) { 21 | a = false; 22 | } else { 23 | b = false; 24 | } 25 | } 26 | 27 | function getX() public view returns (uint){ 28 | return x; 29 | } 30 | } -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Expensive.sol: -------------------------------------------------------------------------------- 1 | // Cost to deploy Expensive: 0x4e042f 2 | // Block gas limit is: 0x47e7c4 3 | // Should throw out of gas on unmodified truffle 4 | // Should pass solcover truffle 5 | pragma solidity >=0.8.0 <0.9.0; 6 | 7 | contract Expensive { 8 | mapping (uint => address) map; 9 | constructor() public { 10 | for(uint i = 0; i < 1000; i++ ){ 11 | map[i] = address(this); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Migrations { 4 | address public owner; 5 | 6 | uint public last_completed_migration; 7 | 8 | modifier restricted() { 9 | if (msg.sender == owner) { _; } 10 | } 11 | 12 | constructor() public { 13 | owner = msg.sender; 14 | } 15 | 16 | function setCompleted(uint completed) public restricted { 17 | last_completed_migration = completed; 18 | } 19 | 20 | function upgrade(address new_address) public restricted { 21 | Migrations upgraded = Migrations(new_address); 22 | upgraded.setCompleted(last_completed_migration); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Modified.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Modified { 4 | uint counter; 5 | 6 | modifier m { 7 | _; 8 | } 9 | 10 | // When modifier coverage is on, branch cov should be 50% 11 | // When off: 100% 12 | function set(uint i) 13 | m 14 | public 15 | payable 16 | virtual 17 | { 18 | counter = counter + i; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/OnlyCall.sol: -------------------------------------------------------------------------------- 1 | /** 2 | * This contract contains a single function that is accessed using method.call 3 | * With an unpatched testrpc it should not generate any events. 4 | */ 5 | pragma solidity >=0.8.0 <0.9.0; 6 | 7 | contract OnlyCall { 8 | function addTwo(uint val) public pure returns (uint){ 9 | val = val + 2; 10 | return val; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Owned.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Owned { 4 | constructor() public { owner = msg.sender; } 5 | address owner; 6 | } 7 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Proxy.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | import "./Owned.sol"; 4 | 5 | contract Proxy is Owned { 6 | function isOwner() public view returns (bool) { 7 | if (msg.sender == owner) { 8 | return true; 9 | } else { 10 | return false; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Simple.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Simple { 4 | uint x = 0; 5 | 6 | function test(uint val) public { 7 | x = x + val; 8 | } 9 | 10 | function getX() public view returns (uint){ 11 | return x; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/SimpleError.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | address a; 5 | address a; 6 | } 7 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Unparseable.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Unparseable { 4 | uint x = 0; 5 | 6 | function test(uint val) public { 7 | x = x + val; 8 | } 9 | 10 | function getX() public view returns (uint){ 11 | return x; 12 | 13 | // Missing a bracket! 14 | } 15 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/Wallet.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Wallet { 4 | 5 | event Deposit(address indexed _sender, uint _value); 6 | 7 | function transferPayment(uint payment, address payable recipient) public { 8 | recipient.transfer(payment); 9 | } 10 | 11 | function sendPayment(uint payment, address payable recipient) public { 12 | require(recipient.send(payment), 'sendPayment failed'); 13 | } 14 | 15 | function getBalance() public view returns(uint){ 16 | return address(this).balance; 17 | } 18 | 19 | receive() external payable 20 | { 21 | if (msg.value > 0) 22 | emit Deposit(msg.sender, msg.value); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/app/auction.vy: -------------------------------------------------------------------------------- 1 | # Open Auction 2 | 3 | # Auction params 4 | # Beneficiary receives money from the highest bidder 5 | beneficiary: public(address) 6 | auctionStart: public(uint256) 7 | auctionEnd: public(uint256) 8 | 9 | # Current state of auction 10 | highestBidder: public(address) 11 | highestBid: public(uint256) 12 | 13 | # Set to true at the end, disallows any change 14 | ended: public(bool) 15 | 16 | # Keep track of refunded bids so we can follow the withdraw pattern 17 | pendingReturns: public(HashMap[address, uint256]) 18 | 19 | # Create a simple auction with `_bidding_time` 20 | # seconds bidding time on behalf of the 21 | # beneficiary address `_beneficiary`. 22 | @external 23 | def __init__(_beneficiary: address, _bidding_time: uint256): 24 | self.beneficiary = _beneficiary 25 | self.auctionStart = block.timestamp 26 | self.auctionEnd = self.auctionStart + _bidding_time 27 | 28 | # Bid on the auction with the value sent 29 | # together with this transaction. 30 | # The value will only be refunded if the 31 | # auction is not won. 32 | @external 33 | @payable 34 | def bid(): 35 | # Check if bidding period is over. 36 | assert block.timestamp < self.auctionEnd 37 | # Check if bid is high enough 38 | assert msg.value > self.highestBid 39 | # Track the refund for the previous high bidder 40 | self.pendingReturns[self.highestBidder] += self.highestBid 41 | # Track new high bid 42 | self.highestBidder = msg.sender 43 | self.highestBid = msg.value 44 | 45 | # Withdraw a previously refunded bid. The withdraw pattern is 46 | # used here to avoid a security issue. If refunds were directly 47 | # sent as part of bid(), a malicious bidding contract could block 48 | # those refunds and thus block new higher bids from coming in. 49 | @external 50 | def withdraw(): 51 | pending_amount: uint256 = self.pendingReturns[msg.sender] 52 | self.pendingReturns[msg.sender] = 0 53 | send(msg.sender, pending_amount) 54 | 55 | # End the auction and send the highest bid 56 | # to the beneficiary. 57 | @external 58 | def endAuction(): 59 | # It is a good guideline to structure functions that interact 60 | # with other contracts (i.e. they call functions or send Ether) 61 | # into three phases: 62 | # 1. checking conditions 63 | # 2. performing actions (potentially changing conditions) 64 | # 3. interacting with other contracts 65 | # If these phases are mixed up, the other contract could call 66 | # back into the current contract and modify the state or cause 67 | # effects (Ether payout) to be performed multiple times. 68 | # If functions called internally include interaction with external 69 | # contracts, they also have to be considered interaction with 70 | # external contracts. 71 | 72 | # 1. Conditions 73 | # Check if auction endtime has been reached 74 | assert block.timestamp >= self.auctionEnd 75 | # Check if this function has already been called 76 | assert not self.ended 77 | 78 | # 2. Effects 79 | self.ended = True 80 | 81 | # 3. Interaction 82 | send(self.beneficiary, self.highestBid) -------------------------------------------------------------------------------- /test/sources/solidity/contracts/assembly/if.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | 5 | function isWhitelisted 6 | ( 7 | address _address 8 | ) 9 | public 10 | view 11 | returns (bool _isWhitelisted) 12 | { 13 | bytes4 _signature = bytes4(keccak256("whitelisted(address)")); 14 | address _whitelistContract = address(this); 15 | 16 | assembly { 17 | let _pointer := mload(0x40) // Set _pointer to free memory pointer 18 | mstore(_pointer, _signature) // Store _signature at _pointer 19 | mstore(add(_pointer, 0x04), _address) // Store _address at _pointer. Offset by 4 bytes for previously stored _signature 20 | 21 | // staticcall(g, a, in, insize, out, outsize) => returns 0 on error, 1 on success 22 | let result := staticcall( 23 | gas(), // g = gas: whatever was passed already 24 | _whitelistContract, // a = address: _whitelist address assigned from getContractAddress() 25 | _pointer, // in = mem in mem[in..(in+insize): set to _pointer pointer 26 | 0x24, // insize = mem insize mem[in..(in+insize): size of signature (bytes4) + bytes32 = 0x24 27 | _pointer, // out = mem out mem[out..(out+outsize): output assigned to this storage address 28 | 0x20 // outsize = mem outsize mem[out..(out+outsize): output should be 32byte slot (bool size = 0x01 < slot size 0x20) 29 | ) 30 | 31 | // Revert if not successful 32 | if iszero(result) { 33 | revert(0, 0) 34 | } 35 | 36 | _isWhitelisted := mload(_pointer) // Assign result to returned value 37 | mstore(0x40, add(_pointer, 0x24)) // Advance free memory pointer by largest _pointer size 38 | } 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/assembly/spaces-in-function.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | assembly { 6 | function power(base, exponent) -> result { 7 | switch exponent 8 | case 0 { result := 1 } 9 | case 1 { result := base } 10 | default { 11 | result := power(mul(base, base), div(exponent, 2)) 12 | switch mod(exponent, 2) 13 | case 1 { result := mul(base, result) } 14 | } 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/assert/Assert.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(bool test) public { 5 | assert(test); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/assert/Require-fn-reason.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function getBool(bool _b) public pure returns (bool){ 5 | return _b; 6 | } 7 | 8 | function a(bool _a) public { 9 | require(getBool(_a), "mi ritrovai per una selva oscura"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/assert/Require-fn.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function getBool(bool _b) public pure returns (bool){ 5 | return _b; 6 | } 7 | 8 | function a(bool _a) public { 9 | require(getBool(_a)); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/assert/RequireMultiline.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(bool _a, bool _b, bool _c) public { 5 | require(_a && 6 | _b && 7 | _c); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/comments/postContractComment.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test {//Comment immediately after contract declaration 4 | function a(bool test) public { 5 | uint8 x = 1; 6 | uint8 y = 2; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/comments/postFunctionDeclarationComment.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(bool test) public {//Comment immediately after function declaration 5 | } 6 | function b(bool test) public { 7 | uint8 x=1; 8 | }//Comment immediately after function closes 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/comments/postIfStatementComment.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(bool x) public { 5 | int y; 6 | if (x){//Comment straight after { 7 | y = 1; 8 | }else{//Comment straight after { 9 | y = 2; 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/comments/postLineComment.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(bool test) public { 5 | uint x = 1;//Comment immediately after line 6 | uint y = 2; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/and-condition.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = true; 6 | bool y = true; 7 | x && y ? y = false : y = false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/chained-multiline.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | int min = 1; 6 | int max = 2; 7 | int value = 3; 8 | value < min 9 | ? min 10 | : value > max 11 | ? max 12 | : value; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/chained-singleline.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | int min = 1; 6 | int max = 2; 7 | int value = 3; 8 | value < min ? min : value > max ? max : value; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/chained-true.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | int min = 1; 6 | int max = 2; 7 | int value = 3; 8 | value < min 9 | ? value > max 10 | ? max 11 | : value 12 | : min; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/chained-with-parens.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | int min = 1; 6 | int max = 2; 7 | int value = 3; 8 | (value < min) ? min : (value > max) ? max : value; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/declarative-exp-assignment-alternate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = false; 6 | bool y = false; 7 | bool z = (x) ? false : true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/identifier-assignment-alternate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = false; 6 | bool y = false; 7 | bool z = false; 8 | z = (x) ? false : true; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/mapping-assignment.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | struct Vote { 5 | mapping (address => uint) voted; 6 | } 7 | 8 | Vote vote; 9 | 10 | function a() public { 11 | bool isYay = false; 12 | vote.voted[msg.sender] = isYay ? 1 : 2; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/multiline-alternate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = false; 6 | bool y = false; 7 | (x) 8 | ? y = false 9 | : y = false; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/multiline-consequent.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = true; 6 | bool y = false; 7 | (x) 8 | ? y = false 9 | : y = false; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/or-always-false-condition.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = false; 6 | bool y = false; 7 | (x || y) ? y = false : y = false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/or-condition.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = false; 6 | bool y = true; 7 | (x || y) ? y = false : y = false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/sameline-alternate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = false; 6 | bool y = false; 7 | (x) ? y = false : y = false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/sameline-consequent.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = true; 6 | bool y = false; 7 | (x) ? y = false : y = false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/ternary-with-unbracketed-else.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | int i = 0; 6 | if (false) {} else i == 0 ? i = 0 : i--; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/unbracketed-condition.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = true; 6 | bool y = false; 7 | x ? y = false : y = false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/unbracketed-or-condition.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = false; 6 | bool y = true; 7 | x || y ? y = false : y = false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/conditional/variable-decl-assignment-alternate.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool x = false; 6 | bool y = false; 7 | bool z = (x) ? false : true; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/diff/addition.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Old { 4 | uint public y; 5 | 6 | function a() public { 7 | bool x = true; 8 | } 9 | 10 | function b() external { 11 | bool x = true; 12 | } 13 | 14 | function c() external { 15 | bool x = true; 16 | } 17 | } 18 | 19 | contract New { 20 | uint public y; 21 | 22 | function a() public { 23 | bool x = true; 24 | } 25 | 26 | function b() external { 27 | bool x = true; 28 | } 29 | 30 | function c() external { 31 | bool x = true; 32 | } 33 | 34 | function d() external { 35 | bool x = true; 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/diff/events.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Old { 4 | uint y; 5 | 6 | event Evt(uint x, bytes8 y); 7 | 8 | function a() public { 9 | bool x = true; 10 | } 11 | } 12 | 13 | contract New { 14 | uint y; 15 | 16 | function a() public { 17 | bool x = true; 18 | } 19 | 20 | event aEvt(bytes8); 21 | event _Evt(bytes8 x, bytes8 y); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/diff/no-change.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Old { 4 | uint y; 5 | 6 | function a() public { 7 | bool x = true; 8 | } 9 | 10 | function b() external { 11 | bool x = true; 12 | } 13 | 14 | function c() external { 15 | bool x = true; 16 | } 17 | } 18 | 19 | contract New { 20 | uint y; 21 | 22 | function a() public { 23 | bool x = true; 24 | } 25 | 26 | function b() external { 27 | bool x = true; 28 | } 29 | 30 | function c() external { 31 | bool x = true; 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/diff/param-change.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Old { 4 | uint y; 5 | 6 | function a() public { 7 | bool x = true; 8 | } 9 | 10 | function b() external { 11 | bool x = true; 12 | } 13 | 14 | function c() external { 15 | bool x = true; 16 | } 17 | } 18 | 19 | contract New { 20 | uint y; 21 | 22 | function a() public { 23 | bool x = true; 24 | } 25 | 26 | function b(bytes8 z) external { 27 | bool x = true; 28 | } 29 | 30 | function c(uint q, uint r) external { 31 | bool x = true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/diff/removal.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Old { 4 | uint y; 5 | 6 | function a() public { 7 | bool x = true; 8 | } 9 | 10 | function b() external { 11 | bool x = true; 12 | } 13 | 14 | function c() external { 15 | bool x = true; 16 | } 17 | } 18 | 19 | contract New { 20 | uint y; 21 | 22 | function a() public { 23 | bool x = true; 24 | } 25 | 26 | function b() external { 27 | bool x = true; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/diff/reorder.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Old { 4 | uint y; 5 | 6 | function a() public { 7 | bool x = true; 8 | } 9 | 10 | function b() external { 11 | bool x = true; 12 | } 13 | 14 | function c() external { 15 | bool x = true; 16 | } 17 | } 18 | 19 | contract New { 20 | uint y; 21 | 22 | function c() external { 23 | bool x = true; 24 | } 25 | 26 | function a() public { 27 | bool x = true; 28 | } 29 | 30 | function b() external { 31 | bool x = true; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/diff/return-sig.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Old { 4 | function a() public view returns (uint) { 5 | return 1; 6 | } 7 | } 8 | 9 | contract New { 10 | function a() public view returns (bool) { 11 | return true; 12 | } 13 | 14 | function e() public view returns (uint8[2] memory) { 15 | return [5,7]; 16 | } 17 | 18 | function f() public view returns (uint8[2] memory, uint) { 19 | return ([5,7], 7); 20 | } 21 | 22 | function g() public view returns (uint8[3] memory) { 23 | return [5,7,8]; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/diff/state-mod-change.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Old { 4 | function a() public { 5 | bool x = true; 6 | } 7 | } 8 | 9 | contract New { 10 | function a() public view returns (bool) { 11 | return true; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/expressions/new-expression.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | new Test2(x); 6 | } 7 | } 8 | contract Test2 { 9 | constructor(uint x) public { 10 | x+1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/expressions/single-binary-expression.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | x+1; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/function/abstract.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | abstract contract Test { 4 | function abstractFn(uint x) virtual public; 5 | } 6 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/function/empty-body.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function emptyBody(uint x) public {} 5 | } 6 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/function/function-call.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | // This test verifies that an invoked function gets logged as a statement 4 | contract Test { 5 | function loggedAsStatement(uint x) public {} 6 | function a() public { 7 | loggedAsStatement(5); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/function/function.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(bytes32 x) public { 5 | x; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/function/modifier.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | modifier b(){ 5 | uint y; 6 | _; 7 | } 8 | function a(uint x) b public { 9 | x; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/function/multiple.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function f1(uint x) public { 5 | x = 1; 6 | } 7 | 8 | function f2(uint x) public { x = 2; } 9 | 10 | address a; 11 | 12 | function f3(uint y) public { 13 | y = 1; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/else-if-unbracketed-multi.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | mapping (address => uint) balances; 5 | 6 | event Transfer(address indexed _from, address indexed _to, uint256 _value); 7 | 8 | constructor() public { 9 | balances[tx.origin] = 10000; 10 | } 11 | 12 | function sendCoin(address receiver, uint amount) public returns(bool sufficient) { 13 | if (balances[msg.sender] < amount) 14 | return false; 15 | else if (amount == 1) 16 | return false; 17 | else if (amount == 2 || amount == 3 || amount == 4) 18 | return false; 19 | else if (amount == 5) 20 | return false; 21 | else if (amount == 1) 22 | return false; 23 | else if (amount == 2 || amount == 3 || amount == 4) 24 | return false; 25 | else if (amount == 5) 26 | return false; 27 | else if (amount == 1) 28 | return false; 29 | else if (amount == 2 || amount == 3 || amount == 4) 30 | return false; 31 | else if (amount == 5) 32 | return false; 33 | else if (amount == 1) 34 | return false; 35 | else if (amount == 2 || amount == 3 || amount == 4) 36 | return false; 37 | else if (amount == 5) 38 | return false; 39 | else if (amount == 1) 40 | return false; 41 | else if (amount == 2 || amount == 3 || amount == 4) 42 | return false; 43 | else if (amount == 5) 44 | return false; 45 | 46 | balances[msg.sender] -= amount; 47 | balances[receiver] += amount; 48 | emit Transfer(msg.sender, receiver, amount); 49 | 50 | if(balances[receiver] >= amount) 51 | sufficient = true; 52 | } 53 | 54 | function getBalance(address addr) public view returns(uint) { 55 | return balances[addr]; 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/else-if-without-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1) { 6 | revert(); 7 | } else if (x == 50) 8 | x = 5; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/else-with-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1) { 6 | revert(); 7 | } else { 8 | x = 5; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/else-without-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1) { 6 | revert(); 7 | } else 8 | x = 5; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/if-else-no-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x,uint y, uint z) public { 5 | if (x==y) 6 | x = 5; 7 | else 8 | x = 7; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/if-elseif-else.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x,uint y, uint z) public { 5 | if (x == y) { 6 | z = 0; 7 | } else if (x == 2) { 8 | z = 1; 9 | } else { 10 | z = 2; 11 | } 12 | 13 | if (x == y) { 14 | z = 0; 15 | } else if (x == 2) { 16 | z = 1; 17 | } else { 18 | z = 2; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/if-no-brackets-multiline.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1) 6 | x = 2; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/if-no-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1) x = 2; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/if-with-brackets-multiline.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1) { 6 | x = 3; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/if-with-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1) {x = 3;} 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/if/nested-if-missing-else.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x,uint y, uint z) public { 5 | if (x==y){ 6 | } else if (x==2){ 7 | if (y==z){ 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/loops/for-no-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | for(uint x = 0; x < 10; x++) 6 | keccak256(abi.encodePacked(x)); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/loops/for-with-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | for(uint x = 0; x < 10; x++){ 6 | keccak256(abi.encodePacked(x)); 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/loops/while-no-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool t = true; 6 | while(t) 7 | t = false; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/loops/while-with-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | bool t = true; 6 | while(t){ 7 | t = false; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/both-branches.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | bool flag = true; 5 | 6 | modifier m { 7 | require(flag); 8 | _; 9 | } 10 | 11 | function flip() public { 12 | flag = !flag; 13 | } 14 | 15 | function a() m public { 16 | uint x = 5; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/constructor.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Parent { 4 | string public name; 5 | 6 | constructor(string memory _name) public { 7 | name = _name; 8 | } 9 | } 10 | 11 | contract Test is Parent { 12 | constructor() public Parent("Test") {} 13 | 14 | function a() public { 15 | uint x = 5; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/duplicate-mods-same-fn.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | modifier m(string memory val) { 5 | _; 6 | } 7 | 8 | function a() 9 | m('ETH') 10 | m('BTC') 11 | public 12 | { 13 | uint x = 5; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/listed-modifiers.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | modifier mmm { 5 | require(true); 6 | _; 7 | } 8 | 9 | modifier nnn { 10 | require(true); 11 | _; 12 | } 13 | 14 | function a() 15 | mmm 16 | nnn 17 | public 18 | { 19 | uint x = 5; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/multiple-fns-same-mod.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | modifier mmm { 5 | require(true); 6 | _; 7 | } 8 | 9 | function a() mmm public { 10 | uint x = 5; 11 | } 12 | 13 | function b() mmm public { 14 | uint x = 5; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/multiple-mods-same-fn.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | modifier mmm { 5 | require(true); 6 | _; 7 | } 8 | 9 | modifier nnn { 10 | require(true); 11 | _; 12 | } 13 | 14 | function a() mmm nnn public { 15 | uint x = 5; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/override-function.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | abstract contract IM { 4 | function a() payable virtual public; 5 | } 6 | 7 | contract Test is IM { 8 | modifier m { 9 | require(true); 10 | _; 11 | } 12 | 13 | function a() payable m public override { 14 | uint x = 5; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/postconditions.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | bool precondition = true; 5 | bool postcondition = true; 6 | 7 | modifier m { 8 | require(precondition); 9 | _; 10 | require(postcondition); 11 | } 12 | 13 | function flip_precondition() public { 14 | precondition = !precondition; 15 | } 16 | 17 | function flip_postcondition() public { 18 | postcondition = !postcondition; 19 | } 20 | 21 | function a() m public { 22 | uint x = 5; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/reverting-fn.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | bool flag = true; 5 | 6 | modifier m { 7 | require(flag); 8 | _; 9 | } 10 | 11 | function a(bool success) m public { 12 | require(success); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/reverting-neighbor.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | bool flag = true; 5 | 6 | modifier m { 7 | require(true); 8 | _; 9 | } 10 | 11 | modifier n { 12 | require(flag); 13 | _; 14 | } 15 | 16 | function flip() public { 17 | flag = !flag; 18 | } 19 | 20 | function a() m n public { 21 | uint x = 5; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/same-contract-fail.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | modifier m { 5 | require(false); 6 | _; 7 | } 8 | 9 | function a() m public { 10 | uint x = 5; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/modifiers/same-contract-pass.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | modifier m { 5 | require(true); 6 | _; 7 | } 8 | 9 | function a() m public { 10 | uint x = 5; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/and-or-brackets.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if ((x == 1) && (x == 2 || true)) { 6 | /* ignore */ 7 | } else { 8 | revert(); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/and-or.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1 && true || x == 2) { 6 | /* ignore */ 7 | } else { 8 | revert(); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/bzx-or.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function isFalse(uint _a, uint _b) public pure returns (bool){ 5 | return false; 6 | } 7 | 8 | function a(uint x) public { 9 | require(( 10 | x == 1 && 11 | x == 2 ) || 12 | !isFalse( 13 | x, 14 | 3 15 | ), 16 | "unhealthy position" 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/if-or.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x == 1 || x == 2) { 6 | /* ignore */ 7 | } else { 8 | revert(); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/multi-or.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if ((x == 1) || (x == 2 || true)) { 6 | /* ignore */ 7 | } else { 8 | revert(); 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/require-multiline-or.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | require( 6 | x == 1 || 7 | x == 2 || 8 | x == 3 9 | ); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/require-or.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | require(x == 1 || x == 2); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/return-or.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public pure returns (bool) { 5 | return (x == 1 && true) || (x == 2 && true); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/or/while-or.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | uint counter; 6 | while( (x == 1 || x == 2) && counter < 2 ){ 7 | counter++; 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/return/empty-return.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public pure { 5 | return; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/return/return.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public returns (bool) { 5 | return true; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/return/ternary-return.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public pure returns (uint) { 5 | return x > 3 ? x : 1; 6 | } 7 | 8 | function b(uint x) public pure returns (uint) { 9 | return (x > 3) ? x : 1; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/emit-coverage.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | event TestEvent(); 5 | function a(uint x) public { 6 | emit TestEvent(); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/emit-instrument.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | event TestEvent(); 5 | function a(uint x) public { 6 | if(true) 7 | emit TestEvent(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/empty-contract-ala-melonport.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test {} 4 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/empty-contract-body.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | } 5 | 6 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/fn-argument-multiline.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | 5 | function multiline( 6 | uint a, 7 | uint b, 8 | uint c, 9 | bytes32 d) public 10 | { 11 | uint x = a; 12 | } 13 | 14 | constructor() public { 15 | multiline( 16 | 1, 17 | 2, 18 | 3, 19 | keccak256(abi.encodePacked('hello')) 20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/fn-argument.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(bytes32 x) public { 5 | x; 6 | } 7 | 8 | function b () public { 9 | a(keccak256(abi.encodePacked(uint256(0)))); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/fn-struct.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | struct Fn { 5 | function(bytes32) internal view returns(bool) startConditions; 6 | function(bytes32) internal view endConditions; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/interface.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | interface IInterface { 4 | event Assign(address indexed token, address indexed from, address indexed to, uint256 amount); 5 | event Withdraw(address indexed token, address indexed from, address indexed to, uint256 amount); 6 | 7 | // TODO: remove init from the interface, all the initialization should be outside the court 8 | function init(address _owner) external; 9 | 10 | function assign(uint _token, address _to, uint256 _amount) external; 11 | function withdraw(uint _token, address _to, uint256 _amount) external; 12 | } 13 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/interpolation.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Interpolated { 4 | constructor(string memory a) public { 5 | string memory b = a; 6 | } 7 | } 8 | 9 | contract TestA is Interpolated("abc{defg}"){ 10 | function a(uint x) public { 11 | uint y = x; 12 | } 13 | } 14 | 15 | contract TestB is Interpolated { 16 | constructor(uint x) public Interpolated("abc{defg}") { 17 | uint y = x; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/library.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | /* 4 | Library and Using statements: invoking 'Test.not' should generate line and statement 5 | coverage for L 9, 10, and 19, plus function coverage for 'flip' and 'not'. 6 | */ 7 | library Boolean { 8 | struct Value { bool val; } 9 | 10 | function flip(Value storage self) internal returns (bool) { 11 | self.val = !self.val; 12 | return self.val; 13 | } 14 | } 15 | 16 | contract Test { 17 | using Boolean for Boolean.Value; 18 | Boolean.Value b; 19 | 20 | function not() public returns (bool) { 21 | return b.flip(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/multiple.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | keccak256(abi.encodePacked(x)); 6 | keccak256(abi.encodePacked(uint256(0))); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/post-close-brace.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | if (x>1){ 6 | x=3; 7 | } 8 | x=2; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/require.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | require(true); 6 | require(true) ; 7 | require(true) ; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/single.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a(uint x) public { 5 | keccak256(abi.encodePacked(x)); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/stack-too-deep.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | // 15 fn args + 1 local variable assignment 5 | // will normally compile w/out stack too deep 6 | // error. 7 | function a( 8 | uint _a, 9 | uint _b, 10 | uint _c, 11 | uint _d, 12 | uint _e, 13 | uint _f, 14 | uint _g, 15 | uint _h, 16 | uint _i, 17 | uint _j, 18 | uint _k, 19 | uint _l, 20 | uint _m, 21 | uint _n, 22 | uint _o 23 | ) public { 24 | uint x = _a; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/tuple.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | 5 | function returnTuple() public returns (uint x, uint y) { 6 | return (10, 20); 7 | } 8 | 9 | function a() public { 10 | (uint _a, uint _b) = (10, 20); 11 | (_a, _b) = returnTuple(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/type-keyword.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Account { 4 | address public owner; 5 | 6 | constructor(address payable _owner) public { 7 | owner = _owner; 8 | } 9 | 10 | function setOwner(address _owner) public { 11 | require(msg.sender == owner); 12 | owner = _owner; 13 | } 14 | 15 | function destroy(address payable recipient) public { 16 | require(msg.sender == owner); 17 | selfdestruct(recipient); 18 | } 19 | } 20 | 21 | contract Factory { 22 | 23 | bytes32 private contractCodeHash; 24 | 25 | constructor() public { 26 | contractCodeHash = keccak256( 27 | type(Account).creationCode 28 | ); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/statements/unary.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function a() public { 5 | uint x = 1; 6 | x++; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/try/try-catch-empty-blocks.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function op(bool y) external { 5 | require(y); 6 | } 7 | 8 | function a(bool x) external { 9 | try this.op(x) { } catch { } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/try/try-error-block.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function op(bool y) external returns (uint){ 5 | require(y, "sorry"); 6 | return 1; 7 | } 8 | 9 | function a(bool x) external returns (uint) { 10 | try this.op(x) returns (uint v) { 11 | return v; 12 | } catch Error(string memory /*reason*/) { 13 | return 0; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/try/try-multi-block.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function op(uint y) external returns (uint){ 5 | uint a = 100; 6 | uint b = 0; 7 | 8 | if (y == 0) 9 | return 0; 10 | if (y == 1) 11 | require(false, 'sorry'); 12 | if (y == 2) 13 | uint x = (a / b); 14 | if (y == 3) 15 | revert(); 16 | } 17 | 18 | function a(uint x) external returns (uint) { 19 | try this.op(x) returns (uint v) { 20 | return 0; 21 | } catch Error(string memory /*reason*/) { 22 | return 1; 23 | } catch Panic(uint /*errorCode*/) { 24 | return 2; 25 | } catch (bytes memory /*lowLevelData*/) { 26 | return 3; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/try/try-panic-block.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function op(bool y) external returns (uint){ 5 | uint x = 100 / 0; 6 | return x; 7 | } 8 | 9 | function a(bool x) external pure returns (uint) { 10 | try this.op(x) returns (uint v) { 11 | return v; 12 | } catch Panic(uint /*errorCode*/) { 13 | return 0; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /test/sources/solidity/contracts/try/try-revert-block.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract Test { 4 | function op(bool y) external returns (uint){ 5 | if (y == false) revert(); 6 | } 7 | 8 | function a(bool x) external pure returns (uint) { 9 | try this.op(x) returns (uint v) { 10 | return v; 11 | } catch (bytes memory /*lowLevelData*/) { 12 | return 0; 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/sources/solidity/external/CLibrary.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | library CLibrary { 4 | uint constant x = 1; 5 | function a() public view returns (uint) { 6 | return x; 7 | } 8 | } -------------------------------------------------------------------------------- /test/sources/solidity/external/Face.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | interface Face { 4 | function stare(uint a, uint b) external; 5 | function cry() external; 6 | } -------------------------------------------------------------------------------- /test/sources/solidity/external/PureView.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.8.0 <0.9.0; 2 | 3 | contract PureView { 4 | 5 | // Make sure we aren't corrupting anything with the replace 6 | uint notpureview = 5; 7 | 8 | // Abstract functions to inherit from an uninstrumented, imported file. 9 | function bePure(uint a, uint b) public pure returns (uint); 10 | function beView() public view returns (uint); 11 | 12 | function inheritedPure(uint a, uint b) public pure returns(uint){ 13 | return a + b; 14 | } 15 | 16 | function inheritedView() public view returns (uint){ 17 | return notpureview; 18 | } 19 | } -------------------------------------------------------------------------------- /test/units/api.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | const util = require('./../util/util.js'); 4 | const API = require('./../../api.js'); 5 | const utils = require('./../../utils.js'); 6 | 7 | describe('api', () => { 8 | let opts; 9 | 10 | beforeEach(() => opts = {silent: true}) 11 | 12 | it('getInstrumentationData', function(){ 13 | const api = new API(opts); 14 | const canonicalPath = 'statements/single.sol' 15 | const source = util.getCode(canonicalPath); 16 | 17 | api.instrument([{ 18 | source: source, 19 | canonicalPath: canonicalPath 20 | }]); 21 | 22 | const data = api.getInstrumentationData(); 23 | 24 | const hash = Object.keys(data)[0]; 25 | assert(data[hash].hits === 0); 26 | }); 27 | 28 | it('setInstrumentationData', function(){ 29 | let api = new API(opts); 30 | 31 | const canonicalPath = 'statements/single.sol' 32 | const source = util.getCode(canonicalPath); 33 | 34 | api.instrument([{ 35 | source: source, 36 | canonicalPath: canonicalPath 37 | }]); 38 | 39 | const cloneA = api.getInstrumentationData(); 40 | const hash = Object.keys(cloneA)[0]; 41 | 42 | // Verify cloning 43 | cloneA[hash].hits = 5; 44 | const cloneB = api.getInstrumentationData(); 45 | assert(cloneB[hash].hits === 0); 46 | 47 | // Verify setting 48 | api = new API(opts); 49 | api.instrument([{ 50 | source: source, 51 | canonicalPath: canonicalPath 52 | }]); 53 | 54 | api.setInstrumentationData(cloneA); 55 | const cloneC = api.getInstrumentationData(); 56 | assert(cloneC[hash].hits === 5); 57 | }); 58 | 59 | it('utils', async function(){ 60 | assert(utils.assembleFiles !== undefined) 61 | assert(utils.checkContext !== undefined) 62 | assert(utils.finish !== undefined) 63 | assert(utils.getTempLocations !== undefined) 64 | assert(utils.setupTempFolders !== undefined) 65 | assert(utils.loadSource !== undefined) 66 | assert(utils.loadSolcoverJS !== undefined) 67 | assert(utils.save !== undefined) 68 | }); 69 | }) 70 | -------------------------------------------------------------------------------- /test/units/assembly.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const util = require('./../util/util.js'); 3 | 4 | describe('assembly expressions', () => { 5 | 6 | it('should compile after instrumenting an assembly function with spaces in parameters', () => { 7 | const info = util.instrumentAndCompile('assembly/spaces-in-function'); 8 | util.report(info.solcOutput.errors); 9 | }); 10 | 11 | it('should compile after instrumenting an assembly if statement', () => { 12 | const info = util.instrumentAndCompile('assembly/if'); 13 | util.report(info.solcOutput.errors); 14 | }); 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /test/units/comments.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const util = require('./../util/util.js'); 3 | 4 | describe('comments', () => { 5 | 6 | it('should cover functions even if comments are present immediately after the opening {', () => { 7 | const info = util.instrumentAndCompile('comments/postFunctionDeclarationComment'); 8 | util.report(info.solcOutput.errors); 9 | }); 10 | 11 | it('should cover lines even if comments are present', () => { 12 | const info = util.instrumentAndCompile('comments/postLineComment'); 13 | assert.deepEqual([6, 5], info.instrumented.runnableLines); 14 | util.report(info.solcOutput.errors); 15 | }); 16 | 17 | it('should cover contracts even if comments are present', () => { 18 | const info = util.instrumentAndCompile('comments/postContractComment'); 19 | util.report(info.solcOutput.errors); 20 | }); 21 | 22 | it('should cover if statements even if comments are present immediately after opening { ', () => { 23 | const info = util.instrumentAndCompile('comments/postIfStatementComment'); 24 | util.report(info.solcOutput.errors); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /test/units/expressions.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const util = require('./../util/util.js'); 3 | 4 | describe('generic expressions / misc', () => { 5 | it('should compile after instrumenting a single binary expression', () => { 6 | const info = util.instrumentAndCompile('expressions/single-binary-expression'); 7 | util.report(info.solcOutput.errors); 8 | }); 9 | 10 | it('should compile after instrumenting a new expression', () => { 11 | const info = util.instrumentAndCompile('expressions/new-expression'); 12 | util.report(info.solcOutput.errors); 13 | }); 14 | 15 | it('should compile after instrumenting function that returns true', () => { 16 | const info = util.instrumentAndCompile('return/return'); 17 | util.report(info.solcOutput.errors); 18 | }); 19 | 20 | it('should compile after instrumenting function that returns void', () => { 21 | const info = util.instrumentAndCompile('return/empty-return'); 22 | util.report(info.solcOutput.errors); 23 | }); 24 | 25 | it('should compile after instrumenting function that returns via ternary conditional', () => { 26 | const info = util.instrumentAndCompile('return/ternary-return'); 27 | util.report(info.solcOutput.errors); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /test/units/function.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const util = require('./../util/util.js'); 3 | const Coverage = require('./../../lib/coverage'); 4 | const Api = require('./../../lib/api') 5 | 6 | describe('function declarations', () => { 7 | let coverage; 8 | let api; 9 | 10 | before(async () => api = new Api({silent: true})); 11 | beforeEach(() => coverage = new Coverage()); 12 | after(async() => await api.finish()); 13 | 14 | it('should compile after instrumenting an ordinary function declaration', () => { 15 | const info = util.instrumentAndCompile('function/function'); 16 | util.report(info.solcOutput.errors); 17 | }); 18 | 19 | it('should compile after instrumenting an abstract function declaration', () => { 20 | const info = util.instrumentAndCompile('function/abstract'); 21 | util.report(info.solcOutput.errors); 22 | }); 23 | 24 | it('should compile after instrumenting a function declaration with an empty body', () => { 25 | const info = util.instrumentAndCompile('function/empty-body'); 26 | util.report(info.solcOutput.errors); 27 | }); 28 | 29 | it('should compile after instrumenting lots of declarations in row', () => { 30 | const info = util.instrumentAndCompile('function/multiple'); 31 | util.report(info.solcOutput.errors); 32 | }); 33 | 34 | it('should cover a simple invoked function call', async function() { 35 | const contract = await util.bootstrapCoverage('function/function-call', api, this.provider); 36 | coverage.addContract(contract.instrumented, util.filePath); 37 | await contract.instance.a(contract.gas); 38 | const mapping = coverage.generate(contract.data, util.pathPrefix); 39 | 40 | assert.deepEqual(mapping[util.filePath].l, { 41 | 7: 1, 42 | }); 43 | assert.deepEqual(mapping[util.filePath].b, {}); 44 | assert.deepEqual(mapping[util.filePath].s, { 45 | 1: 1, 46 | }); 47 | assert.deepEqual(mapping[util.filePath].f, { 48 | 1: 1, 49 | 2: 1, 50 | }); 51 | }); 52 | 53 | it('should cover a modifier used on a function', async function() { 54 | const contract = await util.bootstrapCoverage('function/modifier', api, this.provider); 55 | coverage.addContract(contract.instrumented, util.filePath); 56 | await contract.instance.a(0, contract.gas); 57 | const mapping = coverage.generate(contract.data, util.pathPrefix); 58 | 59 | assert.deepEqual(mapping[util.filePath].l, { 60 | 5: 1, 6: 1, 9: 1, 61 | }); 62 | assert.deepEqual(mapping[util.filePath].b, { 63 | 1: [1, 0] 64 | }); 65 | assert.deepEqual(mapping[util.filePath].s, { 66 | 1: 1 67 | }); 68 | assert.deepEqual(mapping[util.filePath].f, { 69 | 1: 1, 70 | 2: 1, 71 | }); 72 | }); 73 | }); 74 | 75 | -------------------------------------------------------------------------------- /test/units/loops.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const util = require('./../util/util.js'); 3 | const Coverage = require('./../../lib/coverage'); 4 | const Api = require('./../../lib/api') 5 | 6 | describe('for and while statements', () => { 7 | let coverage; 8 | let api; 9 | 10 | before(async () => api = new Api({silent: true})); 11 | beforeEach(() => coverage = new Coverage()); 12 | after(async() => await api.finish()); 13 | 14 | // Runs: a() => for(var x = 1; x < 10; x++){\n sha3(x);\n } 15 | it('should cover a for statement with a bracketed body (multiline)', async function() { 16 | const contract = await util.bootstrapCoverage('loops/for-with-brackets', api, this.provider); 17 | coverage.addContract(contract.instrumented, util.filePath); 18 | await contract.instance.a(contract.gas); 19 | const mapping = coverage.generate(contract.data, util.pathPrefix); 20 | 21 | assert.deepEqual(mapping[util.filePath].l, { 22 | 5: 1, 6: 10, 23 | }); 24 | assert.deepEqual(mapping[util.filePath].b, {}); 25 | assert.deepEqual(mapping[util.filePath].s, { 26 | 1: 1, 2: 10, 27 | }); 28 | assert.deepEqual(mapping[util.filePath].f, { 29 | 1: 1, 30 | }); 31 | }); 32 | 33 | // Runs: a() => for(var x = 1; x < 10; x++)\n sha3(x);\n 34 | it('should cover a for statement with an unbracketed body', async function() { 35 | const contract = await util.bootstrapCoverage('loops/for-no-brackets', api, this.provider); 36 | coverage.addContract(contract.instrumented, util.filePath); 37 | await contract.instance.a(contract.gas); 38 | const mapping = coverage.generate(contract.data, util.pathPrefix); 39 | 40 | assert.deepEqual(mapping[util.filePath].l, { 41 | 5: 1, 6: 10, 42 | }); 43 | assert.deepEqual(mapping[util.filePath].b, {}); 44 | assert.deepEqual(mapping[util.filePath].s, { 45 | 1: 1, 2: 10, 46 | }); 47 | assert.deepEqual(mapping[util.filePath].f, { 48 | 1: 1, 49 | }); 50 | }); 51 | 52 | // Runs: a() => var t = true;\n while(t){\n t = false;\n } 53 | it('should cover a while statement with an bracketed body (multiline)', async function() { 54 | const contract = await util.bootstrapCoverage('loops/while-with-brackets', api, this.provider); 55 | coverage.addContract(contract.instrumented, util.filePath); 56 | await contract.instance.a(contract.gas); 57 | const mapping = coverage.generate(contract.data, util.pathPrefix); 58 | 59 | assert.deepEqual(mapping[util.filePath].l, { 60 | 5: 1, 6: 1, 7: 1, 61 | }); 62 | assert.deepEqual(mapping[util.filePath].b, {}); 63 | assert.deepEqual(mapping[util.filePath].s, { 64 | 1: 1, 2: 1, 65 | }); 66 | assert.deepEqual(mapping[util.filePath].f, { 67 | 1: 1, 68 | }); 69 | }); 70 | 71 | // Runs: a() => var t = true;\n while(t)\n t = false;\n 72 | it('should cover a while statement with an unbracketed body (multiline)', async function() { 73 | const contract = await util.bootstrapCoverage('loops/while-no-brackets', api, this.provider); 74 | coverage.addContract(contract.instrumented, util.filePath); 75 | await contract.instance.a(contract.gas); 76 | const mapping = coverage.generate(contract.data, util.pathPrefix); 77 | 78 | assert.deepEqual(mapping[util.filePath].l, { 79 | 5: 1, 6: 1, 7: 1, 80 | }); 81 | assert.deepEqual(mapping[util.filePath].b, {}); 82 | assert.deepEqual(mapping[util.filePath].s, { 83 | 1: 1, 2: 1, 84 | }); 85 | assert.deepEqual(mapping[util.filePath].f, { 86 | 1: 1, 87 | }); 88 | }); 89 | }); 90 | -------------------------------------------------------------------------------- /test/units/options.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const util = require('./../util/util.js'); 3 | const Coverage = require('./../../lib/coverage'); 4 | const Api = require('./../../lib/api') 5 | 6 | describe('measureCoverage options', () => { 7 | let coverage; 8 | let api; 9 | 10 | before(async () => api = new Api({silent: true})) 11 | beforeEach(() => { 12 | api.config = {} 13 | coverage = new Coverage() 14 | }); 15 | after(async() => await api.finish()); 16 | 17 | async function setupAndRun(solidityFile, val, provider){ 18 | const contract = await util.bootstrapCoverage(solidityFile, api, provider); 19 | coverage.addContract(contract.instrumented, util.filePath); 20 | 21 | /* some methods intentionally fail */ 22 | try { 23 | (val) 24 | ? await contract.instance.a(val, contract.gas) 25 | : await contract.instance.a(contract.gas); 26 | } catch(e){} 27 | 28 | return coverage.generate(contract.data, util.pathPrefix); 29 | } 30 | 31 | // if (x == 1 || x == 2) { } else ... 32 | it('should ignore OR branches when measureBranchCoverage = false', async function() { 33 | api.config.measureBranchCoverage = false; 34 | const mapping = await setupAndRun('or/if-or', 1, this.provider); 35 | 36 | assert.deepEqual(mapping[util.filePath].l, { 37 | 5: 1, 8: 0 38 | }); 39 | assert.deepEqual(mapping[util.filePath].b, {}); 40 | assert.deepEqual(mapping[util.filePath].s, { 41 | 1: 1, 2: 0, 42 | }); 43 | assert.deepEqual(mapping[util.filePath].f, { 44 | 1: 1, 45 | }); 46 | }); 47 | 48 | it('should ignore if/else branches when measureBranchCoverage = false', async function() { 49 | api.config.measureBranchCoverage = false; 50 | const mapping = await setupAndRun('if/if-with-brackets', 1, this.provider); 51 | 52 | assert.deepEqual(mapping[util.filePath].l, { 53 | 5: 1, 54 | }); 55 | assert.deepEqual(mapping[util.filePath].b, {}); 56 | assert.deepEqual(mapping[util.filePath].s, { 57 | 1: 1, 58 | }); 59 | assert.deepEqual(mapping[util.filePath].f, { 60 | 1: 1, 61 | }); 62 | }); 63 | 64 | it('should ignore ternary conditionals when measureBranchCoverage = false', async function() { 65 | api.config.measureBranchCoverage = false; 66 | const mapping = await setupAndRun('conditional/sameline-consequent', null, this.provider); 67 | 68 | assert.deepEqual(mapping[util.filePath].l, { 69 | 5: 1, 6: 1, 7: 1, 70 | }); 71 | assert.deepEqual(mapping[util.filePath].b, {}); 72 | 73 | assert.deepEqual(mapping[util.filePath].s, { 74 | 1: 1, 2: 1, 75 | }); 76 | assert.deepEqual(mapping[util.filePath].f, { 77 | 1: 1, 78 | }); 79 | }); 80 | 81 | it('should ignore modifier branches when measureModifierCoverage = false', async function() { 82 | api.config.measureModifierCoverage = false; 83 | const mapping = await setupAndRun('modifiers/same-contract-pass', null, this.provider); 84 | 85 | assert.deepEqual(mapping[util.filePath].l, { 86 | 5: 1, 6: 1, 10: 1, 87 | }); 88 | assert.deepEqual(mapping[util.filePath].b, { // Source contains a `require` 89 | 1: [1, 0] 90 | }); 91 | assert.deepEqual(mapping[util.filePath].s, { 92 | 1: 1, 2: 1, 93 | }); 94 | assert.deepEqual(mapping[util.filePath].f, { 95 | 1: 1, 2: 1 96 | }); 97 | }); 98 | 99 | it('should ignore statements when measureStatementCoverage = false', async function() { 100 | api.config.measureStatementCoverage = false; 101 | const mapping = await setupAndRun('modifiers/same-contract-pass', null, this.provider); 102 | assert.deepEqual(mapping[util.filePath].s, {}); 103 | }); 104 | 105 | it('should ignore lines when measureLineCoverage = false', async function() { 106 | api.config.measureLineCoverage = false; 107 | const mapping = await setupAndRun('modifiers/same-contract-pass', null, this.provider); 108 | assert.deepEqual(mapping[util.filePath].l, {}); 109 | }); 110 | 111 | it('should ignore functions when measureFunctionCoverage = false', async function() { 112 | api.config.measureFunctionCoverage = false; 113 | const mapping = await setupAndRun('modifiers/same-contract-pass', null, this.provider); 114 | assert.deepEqual(mapping[util.filePath].f, {}); 115 | }); 116 | }); 117 | -------------------------------------------------------------------------------- /test/util/mochaRootHook.js: -------------------------------------------------------------------------------- 1 | const { createProvider } = require("hardhat/internal/core/providers/construction"); 2 | const { resolveConfig } = require("hardhat/internal/core/config/config-resolution"); 3 | const { HARDHAT_NETWORK_NAME } = require("hardhat/plugins") 4 | 5 | // Creates a minimal HH provider for use in the unit tests 6 | exports.mochaHooks = { 7 | beforeEach: async function() { 8 | const config = await resolveConfig("./", {}); 9 | this.provider = await createProvider( 10 | config, 11 | HARDHAT_NETWORK_NAME 12 | ); 13 | } 14 | }; -------------------------------------------------------------------------------- /test/util/verifiers.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const shell = require('shelljs'); 4 | const assert = require('assert'); 5 | 6 | function pathExists(path) { return shell.test('-e', path); } 7 | 8 | function lineCoverage(expected=[]){ 9 | let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); 10 | 11 | expected.forEach((item, idx) => { 12 | if (item === undefined) return; 13 | 14 | assert( 15 | summary[item.file].lines.pct === item.pct, 16 | 17 | `For condition ${idx} - expected ${item.pct} %,` + 18 | `saw - ${summary[item.file].lines.pct} %` 19 | ) 20 | }); 21 | } 22 | 23 | function statementCoverage(expected=[], summaryKey='pct'){ 24 | let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); 25 | 26 | expected.forEach((item, idx) => { 27 | assert( 28 | summary[item.file].statements[summaryKey] === item[summaryKey], 29 | 30 | `For condition ${idx} - expected ${item[summaryKey]} %,` + 31 | `saw - ${summary[item.file].statements[summaryKey]} %` 32 | ) 33 | }); 34 | } 35 | 36 | function functionCoverage(expected=[], summaryKey='pct'){ 37 | let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); 38 | 39 | expected.forEach((item, idx) => { 40 | assert( 41 | summary[item.file].functions[summaryKey] === item[summaryKey], 42 | 43 | `For condition ${idx} - expected ${item[summaryKey]} %,` + 44 | `saw - ${summary[item.file].functions[summaryKey]} %` 45 | ) 46 | }); 47 | } 48 | 49 | function branchCoverage(expected=[], summaryKey='pct'){ 50 | let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); 51 | 52 | expected.forEach((item, idx) => { 53 | assert( 54 | summary[item.file].branches.pct === item[summaryKey], 55 | 56 | `For condition ${idx} - expected ${item[summaryKey]} %,` + 57 | `saw - ${summary[item.file].branches[summaryKey]} %` 58 | ) 59 | }); 60 | } 61 | 62 | function coverageMissing(expected=[]){ 63 | let summary = JSON.parse(fs.readFileSync('coverage/coverage-summary.json')); 64 | expected.forEach(item => assert(summary[item.file] === undefined)) 65 | } 66 | 67 | function cleanInitialState(){ 68 | assert(pathExists('./coverage') === false, 'should start without: coverage'); 69 | assert(pathExists('./coverage.json') === false, 'should start without: coverage.json'); 70 | } 71 | 72 | function coverageGenerated(config){ 73 | const workingDir = config.working_directory || config.paths.root; 74 | const jsonPath = path.join(workingDir, "coverage.json"); 75 | 76 | assert(pathExists('./coverage') === true, 'should gen coverage folder'); 77 | assert(pathExists(jsonPath) === true, 'should gen coverage.json'); 78 | } 79 | 80 | function coverageNotGenerated(config){ 81 | const workingDir = config.working_directory || config.paths.root; 82 | const jsonPath = path.join(workingDir, "coverage.json"); 83 | 84 | assert(pathExists('./coverage') !== true, 'should NOT gen coverage folder'); 85 | assert(pathExists(jsonPath) !== true, 'should NOT gen coverage.json'); 86 | } 87 | 88 | module.exports = { 89 | pathExists: pathExists, 90 | lineCoverage: lineCoverage, 91 | statementCoverage: statementCoverage, 92 | functionCoverage: functionCoverage, 93 | branchCoverage: branchCoverage, 94 | coverageMissing: coverageMissing, 95 | cleanInitialState: cleanInitialState, 96 | coverageGenerated: coverageGenerated, 97 | coverageNotGenerated: coverageNotGenerated, 98 | } 99 | -------------------------------------------------------------------------------- /utils.js: -------------------------------------------------------------------------------- 1 | // For require('solidity-coverage/utils'); 2 | const utils = require('./plugins/resources/plugin.utils'); 3 | 4 | module.exports = utils; 5 | --------------------------------------------------------------------------------