├── crytic_compile ├── py.typed ├── utils │ ├── __init__.py │ ├── name_collision.py │ ├── unit_tests.py │ ├── npm.py │ ├── zip.py │ ├── subprocess.py │ ├── naming.py │ └── natspec.py ├── compiler │ ├── __init__.py │ └── compiler.py ├── cryticparser │ ├── __init__.py │ └── defaults.py ├── platform │ ├── types.pyc │ ├── __init__.py │ ├── exceptions.py │ ├── all_export.py │ ├── all_platforms.py │ ├── types.py │ ├── archive.py │ ├── abstract_platform.py │ ├── foundry.py │ ├── vyper.py │ ├── etherlime.py │ ├── brownie.py │ ├── dapp.py │ └── buidler.py ├── __init__.py ├── __main__.py └── compilation_unit.py ├── tests ├── buidler │ ├── buidler.config.js │ └── contracts │ │ └── Greeter.sol ├── toplevel.sol ├── contract.sol ├── expected │ ├── solc-multi-file │ │ └── combined_solc.json │ ├── hardhat-multi-file │ │ └── combined_solc.json │ ├── solc-demo.json │ └── embark-demo.json ├── contract_with_toplevel.sol ├── monorepo │ ├── package.json │ └── contracts │ │ ├── package.json │ │ ├── contracts │ │ └── Greeter.sol │ │ └── hardhat.config.js ├── .gitattributes ├── call_to_variable-all.sol-0.5.8-legacy.zip ├── hardhat │ ├── package.json │ ├── test │ │ └── sample-test.js │ ├── contracts │ │ └── Greeter.sol │ ├── hardhat.config.js │ └── scripts │ │ └── sample-script.js ├── hardhat-multi-file │ ├── package.json │ ├── test │ │ └── sample-test.js │ ├── contracts │ │ ├── X │ │ │ ├── Z.sol │ │ │ └── X.sol │ │ ├── E │ │ │ ├── G.sol │ │ │ └── E.sol │ │ ├── I │ │ │ ├── K.sol │ │ │ └── I.sol │ │ ├── C.sol │ │ └── A.sol │ ├── hardhat.config.js │ └── scripts │ │ └── sample-script.js ├── solc-multi-file │ ├── X │ │ ├── Z.sol │ │ └── X.sol │ ├── E │ │ ├── G.sol │ │ └── E.sol │ ├── I │ │ ├── K.sol │ │ └── I.sol │ ├── C.sol │ └── A.sol ├── library_linking.sol ├── process_combined_solc.js ├── test_library_linking.py ├── test_zip_archive.py └── vyper │ └── auction.vy ├── CODEOWNERS ├── .pylintrc ├── docs ├── source │ ├── modules.rst │ ├── crytic_compile.compiler.rst │ ├── crytic_compile.cryticparser.rst │ ├── crytic_compile.rst │ ├── crytic_compile.utils.rst │ └── crytic_compile.platform.rst ├── index.rst ├── Makefile ├── make.bat └── conf.py ├── .github ├── dependabot.yml └── workflows │ ├── darglint.yml │ ├── pytest.yml │ ├── mypy.yml │ ├── black.yml │ ├── pylint.yml │ ├── doc.yml │ ├── etherscan.yml │ ├── publish.yml │ ├── linter.yml │ └── ci.yml ├── .gitignore ├── scripts ├── ci_darglint.sh ├── ci_test_buidler.sh ├── ci_test_etherlime.sh ├── ci_test_hardhat.sh ├── ci_test_brownie.sh ├── ci_test_vyper.sh ├── ci_test_solc.sh ├── ci_test_waffle.sh ├── ci_test_embark.sh ├── ci_test_monorepo.sh ├── ci_test_hardhat_multi_file.sh ├── ci_test_truffle.sh ├── ci_test_standard.sh ├── ci_test_foundry.sh ├── ci_test_dapp.sh ├── ci_test_solc_multi_file.sh └── ci_test_etherscan.sh ├── mypy.ini ├── pyproject.toml ├── setup.py ├── Makefile ├── README.md └── CONTRIBUTING.md /crytic_compile/py.typed: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crytic_compile/utils/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/buidler/buidler.config.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crytic_compile/compiler/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /crytic_compile/utils/name_collision.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/toplevel.sol: -------------------------------------------------------------------------------- 1 | function g(){ 2 | 3 | } -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @elopez @bohendo @smonicas 2 | -------------------------------------------------------------------------------- /tests/contract.sol: -------------------------------------------------------------------------------- 1 | contract C{ 2 | function f() external{ 3 | 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tests/expected/solc-multi-file/combined_solc.json: -------------------------------------------------------------------------------- 1 | ["A.sol","C.sol","E.sol","G.sol","I.sol","K.sol"] -------------------------------------------------------------------------------- /tests/expected/hardhat-multi-file/combined_solc.json: -------------------------------------------------------------------------------- 1 | ["A.sol","C.sol","E.sol","G.sol","I.sol","K.sol","X.sol","Z.sol"] -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [MESSAGES CONTROL] 2 | # Disable bad continuation, too many issues with black 3 | disable = bad-continuation 4 | -------------------------------------------------------------------------------- /crytic_compile/cryticparser/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Init module 3 | """ 4 | from .defaults import DEFAULTS_FLAG_IN_CONFIG 5 | -------------------------------------------------------------------------------- /crytic_compile/platform/types.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crytic/crytic-compile/HEAD/crytic_compile/platform/types.pyc -------------------------------------------------------------------------------- /docs/source/modules.rst: -------------------------------------------------------------------------------- 1 | crytic_compile 2 | ============== 3 | 4 | .. toctree:: 5 | :maxdepth: 4 6 | 7 | crytic_compile 8 | -------------------------------------------------------------------------------- /tests/contract_with_toplevel.sol: -------------------------------------------------------------------------------- 1 | import "./toplevel.sol"; 2 | 3 | contract C{ 4 | function f() external{ 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/monorepo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "monorepo", 3 | "workspaces": [ 4 | "contracts" 5 | ], 6 | "private": true 7 | } 8 | -------------------------------------------------------------------------------- /crytic_compile/platform/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Init module 3 | """ 4 | from .exceptions import InvalidCompilation 5 | from .types import Type 6 | -------------------------------------------------------------------------------- /tests/.gitattributes: -------------------------------------------------------------------------------- 1 | # Always checkout test solidity code with lf endings 2 | # autocrlf breaks file offsets in tests. 3 | *.sol text eol=lf 4 | -------------------------------------------------------------------------------- /tests/call_to_variable-all.sol-0.5.8-legacy.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/crytic/crytic-compile/HEAD/tests/call_to_variable-all.sol-0.5.8-legacy.zip -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 2 3 | updates: 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | target-branch: "dev" 7 | schedule: 8 | interval: "weekly" 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.nix 2 | *.pyc 3 | .idea/ 4 | __pycache__/ 5 | artifacts 6 | build/ 7 | cache 8 | crytic_compile.egg-info/ 9 | dist/ 10 | node_modules 11 | package-lock.json 12 | result 13 | env/ 14 | .coverage* 15 | -------------------------------------------------------------------------------- /scripts/ci_darglint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | pip install darglint 5 | 6 | if ! darglint . 7 | then 8 | echo "Darglint failed. Please fix the above issues" 9 | exit 255 10 | fi 11 | -------------------------------------------------------------------------------- /crytic_compile/platform/exceptions.py: -------------------------------------------------------------------------------- 1 | """ 2 | Crytic Compile Exceptions 3 | """ 4 | 5 | 6 | class InvalidCompilation(Exception): 7 | """ 8 | Invalid compilation exception 9 | """ 10 | 11 | # pylint: disable=unnecessary-pass 12 | pass 13 | -------------------------------------------------------------------------------- /scripts/ci_test_buidler.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | ### Test buidler integration 5 | 6 | cd tests/buidler || exit 255 7 | 8 | npm install --save-dev @nomiclabs/buidler 9 | 10 | if ! crytic-compile . 11 | then 12 | echo "buidler test failed" 13 | exit 255 14 | fi 15 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | 2 | Welcome to crytic-compile's documentation! 3 | ========================================== 4 | 5 | .. toctree:: 6 | :maxdepth: 2 7 | :caption: Contents: 8 | 9 | Indices and tables 10 | ================== 11 | 12 | * :ref:`genindex` 13 | * :ref:`modindex` 14 | * :ref:`search` 15 | -------------------------------------------------------------------------------- /crytic_compile/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | .. include:: ../README.md 3 | """ 4 | from .crytic_compile import CryticCompile, compile_all, is_supported 5 | from .compilation_unit import CompilationUnit 6 | from .cryticparser import cryticparser 7 | from .platform import InvalidCompilation 8 | from .utils.zip import save_to_zip 9 | -------------------------------------------------------------------------------- /tests/hardhat/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project", 3 | "devDependencies": { 4 | "@nomiclabs/hardhat-ethers": "^2.0.0", 5 | "@nomiclabs/hardhat-waffle": "^2.0.0", 6 | "chai": "^4.2.0", 7 | "ethereum-waffle": "^3.2.0", 8 | "ethers": "^5.0.19", 9 | "hardhat": "^2.0.2" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project", 3 | "devDependencies": { 4 | "@nomiclabs/hardhat-ethers": "^2.0.0", 5 | "@nomiclabs/hardhat-waffle": "^2.0.0", 6 | "chai": "^4.2.0", 7 | "ethereum-waffle": "^3.2.0", 8 | "ethers": "^5.0.19", 9 | "hardhat": "^2.0.2" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tests/monorepo/contracts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hardhat-project", 3 | "devDependencies": { 4 | "@nomiclabs/hardhat-ethers": "^2.0.0", 5 | "@nomiclabs/hardhat-waffle": "^2.0.0", 6 | "chai": "^4.2.0", 7 | "ethereum-waffle": "^3.2.0", 8 | "ethers": "^5.0.19", 9 | "hardhat": "^2.0.2" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /scripts/ci_test_etherlime.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | ### Test etherlime integration 5 | 6 | DIR=$(mktemp -d) 7 | cd "$DIR" || exit 255 8 | 9 | npm i -g etherlime 10 | etherlime init 11 | 12 | if ! crytic-compile . --compile-remove-metadata 13 | then 14 | echo "Etherlime test failed" 15 | exit 255 16 | fi 17 | 18 | -------------------------------------------------------------------------------- /scripts/ci_test_hardhat.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | echo "Testing hardhat integration of $(realpath "$(which crytic-compile)")" 5 | 6 | cd tests/hardhat || exit 255 7 | 8 | npm install 9 | 10 | if ! crytic-compile . 11 | then echo "Monorepo test failed" && exit 255 12 | else echo "Monorepo test passed" && exit 0 13 | fi 14 | -------------------------------------------------------------------------------- /mypy.ini: -------------------------------------------------------------------------------- 1 | [mypy] 2 | warn_incomplete_stub = true 3 | ignore_missing_imports = true 4 | disallow_untyped_calls = true 5 | disallow_untyped_defs = true 6 | disallow_incomplete_defs = true 7 | check_untyped_defs = true 8 | disallow_untyped_decorators = true 9 | warn_redundant_casts = true 10 | warn_no_return = true 11 | warn_unreachable = true 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /tests/solc-multi-file/X/Z.sol: -------------------------------------------------------------------------------- 1 | import "./X.sol"; 2 | 3 | contract Z { 4 | uint256 y; 5 | X x; 6 | 7 | constructor(uint256 yval) public { 8 | y = yval; 9 | x = new X(5); 10 | } 11 | 12 | function sum() public view returns (uint256) { 13 | return x.sum(); 14 | } 15 | 16 | function setX(uint256 xval) public { 17 | x.setX(xval+1); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /scripts/ci_test_brownie.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # https://github.com/eth-brownie/brownie/pull/1873#issuecomment-2927669459 5 | pip install -U setuptools 6 | 7 | pip install eth-brownie 8 | brownie bake token 9 | cd token || exit 255 10 | 11 | if ! crytic-compile . --compile-force-framework Brownie 12 | then 13 | echo "Brownie test failed" 14 | exit 255 15 | fi 16 | -------------------------------------------------------------------------------- /scripts/ci_test_vyper.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | ### Test vyper integration 5 | 6 | pip install 'vyper>=0.3.7,<0.4' 7 | 8 | echo "Testing vyper integration of $(realpath "$(which crytic-compile)")" 9 | 10 | cd tests/vyper || exit 255 11 | 12 | if ! crytic-compile auction.vy --export-formats standard 13 | then echo "vyper test failed" && exit 255 14 | else echo "vyper test passed" && exit 0 15 | fi 16 | -------------------------------------------------------------------------------- /tests/solc-multi-file/E/G.sol: -------------------------------------------------------------------------------- 1 | import "./E.sol"; 2 | 3 | contract G { 4 | uint256 x; 5 | uint256 y; 6 | E e; 7 | 8 | constructor(uint256 yval) public { 9 | x = 0; 10 | y = yval; 11 | e = new E(5); 12 | } 13 | 14 | function sum() public view returns (uint256) { 15 | return e.sum(); 16 | } 17 | 18 | function setX(uint256 xval) public { 19 | x = xval; 20 | e.setX(xval+1); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/solc-multi-file/I/K.sol: -------------------------------------------------------------------------------- 1 | import "./I.sol"; 2 | 3 | contract K { 4 | uint256 x; 5 | uint256 y; 6 | I i; 7 | 8 | constructor(uint256 yval) public { 9 | x = 0; 10 | y = yval; 11 | i = new I(5); 12 | } 13 | 14 | function sum() public view returns (uint256) { 15 | return i.sum(); 16 | } 17 | 18 | function setX(uint256 xval) public { 19 | x = xval; 20 | i.setX(xval+1); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/test/sample-test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | 3 | describe("example test", function() { 4 | it("A", async function() { 5 | const A = await ethers.getContractFactory("A"); 6 | const a = await A.deploy(100,101); 7 | 8 | await a.deployed(); 9 | expect(await a.sum()).to.equal(195); 10 | 11 | await a.set(50); 12 | expect(await a.sum()).to.equal(295); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /tests/solc-multi-file/E/E.sol: -------------------------------------------------------------------------------- 1 | import "../C.sol"; 2 | import "../I/I.sol"; 3 | 4 | contract E { 5 | uint256 x; 6 | uint256 y; 7 | D d; 8 | 9 | constructor(uint256 yval) public { 10 | x = 0; 11 | y = yval; 12 | d = new D(yval); 13 | } 14 | 15 | function sum() public view returns (uint256) { 16 | return x+y+d.diff(); 17 | } 18 | 19 | function setX(uint256 xval) public { 20 | x = xval; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/library_linking.sol: -------------------------------------------------------------------------------- 1 | library NeedsLinkingA { 2 | function testA() external pure returns (uint) { 3 | return type(uint).max; 4 | } 5 | } 6 | library NeedsLinkingB { 7 | function testB() external pure returns (uint) { 8 | return type(uint).min; 9 | } 10 | } 11 | contract TestLibraryLinking { 12 | function test() external { 13 | NeedsLinkingA.testA(); 14 | NeedsLinkingB.testB(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/contracts/X/Z.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "./X.sol"; 5 | 6 | contract Z { 7 | uint256 y; 8 | X x; 9 | 10 | constructor(uint256 yval) { 11 | y = yval; 12 | x = new X(5); 13 | } 14 | 15 | function sum() public view returns (uint256) { 16 | return x.sum(); 17 | } 18 | 19 | function setX(uint256 xval) public { 20 | x.setX(xval+1); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /tests/buidler/contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.1; 2 | 3 | 4 | contract Greeter { 5 | 6 | string greeting; 7 | 8 | constructor(string memory _greeting) public { 9 | greeting = _greeting; 10 | } 11 | 12 | function greet() public view returns (string memory) { 13 | return greeting; 14 | } 15 | 16 | function setGreeting(string memory _greeting) public { 17 | greeting = _greeting; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /scripts/ci_test_solc.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | DIR=$(mktemp -d) 5 | 6 | cp tests/contract.sol "$DIR" 7 | cd "$DIR" || exit 255 8 | crytic-compile contract.sol --compile-remove-metadata --export-format truffle 9 | 10 | cd - || exit 255 11 | DIFF=$(diff "$DIR/crytic-export/C.json" tests/expected/solc-demo.json) 12 | if [ "$?" != "0" ] || [ "$DIFF" != "" ] 13 | then 14 | echo "solc test failed" 15 | echo "$DIFF" 16 | exit 255 17 | fi 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/solc-multi-file/I/I.sol: -------------------------------------------------------------------------------- 1 | import "../C.sol"; 2 | import "../E/E.sol"; 3 | 4 | contract I { 5 | uint256 x; 6 | uint256 y; 7 | D d; 8 | E e; 9 | 10 | constructor(uint256 yval) public { 11 | x = 0; 12 | y = yval; 13 | d = new D(yval); 14 | e = new E(yval+1); 15 | } 16 | 17 | function sum() public view returns (uint256) { 18 | return x+y+d.diff()+e.sum(); 19 | } 20 | 21 | function setX(uint256 xval) public { 22 | x = xval; 23 | e.setX(y); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/solc-multi-file/X/X.sol: -------------------------------------------------------------------------------- 1 | import "../C.sol"; 2 | import "../E/E.sol"; 3 | 4 | contract X { 5 | uint256 x; 6 | uint256 y; 7 | D d; 8 | E e; 9 | 10 | constructor(uint256 yval) public { 11 | x = 0; 12 | y = yval; 13 | d = new D(yval); 14 | e = new E(yval+1); 15 | } 16 | 17 | function sum() public view returns (uint256) { 18 | return x+y+d.diff()+e.sum(); 19 | } 20 | 21 | function setX(uint256 xval) public { 22 | x = xval; 23 | e.setX(y); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/contracts/E/G.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "./E.sol"; 5 | 6 | contract G { 7 | uint256 x; 8 | uint256 y; 9 | E e; 10 | 11 | constructor(uint256 yval) { 12 | x = 0; 13 | y = yval; 14 | e = new E(5); 15 | } 16 | 17 | function sum() public view returns (uint256) { 18 | return e.sum(); 19 | } 20 | 21 | function setX(uint256 xval) public { 22 | x = xval; 23 | e.setX(xval+1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/contracts/I/K.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "./I.sol"; 5 | 6 | contract K { 7 | uint256 x; 8 | uint256 y; 9 | I i; 10 | 11 | constructor(uint256 yval) { 12 | x = 0; 13 | y = yval; 14 | i = new I(5); 15 | } 16 | 17 | function sum() public view returns (uint256) { 18 | return i.sum(); 19 | } 20 | 21 | function setX(uint256 xval) public { 22 | x = xval; 23 | i.setX(xval+1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/contracts/E/E.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "../C.sol"; 5 | import "../I/I.sol"; 6 | 7 | contract E { 8 | uint256 x; 9 | uint256 y; 10 | D d; 11 | 12 | constructor(uint256 yval) { 13 | x = 0; 14 | y = yval; 15 | d = new D(yval); 16 | } 17 | 18 | function sum() public view returns (uint256) { 19 | return x+y+d.diff(); 20 | } 21 | 22 | function setX(uint256 xval) public { 23 | x = xval; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /docs/source/crytic_compile.compiler.rst: -------------------------------------------------------------------------------- 1 | crytic\_compile.compiler package 2 | ================================ 3 | 4 | Submodules 5 | ---------- 6 | 7 | crytic\_compile.compiler.compiler module 8 | ---------------------------------------- 9 | 10 | .. automodule:: crytic_compile.compiler.compiler 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | Module contents 16 | --------------- 17 | 18 | .. automodule:: crytic_compile.compiler 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | -------------------------------------------------------------------------------- /scripts/ci_test_waffle.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | ### Test waffle integration 5 | 6 | DIR=$(mktemp -d) 7 | cd "$DIR" || exit 255 8 | 9 | npm install -g ethereum-waffle 10 | npm install openzeppelin-solidity 11 | mkdir contracts 12 | cd contracts || exit 255 13 | echo 'contract Test { 14 | constructor() public {} 15 | }' > token.sol 16 | 17 | cd .. 18 | 19 | if ! crytic-compile . --compile-remove-metadata --compile-force-framework Waffle 20 | then 21 | echo "Waffle test failed" 22 | exit 255 23 | fi 24 | 25 | -------------------------------------------------------------------------------- /scripts/ci_test_embark.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | ### Test embark integration 5 | 6 | cd /tmp || exit 255 7 | 8 | curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash 9 | source ~/.nvm/nvm.sh 10 | nvm install 10.17.0 11 | nvm use 10.17.0 12 | 13 | npm install -g embark@4.2.0 14 | embark demo 15 | cd /tmp/embark_demo || exit 255 16 | npm install 17 | 18 | if ! crytic-compile . --embark-overwrite-config --compile-remove-metadata 19 | then 20 | echo "Embark test failed" 21 | exit 255 22 | fi 23 | 24 | -------------------------------------------------------------------------------- /tests/hardhat/test/sample-test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | 3 | describe("Greeter", function() { 4 | it("Should return the new greeting once it's changed", async function() { 5 | const Greeter = await ethers.getContractFactory("Greeter"); 6 | const greeter = await Greeter.deploy("Hello, world!"); 7 | 8 | await greeter.deployed(); 9 | expect(await greeter.greet()).to.equal("Hello, world!"); 10 | 11 | await greeter.setGreeting("Hola, mundo!"); 12 | expect(await greeter.greet()).to.equal("Hola, mundo!"); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /scripts/ci_test_monorepo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | echo "Testing monorepo integration of $(realpath "$(which crytic-compile)")" 5 | 6 | cd tests/monorepo || exit 255 7 | 8 | npm install 9 | 10 | echo "Testing from the root of a monorepo" 11 | if ! crytic-compile ./contracts 12 | then echo "Monorepo test failed" && exit 255 13 | fi 14 | 15 | cd contracts || exit 255 16 | 17 | echo "Testing from within a subdir of a monorepo" 18 | if ! crytic-compile . 19 | then echo "Monorepo test failed" && exit 255 20 | fi 21 | 22 | echo "Monorepo test passed" && exit 0 23 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/contracts/I/I.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "../C.sol"; 5 | import "../E/E.sol"; 6 | 7 | contract I { 8 | uint256 x; 9 | uint256 y; 10 | D d; 11 | E e; 12 | 13 | constructor(uint256 yval) { 14 | x = 0; 15 | y = yval; 16 | d = new D(yval); 17 | e = new E(yval+1); 18 | } 19 | 20 | function sum() public view returns (uint256) { 21 | return x+y+d.diff()+e.sum(); 22 | } 23 | 24 | function setX(uint256 xval) public { 25 | x = xval; 26 | e.setX(y); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/contracts/X/X.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "../C.sol"; 5 | import "../E/E.sol"; 6 | 7 | contract X { 8 | uint256 x; 9 | uint256 y; 10 | D d; 11 | E e; 12 | 13 | constructor(uint256 yval) { 14 | x = 0; 15 | y = yval; 16 | d = new D(yval); 17 | e = new E(yval+1); 18 | } 19 | 20 | function sum() public view returns (uint256) { 21 | return x+y+d.diff()+e.sum(); 22 | } 23 | 24 | function setX(uint256 xval) public { 25 | x = xval; 26 | e.setX(y); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /crytic_compile/platform/all_export.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module containing all the supported export functions 3 | """ 4 | from crytic_compile.platform.archive import export_to_archive 5 | from crytic_compile.platform.solc import export_to_solc 6 | from crytic_compile.platform.standard import export_to_standard 7 | from crytic_compile.platform.truffle import export_to_truffle 8 | 9 | PLATFORMS_EXPORT = { 10 | "standard": export_to_standard, 11 | "crytic-compile": export_to_standard, 12 | "solc": export_to_solc, 13 | "truffle": export_to_truffle, 14 | "archive": export_to_archive, 15 | } 16 | -------------------------------------------------------------------------------- /tests/solc-multi-file/C.sol: -------------------------------------------------------------------------------- 1 | contract C { 2 | uint256 x; 3 | uint256 y; 4 | 5 | constructor(uint256 yval) public { 6 | x = 0; 7 | y = yval; 8 | } 9 | 10 | function sum() public view returns (uint256) { 11 | return x+y; 12 | } 13 | 14 | function setX(uint256 xval) public { 15 | x = xval; 16 | } 17 | } 18 | 19 | contract D { 20 | uint256 x; 21 | uint256 y; 22 | C c; 23 | 24 | constructor(uint256 yval) public { 25 | x = 0; 26 | y = yval; 27 | c = new C(5); 28 | } 29 | 30 | function diff() public view returns (uint256) { 31 | return x-y; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /.github/workflows/darglint.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Darglint 3 | 4 | on: 5 | push: 6 | branches: 7 | - master 8 | - dev 9 | pull_request: 10 | branches: [master, dev] 11 | 12 | concurrency: 13 | group: ${{ github.workflow }}-${{ github.ref }} 14 | cancel-in-progress: true 15 | 16 | jobs: 17 | tests: 18 | runs-on: ubuntu-latest 19 | steps: 20 | - uses: actions/checkout@v5 21 | - name: Set up Python 3.8 22 | uses: actions/setup-python@v6 23 | with: 24 | python-version: 3.8 25 | - name: Run Tests 26 | run: | 27 | bash scripts/ci_darglint.sh 28 | -------------------------------------------------------------------------------- /crytic_compile/platform/all_platforms.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module containing all the platforms 3 | """ 4 | # pylint: disable=unused-import 5 | from .archive import Archive 6 | from .brownie import Brownie 7 | from .buidler import Buidler 8 | from .dapp import Dapp 9 | from .embark import Embark 10 | from .etherlime import Etherlime 11 | from .etherscan import Etherscan 12 | from .hardhat import Hardhat 13 | from .solc import Solc 14 | from .solc_standard_json import SolcStandardJson 15 | from .standard import Standard 16 | from .truffle import Truffle 17 | from .vyper import VyperStandardJson 18 | from .waffle import Waffle 19 | from .foundry import Foundry 20 | -------------------------------------------------------------------------------- /tests/hardhat/contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "hardhat/console.sol"; 5 | 6 | 7 | contract Greeter { 8 | string greeting; 9 | 10 | constructor(string memory _greeting) { 11 | console.log("Deploying a Greeter with greeting:", _greeting); 12 | greeting = _greeting; 13 | } 14 | 15 | function greet() public view returns (string memory) { 16 | return greeting; 17 | } 18 | 19 | function setGreeting(string memory _greeting) public { 20 | console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); 21 | greeting = _greeting; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /tests/monorepo/contracts/contracts/Greeter.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "hardhat/console.sol"; 5 | 6 | 7 | contract Greeter { 8 | string greeting; 9 | 10 | constructor(string memory _greeting) { 11 | console.log("Deploying a Greeter with greeting:", _greeting); 12 | greeting = _greeting; 13 | } 14 | 15 | function greet() public view returns (string memory) { 16 | return greeting; 17 | } 18 | 19 | function setGreeting(string memory _greeting) public { 20 | console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); 21 | greeting = _greeting; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /scripts/ci_test_hardhat_multi_file.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | DIR=$(mktemp -d) 5 | 6 | cp -r tests/hardhat-multi-file "$DIR" 7 | cd "$DIR/hardhat-multi-file" || exit 255 8 | npm install 9 | crytic-compile --compile-remove-metadata --export-formats solc,truffle . 10 | 11 | cd - || exit 255 12 | node tests/process_combined_solc.js "$DIR/hardhat-multi-file/crytic-export/combined_solc.json" "$DIR" 13 | DIFF=$(diff -r "$DIR/hardhat-multi-file/crytic-export" tests/expected/hardhat-multi-file) 14 | if [ "$?" != "0" ] || [ "$DIFF" != "" ] 15 | then 16 | echo "hardhat-multi-file test failed" 17 | echo "$DIFF" 18 | exit 255 19 | fi 20 | -------------------------------------------------------------------------------- /tests/hardhat/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | 3 | // This is a sample Hardhat task. To learn how to create your own go to 4 | // https://hardhat.org/guides/create-task.html 5 | task("accounts", "Prints the list of accounts", async () => { 6 | const accounts = await ethers.getSigners(); 7 | 8 | for (const account of accounts) { 9 | console.log(account.address); 10 | } 11 | }); 12 | 13 | // You need to export an object to set up your config 14 | // Go to https://hardhat.org/config/ to learn more 15 | 16 | /** 17 | * @type import('hardhat/config').HardhatUserConfig 18 | */ 19 | module.exports = { 20 | solidity: "0.7.3", 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /scripts/ci_test_truffle.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | ### Test truffle integration 5 | 6 | DIR=$(mktemp -d) 7 | cd "$DIR" || exit 255 8 | 9 | npm install -g truffle 10 | truffle unbox metacoin 11 | 12 | if ! crytic-compile . --compile-remove-metadata 13 | then 14 | echo "Truffle test failed" 15 | exit 255 16 | fi 17 | # TODO: for some reason truffle output is not deterministic 18 | # The assigned id changes 19 | #cd - 20 | # 21 | #DIFF=$(diff "$DIR/crytic-export/contracts.json" tests/expected/truffle-metacoin.json) 22 | #if [ "$DIFF" != "" ] 23 | #then 24 | # echo "Truffle test failed" 25 | # echo $DIFF 26 | # exit 255 27 | #fi 28 | 29 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/contracts/C.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | contract C { 5 | uint256 x; 6 | uint256 y; 7 | 8 | constructor(uint256 yval) { 9 | x = 0; 10 | y = yval; 11 | } 12 | 13 | function sum() public view returns (uint256) { 14 | return x+y; 15 | } 16 | 17 | function setX(uint256 xval) public { 18 | x = xval; 19 | } 20 | } 21 | 22 | contract D { 23 | uint256 x; 24 | uint256 y; 25 | C c; 26 | 27 | constructor(uint256 yval) { 28 | x = 0; 29 | y = yval; 30 | c = new C(5); 31 | } 32 | 33 | function diff() public view returns (uint256) { 34 | return x-y; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | 3 | // This is a sample Hardhat task. To learn how to create your own go to 4 | // https://hardhat.org/guides/create-task.html 5 | task("accounts", "Prints the list of accounts", async () => { 6 | const accounts = await ethers.getSigners(); 7 | 8 | for (const account of accounts) { 9 | console.log(account.address); 10 | } 11 | }); 12 | 13 | // You need to export an object to set up your config 14 | // Go to https://hardhat.org/config/ to learn more 15 | 16 | /** 17 | * @type import('hardhat/config').HardhatUserConfig 18 | */ 19 | module.exports = { 20 | solidity: "0.7.3", 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /tests/monorepo/contracts/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | 3 | // This is a sample Hardhat task. To learn how to create your own go to 4 | // https://hardhat.org/guides/create-task.html 5 | task("accounts", "Prints the list of accounts", async () => { 6 | const accounts = await ethers.getSigners(); 7 | 8 | for (const account of accounts) { 9 | console.log(account.address); 10 | } 11 | }); 12 | 13 | // You need to export an object to set up your config 14 | // Go to https://hardhat.org/config/ to learn more 15 | 16 | /** 17 | * @type import('hardhat/config').HardhatUserConfig 18 | */ 19 | module.exports = { 20 | solidity: "0.7.3", 21 | }; 22 | 23 | -------------------------------------------------------------------------------- /tests/process_combined_solc.js: -------------------------------------------------------------------------------- 1 | // Used in hardhat-multi-file and solc-multi-file tests 2 | // Edits the combined_solc.json output file 3 | // Takes only the sourceList (since the contracts themselves are unstable) 4 | // and in the sourceList filenames, takes only the "[letter].sol" part, rather than the whole thing 5 | // since the temp dir path isn't going to be the same every run 6 | 7 | const fs = require("fs"); 8 | const process = require("process"); 9 | const fileName = process.argv[2]; 10 | const fileData = JSON.parse(fs.readFileSync(fileName)); 11 | const toWrite = fileData.sourceList.map((s) => s.substring(s.length-5)); 12 | fs.writeFileSync(fileName, JSON.stringify(toWrite)); 13 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/source/crytic_compile.cryticparser.rst: -------------------------------------------------------------------------------- 1 | crytic\_compile.cryticparser package 2 | ==================================== 3 | 4 | Submodules 5 | ---------- 6 | 7 | crytic\_compile.cryticparser.cryticparser module 8 | ------------------------------------------------ 9 | 10 | .. automodule:: crytic_compile.cryticparser.cryticparser 11 | :members: 12 | :undoc-members: 13 | :show-inheritance: 14 | 15 | crytic\_compile.cryticparser.defaults module 16 | -------------------------------------------- 17 | 18 | .. automodule:: crytic_compile.cryticparser.defaults 19 | :members: 20 | :undoc-members: 21 | :show-inheritance: 22 | 23 | Module contents 24 | --------------- 25 | 26 | .. automodule:: crytic_compile.cryticparser 27 | :members: 28 | :undoc-members: 29 | :show-inheritance: 30 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | target-version = ["py38"] 3 | line-length = 100 4 | [tool.pylint.messages_control] 5 | disable = """ 6 | unnecessary-lambda, 7 | bad-continuation, 8 | cyclic-import, 9 | line-too-long, 10 | invalid-name, 11 | fixme, 12 | too-many-return-statements, 13 | too-many-ancestors, 14 | logging-fstring-interpolation, 15 | logging-not-lazy, 16 | duplicate-code, 17 | import-error, 18 | unsubscriptable-object 19 | """ 20 | [tool.mypy] 21 | warn_incomplete_stub = true 22 | ignore_missing_imports = true 23 | disallow_untyped_calls = true 24 | disallow_untyped_defs = true 25 | disallow_incomplete_defs = true 26 | check_untyped_defs = true 27 | disallow_untyped_decorators = true 28 | warn_redundant_casts = true 29 | warn_no_return = true 30 | warn_unreachable = true 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /scripts/ci_test_standard.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | DIR=$(mktemp -d) 5 | 6 | cp tests/contract_with_toplevel.sol "$DIR" 7 | cp tests/toplevel.sol "$DIR" 8 | cd "$DIR" || exit 255 9 | 10 | solc-select use 0.8.0 --always-install 11 | 12 | if ! crytic-compile contract_with_toplevel.sol --export-format archive 13 | then 14 | echo "Standard test failed" 15 | exit 255 16 | fi 17 | 18 | if ! crytic-compile crytic-export/contract_with_toplevel.sol_export_archive.json 19 | then 20 | echo "Standard test failed" 21 | exit 255 22 | fi 23 | 24 | if ! crytic-compile contract_with_toplevel.sol --export-zip test.zip 25 | then 26 | echo "Standard test failed" 27 | exit 255 28 | fi 29 | 30 | if ! crytic-compile test.zip 31 | then 32 | echo "Standard test failed" 33 | exit 255 34 | fi 35 | -------------------------------------------------------------------------------- /docs/source/crytic_compile.rst: -------------------------------------------------------------------------------- 1 | crytic\_compile package 2 | ======================= 3 | 4 | Subpackages 5 | ----------- 6 | 7 | .. toctree:: 8 | :maxdepth: 4 9 | 10 | crytic_compile.compiler 11 | crytic_compile.cryticparser 12 | crytic_compile.platform 13 | crytic_compile.utils 14 | 15 | Submodules 16 | ---------- 17 | 18 | crytic\_compile.compilation\_unit module 19 | ---------------------------------------- 20 | 21 | .. automodule:: crytic_compile.compilation_unit 22 | :members: 23 | :undoc-members: 24 | :show-inheritance: 25 | 26 | crytic\_compile.crytic\_compile module 27 | -------------------------------------- 28 | 29 | .. automodule:: crytic_compile.crytic_compile 30 | :members: 31 | :undoc-members: 32 | :show-inheritance: 33 | 34 | Module contents 35 | --------------- 36 | 37 | .. automodule:: crytic_compile 38 | :members: 39 | :undoc-members: 40 | :show-inheritance: 41 | -------------------------------------------------------------------------------- /tests/solc-multi-file/A.sol: -------------------------------------------------------------------------------- 1 | import "./C.sol"; 2 | import "./E/G.sol"; 3 | import "./I/K.sol"; 4 | 5 | contract A { 6 | uint256 x; 7 | uint256 y; 8 | uint256 z; 9 | B b; 10 | C c; 11 | D d; 12 | 13 | constructor(uint256 yval, uint256 zval) public { 14 | x = 0; 15 | y = yval; 16 | z = zval; 17 | b = new B(); 18 | c = new C(zval); 19 | d = new D(zval); 20 | } 21 | 22 | function sum() public view returns (uint256) { 23 | return x+y+z+b.diff()+c.sum()+d.diff(); 24 | } 25 | 26 | function set(uint256 xval) public { 27 | x = xval; 28 | c.setX(xval); 29 | } 30 | } 31 | 32 | contract B { 33 | uint256 x; 34 | uint256 y; 35 | G g; 36 | K k; 37 | 38 | constructor() public { 39 | x = 0; 40 | y = 6; 41 | g = new G(x+1); 42 | k = new K(x+2); 43 | } 44 | 45 | function diff() public view returns (uint256) { 46 | return x-y+g.sum(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /scripts/ci_test_foundry.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ### Test foundry integration 3 | set -Eeuxo pipefail 4 | 5 | 6 | ## test 1 - same folder 7 | 8 | cd /tmp || exit 255 9 | mkdir forge_test 10 | cd forge_test || exit 255 11 | forge init 12 | 13 | if ! crytic-compile . 14 | then 15 | echo "foundry test 1 failed" 16 | exit 255 17 | fi 18 | 19 | 20 | ## test 2 - same folder, different out dir 21 | 22 | cd /tmp || exit 255 23 | mkdir forge_test2 24 | cd forge_test2 || exit 255 25 | forge init 26 | 27 | sed -i 's/^out\s*=.*$/out = "foobar"/' foundry.toml 28 | 29 | if ! crytic-compile . 30 | then 31 | echo "foundry test 2 failed" 32 | exit 255 33 | fi 34 | 35 | ## test 3 - different folder 36 | 37 | cd /tmp || exit 255 38 | mkdir forge_test3 39 | cd forge_test3 || exit 255 40 | forge init 41 | 42 | cd /tmp || exit 255 43 | 44 | if ! crytic-compile ./forge_test3 45 | then 46 | echo "foundry test 3 failed" 47 | exit 255 48 | fi 49 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/contracts/A.sol: -------------------------------------------------------------------------------- 1 | //SPDX-License-Identifier: Unlicense 2 | pragma solidity ^0.7.0; 3 | 4 | import "./C.sol"; 5 | import "./E/G.sol"; 6 | import "./I/K.sol"; 7 | 8 | contract A { 9 | uint256 x; 10 | uint256 y; 11 | uint256 z; 12 | B b; 13 | C c; 14 | D d; 15 | 16 | constructor(uint256 yval, uint256 zval) { 17 | x = 0; 18 | y = yval; 19 | z = zval; 20 | b = new B(); 21 | c = new C(zval); 22 | d = new D(zval); 23 | } 24 | 25 | function sum() public view returns (uint256) { 26 | return x+y+z+b.diff()+c.sum()+d.diff(); 27 | } 28 | 29 | function set(uint256 xval) public { 30 | x = xval; 31 | c.setX(xval); 32 | } 33 | } 34 | 35 | contract B { 36 | uint256 x; 37 | uint256 y; 38 | G g; 39 | K k; 40 | 41 | constructor() { 42 | x = 0; 43 | y = 6; 44 | g = new G(x+1); 45 | k = new K(x+2); 46 | } 47 | 48 | function diff() public view returns (uint256) { 49 | return x-y+g.sum(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /crytic_compile/utils/unit_tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | Module handling unit-tests features 3 | """ 4 | import json 5 | from pathlib import Path 6 | from typing import List 7 | 8 | 9 | def guess_tests(target: str) -> List[str]: 10 | """Try to guess the unit tests commands 11 | 12 | Args: 13 | target (str): path to the target 14 | 15 | Returns: 16 | List[str]: List of guessed unit tests commands 17 | """ 18 | targets: List[str] = [] 19 | 20 | readme_path = Path(target, "README.md") 21 | if readme_path.is_file(): 22 | with open(readme_path, encoding="utf8") as readme_f: 23 | readme = readme_f.read() 24 | if "yarn test" in readme: 25 | targets += ["yarn test"] 26 | 27 | package_path = Path(target, "package.json") 28 | if package_path.is_file(): 29 | with open(package_path, encoding="utf8") as package_f: 30 | package = json.load(package_f) 31 | if "scripts" in package: 32 | if "test" in package["scripts"]: 33 | targets += package["scripts"]["test"] 34 | 35 | return targets 36 | -------------------------------------------------------------------------------- /.github/workflows/pytest.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Pytest 3 | 4 | defaults: 5 | run: 6 | # To load bashrc 7 | shell: bash -ieo pipefail {0} 8 | 9 | on: 10 | push: 11 | branches: 12 | - main 13 | - dev 14 | pull_request: 15 | branches: [main, dev] 16 | schedule: 17 | # run CI every day even if no PRs/merges occur 18 | - cron: '0 12 * * *' 19 | 20 | concurrency: 21 | group: ${{ github.workflow }}-${{ github.ref }} 22 | cancel-in-progress: true 23 | 24 | jobs: 25 | tests: 26 | runs-on: ubuntu-latest 27 | 28 | steps: 29 | - uses: actions/checkout@v5 30 | - name: Set up Python 3.8 31 | uses: actions/setup-python@v6 32 | with: 33 | python-version: 3.8 34 | cache: "pip" 35 | cache-dependency-path: setup.py 36 | 37 | 38 | - name: Install dependencies 39 | run: | 40 | pip install ".[test]" 41 | solc-select use latest --always-install 42 | 43 | - name: Run Tests 44 | env: 45 | ETHERSCAN_API_KEY: ${{ secrets.ETHERSCAN_API_KEY }} 46 | run: | 47 | pytest tests 48 | -------------------------------------------------------------------------------- /tests/hardhat-multi-file/scripts/sample-script.js: -------------------------------------------------------------------------------- 1 | // We require the Hardhat Runtime Environment explicitly here. This is optional 2 | // but useful for running the script in a standalone fashion through `node